Compare commits

..

2 Commits

Author SHA1 Message Date
Rui Matos
f7e243108d Bump version to 3.16.1.1
Update NEWS.
2015-04-15 14:48:56 +02:00
Carlos Garnacho
0d6420df51 backend: Apply the right settings to the right input devices
Since 8769b3d55, the checks performed on which update_* function was
called for each device got quite more lax, leading to failed asserts
on code that assumed the previous behavior.

Change update_[mouse|touchpad|trackball]_* to bail out early if the
device received has not the right type, and remove the asserts.

https://bugzilla.gnome.org/show_bug.cgi?id=747886
2015-04-15 14:44:11 +02:00
149 changed files with 12873 additions and 11528 deletions

8
.gitignore vendored
View File

@@ -57,8 +57,10 @@ testgradient
m4/*
INSTALL
mkinstalldirs
meta-enum-types.[ch]
src/stamp-meta-enum-types.h
src/mutter-enum-types.[ch]
src/stamp-mutter-enum-types.h
src/mutter-marshal.[ch]
src/stamp-mutter-marshal.h
src/meta-dbus-display-config.[ch]
src/meta-dbus-idle-monitor.[ch]
src/meta-dbus-login1.[ch]
@@ -66,8 +68,6 @@ src/gtk-shell-protocol.c
src/gtk-shell-server-protocol.h
src/xdg-shell-protocol.c
src/xdg-shell-server-protocol.h
src/pointer-gestures-protocol.c
src/pointer-gestures-server-protocol.h
src/xserver-protocol.c
src/xserver-server-protocol.h
src/meta/meta-version.h

View File

@@ -9,3 +9,5 @@ DISTCLEANFILES = \
intltool-update \
po/stamp-it \
po/.intltool-merge-cache
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc

116
NEWS
View File

@@ -1,117 +1,9 @@
3.18.1
======
* Misc. crash fixes [Jonas, Rui, Carlos, Owen, Florian; #755096, #754979,
#755490, #754357, #745785, #756642]
* Improve HiDPI support on wayland [Jonas; #755097]
* Fix doubly-scaled cursor on XWayland HiDPI [Jonas; #755099]
* Stop hiding titlebar buttons in dialogs [Florian; #641630]
* Add support for fullscreen/unfullscreen animations [Cosimo; #707248]
* Misc. bug fixes [Rui, Colin, Florian; #743339, #752047, #756074, #756649]
3.16.1.1
========
* Prevent a crash when switching VTs or adding input devices [Carlos; #747886]
Contributors:
Jonas Ådahl, Cosimo Cecchi, Carlos Garnacho, Rui Matos, Florian Müllner,
Jasper St. Pierre, Colin Walters, Owen W. Taylor
3.18.0
======
* Misc. fixes [Florian, Jonas; #753434]
Contributors:
Jonas Ådahl, Florian Müllner
Translations:
Rūdolfs Mazurs [lv]
3.17.92
=======
* Don't omit the background color for backgrounds that don't fill the screen
[Ray; #754476]
* Fix up key state on FocusIn when running nested [Owen; #753948]
* Find the right DRM device instead of hardcoding card0 [Marek; #753434]
* Scale cursor on HiDPI screens [Jonas; #744932]
* Misc. fixes and cleanups [Lan, Jonas, Javier, Olivier; #754545, #754215,
#754621, #754715]
Contributors:
Jonas Ådahl, Marek Chalupa, Olivier Fourdan, Javier Jardón, Ting-Wei Lan,
Ray Strode, Owen W. Taylor
3.17.91
=======
* Send error on pointer-gesture protocol version mismatch [Jonas; #753855]
* Misc. cleanups [Jonas; #744932]
Contributors:
Jonas Ådahl
Translations:
Chao-Hsiung Liao [zh_TW], Piotr Drąg [pl]
3.17.90
=======
* Fix glitch with some fullscreen apps [Rui; #753020]
* Fix screen update issue with NVidia driver [Aaron, Rui; #728464]
* Only call frame callbacks for surfaces that get drawn [Adel; #739163]
* Misc. bug fixes and cleanups [Jonas, Rui, Ting-Wei; #753222, #752753, #753237,
#753380, #744104, #744932]
Contributors:
Jonas Ådahl, Adel Gadllah, Carlos Garnacho, Ting-Wei Lan, Rui Matos,
Florian Müllner, Aaron Plattner, Jasper St. Pierre
Translations:
Akom Chotiphantawanon [th]
3.17.4
======
* nested: Allow basic configuration of dummy outputs [Jonas; #747089]
* Send wl_surface.enter and wl_surface.leave on output changes [Jonas; #744453]
* Improve HiDPI handling on wayland [Jonas; #745655, #744934]
* Implement compositor-side animated cursors [Carlos; #752342]
* Misc. bug fixes [Peter, Marek, Carlos, Matthias, Rui; #750816, #751884,
#752248, #752551, #752552, #752673, #752674]
Contributors:
Jonas Ådahl, Marek Chalupa, Matthias Clasen, Carlos Garnacho, Peter Hutterer,
Rui Matos, Florian Müllner, Jasper St. Pierre
3.17.3
======
* Add X11/wayland clipboard interaction [Carlos; #738312]
* Support VM monitor layout hints on wayland [Thomas; #750363]
* Misc. bug fixes [Rui, Jonas, Olivier, Carlos, Ting-Wei, Peter, Florian;
#749994, #750256, #749716, #748705, #750552, #751036, #750007, #751136,
#750552, #751471, #751715, #750680]
Contributors:
Jonas Ådahl, Dave Airlie, Cosimo Cecchi, Olivier Fourdan, Carlos Garnacho,
Thomas Hellstrom, Peter Hutterer, Ting-Wei Lan, Jasper Lievisse Adriaanse,
Rui Matos, Florian Müllner, Jasper St. Pierre
Translations:
Marek Černocký [cs], Christian Kirbach [de], Pedro Albuquerque [pt]
3.17.2
======
* Honor default value for click method setting [Rui; #746290]
* Add X11/wayland clipboard interoperation [Carlos; #738312]
* Misc. bug fixes [Rui; #749076, #749711]
Contributors:
Carlos Garnacho, Rui Matos, Jasper St. Pierre
3.17.1
======
* Add public method to get neighboring monitor [Florian; #633994]
* Apply the right settings to the right input devices [Carlos; #747886]
* Fix scroll button setting [Ondrej; #747967]
* Add support for modal hint on wayland [Jonas; #745720]
* Don't reset idle time for non-hardware events [Rui; #748541]
* Misc. bug fixes [Ray, Rui; #748380, #748478]
Contributors:
Jonas Ådahl, Carlos Garnacho, Ondrej Holy, Rui Matos, Florian Müllner,
Jasper St. Pierre, Ray Strode, Tomeu Vizoso
Carlos Garnacho
3.16.1
======

View File

@@ -1,8 +1,8 @@
AC_PREREQ(2.62)
m4_define([mutter_major_version], [3])
m4_define([mutter_minor_version], [18])
m4_define([mutter_micro_version], [1])
m4_define([mutter_minor_version], [16])
m4_define([mutter_micro_version], [1.1])
m4_define([mutter_version],
[mutter_major_version.mutter_minor_version.mutter_micro_version])
@@ -52,6 +52,19 @@ PKG_PROG_PKG_CONFIG([0.21])
# Sets GLIB_GENMARSHAL and GLIB_MKENUMS
AM_PATH_GLIB_2_0()
#### Integer sizes
AC_CHECK_SIZEOF(char)
AC_CHECK_SIZEOF(short)
AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(void *)
AC_CHECK_SIZEOF(long long)
AC_CHECK_SIZEOF(__int64)
## byte order
AC_C_BIGENDIAN
CANBERRA_GTK=libcanberra-gtk3
CANBERRA_GTK_VERSION=0.26
@@ -63,7 +76,7 @@ MUTTER_PC_MODULES="
pango >= 1.2.0
cairo >= 1.10.0
gsettings-desktop-schemas >= 3.15.92
$CLUTTER_PACKAGE >= 1.23.4
$CLUTTER_PACKAGE >= 1.21.3
cogl-1.0 >= 1.17.1
upower-glib >= 0.99.0
gnome-desktop-3.0
@@ -271,8 +284,6 @@ AC_CHECK_LIB(Xrandr, XRRUpdateConfiguration,
if test "x$found_randr" = "xyes"; then
AC_DEFINE(HAVE_RANDR, , [Have the Xrandr extension library])
PKG_CHECK_EXISTS([xrandr >= 1.5.0],
AC_DEFINE([HAVE_XRANDR15],[1],[Define if you have support for XRandR 1.5 or greater]))
fi
MUTTER_LIBS="$MUTTER_LIBS $RANDR_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS -lm"
@@ -319,10 +330,7 @@ if test "x$enable_debug" = "xyes"; then
CFLAGS="$CFLAGS -g -O"
fi
AC_CHECK_DECL([GL_EXT_x11_sync_object],
[],
[AC_MSG_ERROR([GL_EXT_x11_sync_object definition not found, please update your GL headers])],
[#include <GL/glx.h>])
GTK_DOC_CHECK([1.15], [--flavour no-tmpl])
#### Warnings (last since -Werror can disturb other tests)
@@ -395,6 +403,8 @@ Makefile
data/Makefile
doc/Makefile
doc/man/Makefile
doc/reference/Makefile
doc/reference/meta-docs.sgml
src/Makefile
src/libmutter.pc
src/compositor/plugins/Makefile

View File

@@ -1,4 +1,4 @@
SUBDIRS = man
SUBDIRS = man reference
EXTRA_DIST = dialogs.txt code-overview.txt \
how-to-get-focus-right.txt rationales.txt

183
doc/reference/Makefile.am Normal file
View File

@@ -0,0 +1,183 @@
## Process this file with automake to produce Makefile.in
# We require automake 1.6 at least.
AUTOMAKE_OPTIONS = 1.6
# This is a blank Makefile.am for using gtk-doc.
# Copy this to your project's API docs directory and modify the variables to
# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
# of using the various options.
# The name of the module, e.g. 'glib'.
DOC_MODULE=meta
# Uncomment for versioned docs and specify the version of the module, e.g. '2'.
#DOC_MODULE_VERSION=2
# The top-level SGML file. You can change this if you want to.
DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
# Directories containing the source code, relative to $(srcdir).
# gtk-doc will search all .c and .h files beneath these paths
# for inline comments documenting functions and macros.
# e.g. DOC_SOURCE_DIR=../../../gtk ../../../gdk
DOC_SOURCE_DIR=../../src/
# Extra options to pass to gtkdoc-scangobj. Not normally needed.
SCANGOBJ_OPTIONS=
# Extra options to supply to gtkdoc-scan.
# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
SCAN_OPTIONS=--rebuild-types
# Extra options to supply to gtkdoc-mkdb.
# e.g. MKDB_OPTIONS=--xml-mode --output-format=xml
MKDB_OPTIONS=--xml-mode --output-format=xml
# Extra options to supply to gtkdoc-mktmpl
# e.g. MKTMPL_OPTIONS=--only-section-tmpl
MKTMPL_OPTIONS=
# Extra options to supply to gtkdoc-mkhtml
MKHTML_OPTIONS=
# Extra options to supply to gtkdoc-fixref. Not normally needed.
# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
FIXXREF_OPTIONS=
# Used for dependencies. The docs will be rebuilt if any of these change.
# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
HFILE_GLOB=$(top_srcdir)/src/*/*.h
CFILE_GLOB=$(top_srcdir)/src/*/*.c
# Extra header to include when scanning, which are not under DOC_SOURCE_DIR
# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h
EXTRA_HFILES=
# Header files or dirs to ignore when scanning. Use base file/dir names
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h private_code
IGNORE_HFILES= \
async-getprop.h \
atoms.h \
bell.h \
boxes-private.h \
clutter-utils.h \
cogl-utils.h \
compositor-private.h \
constraints.h \
core.h \
display-private.h \
draw-workspace.h \
edge-resistance.h \
eventqueue.h \
frame.h \
frames.h \
group-private.h \
group-props.h \
iconcache.h \
inlinepixbufs.h \
keybindings-private.h \
meta-background-actor-private.h \
meta-background-group-private.h \
meta-dbus-login1.h \
meta-module.h \
meta-plugin-manager.h \
meta-shadow-factory-private.h \
meta-texture-rectangle.h \
meta-texture-tower.h \
meta-window-actor-private.h \
meta-window-group.h \
meta-window-shape.h \
mutter-enum-types.h \
mutter-Xatomtype.h \
place.h \
preview-widget.h \
region-utils.h \
resizepopup.h \
screen-private.h \
session.h \
stack.h \
stack-tracker.h \
stamp-mutter-enum-types.h \
tabpopup.h \
theme.h \
theme-private.h \
tile-preview.h \
ui.h \
window-private.h \
window-props.h \
workspace-private.h \
xprops.h \
$(NULL)
if !HAVE_NATIVE_BACKEND
IGNORE_HFILES+= \
meta-backend-native.h \
meta-barrier-native.h \
meta-cursor-renderer-native.h \
meta-idle-monitor-native.h \
meta-input-settings-native.h \
meta-monitor-manager-kms.h \
$(NULL)
endif
if !HAVE_WAYLAND
IGNORE_HFILES += \
meta-surface-actor-wayland.h \
wayland \
$(NULL)
endif
MKDB_OPTIONS+=--ignore-files="$(IGNORE_HFILES)"
# Images to copy into HTML directory.
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
HTML_IMAGES=
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
content_files= \
mutter-overview.xml \
running-mutter.xml \
$(NULL)
# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
# These files must be listed here *and* in content_files
# e.g. expand_content_files=running.sgml
expand_content_files= \
mutter-overview.xml \
running-mutter.xml \
$(NULL)
# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
# Only needed if you are using gtkdoc-scangobj to dynamically query widget
# signals and properties.
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
GTKDOC_CFLAGS=$(MUTTER_CFLAGS)
GTKDOC_LIBS=$(MUTTER_LIBS) $(top_builddir)/src/libmutter.la
# This includes the standard gtk-doc make rules, copied by gtkdocize.
include $(top_srcdir)/gtk-doc.make
# Other files to distribute
# e.g. EXTRA_DIST += version.xml.in
EXTRA_DIST +=
# Files not to distribute
# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
DISTCLEANFILES = $(DOC_MODULES).types
# Comment this out if you want 'make check' to test you doc status
# and run some sanity checks
if ENABLE_GTK_DOC
TESTS_ENVIRONMENT = cd $(srcdir) && \
DOC_MODULE=$(DOC_MODULE) DOC_MAIN_SGML_FILE=$(DOC_MAIN_SGML_FILE) \
SRCDIR=$(abs_srcdir) BUILDDIR=$(abs_builddir)
#TESTS = $(GTKDOC_CHECK)
endif
-include $(top_srcdir)/git.mk

View File

@@ -0,0 +1,58 @@
<?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
[
<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
<!ENTITY version "@VERSION@">
]>
<book id="index">
<bookinfo>
<title>Mutter Reference Manual</title>
<releaseinfo>
This document is for Mutter &version;.
The latest version of this documentation can be found on-line at
<ulink role="online-location" url="http://developer.gnome.org/meta/">http://developer.gnome.org/meta/</ulink>.
</releaseinfo>
</bookinfo>
<xi:include href="xml/mutter-overview.xml"/>
<xi:include href="xml/running-mutter.xml"/>
<part id="core-reference">
<title>Mutter Core Reference</title>
<xi:include href="xml/main.xml"/>
<xi:include href="xml/common.xml"/>
<xi:include href="xml/prefs.xml"/>
<xi:include href="xml/util.xml"/>
<xi:include href="xml/errors.xml"/>
<xi:include href="xml/meta-plugin.xml"/>
<xi:include href="xml/barrier.xml"/>
<xi:include href="xml/boxes.xml"/>
<xi:include href="xml/compositor.xml"/>
<xi:include href="xml/display.xml"/>
<xi:include href="xml/group.xml"/>
<xi:include href="xml/keybindings.xml"/>
<xi:include href="xml/meta-background-actor.xml"/>
<xi:include href="xml/meta-shadow-factory.xml"/>
<xi:include href="xml/meta-shaped-texture.xml"/>
<xi:include href="xml/meta-window-actor.xml"/>
<xi:include href="xml/screen.xml"/>
<xi:include href="xml/window.xml"/>
<xi:include href="xml/workspace.xml"/>
</part>
<chapter id="object-tree">
<title>Object Hierarchy</title>
<xi:include href="xml/tree_index.sgml"/>
</chapter>
<index id="api-index-full">
<title>API Index</title>
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
</index>
<index id="deprecated-api-index" role="deprecated">
<title>Index of deprecated API</title>
<xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
</index>
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
</book>

View File

@@ -0,0 +1,674 @@
<SECTION>
<FILE>barrier</FILE>
<TITLE>MetaBarrier</TITLE>
MetaBarrier
MetaBarrierClass
meta_barrier_is_active
meta_barrier_destroy
meta_barrier_release
MetaBarrierDirection
MetaBarrierEvent
<SUBSECTION Standard>
META_BARRIER
META_BARRIER_CLASS
META_BARRIER_GET_CLASS
META_IS_BARRIER
META_IS_BARRIER_CLASS
META_TYPE_BARRIER
META_TYPE_BARRIER_EVENT
MetaBarrierPrivate
meta_barrier_event_get_type
meta_barrier_get_type
</SECTION>
<SECTION>
<FILE>boxes</FILE>
MetaRectangle
MetaStrut
MetaEdgeType
MetaEdge
meta_rectangle_copy
meta_rectangle_free
meta_rect
meta_rectangle_area
meta_rectangle_intersect
meta_rectangle_equal
meta_rectangle_union
meta_rectangle_overlap
meta_rectangle_vert_overlap
meta_rectangle_horiz_overlap
meta_rectangle_could_fit_rect
meta_rectangle_contains_rect
<SUBSECTION Standard>
META_TYPE_RECTANGLE
meta_rectangle_get_type
</SECTION>
<SECTION>
<FILE>common</FILE>
META_VIRTUAL_CORE_POINTER_ID
META_VIRTUAL_CORE_KEYBOARD_ID
MetaFrameFlags
MetaMenuOp
MetaWindowMenuFunc
MetaGrabOp
MetaCursor
MetaFrameType
MetaVirtualModifier
MetaDirection
MetaMotionDirection
MetaSide
MetaButtonFunction
MAX_BUTTONS_PER_CORNER
MetaButtonLayout
MetaFrameBorders
meta_frame_borders_clear
META_ICON_WIDTH
META_ICON_HEIGHT
META_MINI_ICON_WIDTH
META_MINI_ICON_HEIGHT
META_DEFAULT_ICON_NAME
META_PRIORITY_RESIZE
META_PRIORITY_BEFORE_REDRAW
META_PRIORITY_REDRAW
META_PRIORITY_PREFS_NOTIFY
POINT_IN_RECT
MetaStackLayer
MetaWindowMenu
MetaResizePopup
</SECTION>
<SECTION>
<FILE>compositor</FILE>
MetaCompEffect
MetaCompositor
meta_compositor_new
meta_compositor_destroy
meta_compositor_manage_screen
meta_compositor_unmanage_screen
meta_compositor_window_shape_changed
meta_compositor_process_event
meta_compositor_filter_keybinding
meta_compositor_add_window
meta_compositor_remove_window
meta_compositor_show_window
meta_compositor_hide_window
meta_compositor_switch_workspace
meta_compositor_maximize_window
meta_compositor_unmaximize_window
meta_compositor_sync_window_geometry
meta_compositor_set_updates_frozen
meta_compositor_queue_frame_drawn
meta_compositor_sync_stack
meta_compositor_sync_screen_size
meta_compositor_flash_screen
meta_get_stage_for_screen
meta_get_overlay_group_for_screen
meta_get_overlay_window
meta_get_window_actors
meta_get_window_group_for_screen
meta_get_top_window_group_for_screen
meta_disable_unredirect_for_screen
meta_enable_unredirect_for_screen
meta_set_stage_input_region
meta_empty_stage_input_region
</SECTION>
<SECTION>
<FILE>display</FILE>
MetaTabList
MetaTabShowType
meta_XFree
meta_display_get_compositor_version
meta_display_get_xinput_opcode
meta_display_supports_extended_barriers
meta_display_get_xdisplay
meta_display_get_compositor
meta_display_get_screens
meta_display_has_shape
meta_display_screen_for_root
meta_display_get_focus_window
meta_display_xwindow_is_a_no_focus_window
meta_display_get_damage_event_base
meta_display_get_shape_event_base
meta_display_xserver_time_is_before
meta_display_get_last_user_time
meta_display_get_current_time
meta_display_get_current_time_roundtrip
meta_display_get_ignored_modifier_mask
meta_display_get_tab_list
meta_display_get_tab_next
meta_display_get_tab_current
meta_display_begin_grab_op
meta_display_end_grab_op
meta_display_get_grab_op
meta_display_add_keybinding
meta_display_remove_keybinding
meta_display_get_keybinding_action
meta_display_set_input_focus_window
meta_display_focus_the_no_focus_window
meta_display_sort_windows_by_stacking
meta_display_get_leader_window
meta_display_add_ignored_crossing_serial
meta_display_unmanage_screen
meta_display_clear_mouse_mode
MetaDisplay
MetaDisplayClass
<SUBSECTION Standard>
META_DISPLAY
META_DISPLAY_CLASS
META_DISPLAY_GET_CLASS
META_IS_DISPLAY
META_IS_DISPLAY_CLASS
META_TYPE_DISPLAY
meta_display_get_type
</SECTION>
<SECTION>
<FILE>errors</FILE>
meta_error_trap_push
meta_error_trap_pop
meta_error_trap_push_with_return
meta_error_trap_pop_with_return
</SECTION>
<SECTION>
<FILE>group</FILE>
MetaGroup
meta_window_get_group
meta_window_compute_group
meta_window_shutdown_group
meta_window_group_leader_changed
meta_display_lookup_group
meta_group_list_windows
meta_group_update_layers
meta_group_get_startup_id
meta_group_get_size
meta_group_property_notify
</SECTION>
<SECTION>
<FILE>keybindings</FILE>
MetaKeyBinding
META_TYPE_KEY_BINDING
meta_key_binding_get_name
meta_key_binding_get_modifiers
meta_key_binding_get_mask
meta_key_binding_is_builtin
meta_keybindings_set_custom_handler
meta_screen_ungrab_all_keys
meta_screen_grab_all_keys
</SECTION>
<SECTION>
<FILE>main</FILE>
meta_get_option_context
meta_init
meta_run
meta_get_replace_current_wm
meta_set_wm_name
meta_set_gnome_wm_keybindings
MetaExitCode
meta_exit
meta_quit
</SECTION>
<SECTION>
<FILE>meta-background</FILE>
<TITLE>MetaBackground</TITLE>
MetaBackgroundEffects
MetaBackground
MetaBackgroundClass
meta_background_new
meta_background_copy
meta_background_load_gradient
meta_background_load_color
meta_background_load_still_frame
meta_background_load_file_async
meta_background_load_file_finish
meta_background_get_filename
meta_background_get_style
meta_background_get_shading
meta_background_get_color
meta_background_get_second_color
<SUBSECTION Standard>
META_BACKGROUND
META_BACKGROUND_CLASS
META_BACKGROUND_GET_CLASS
META_IS_BACKGROUND
META_IS_BACKGROUND_CLASS
META_TYPE_BACKGROUND
MetaBackgroundPrivate
meta_background_get_type
</SECTION>
<SECTION>
<FILE>meta-background-actor</FILE>
<TITLE>MetaBackgroundActor</TITLE>
MetaBackgroundActor
MetaBackgroundActorClass
meta_background_actor_new_for_screen
MetaSnippetHook
meta_background_actor_add_glsl_snippet
meta_background_actor_set_uniform_float
<SUBSECTION Standard>
META_BACKGROUND_ACTOR
META_BACKGROUND_ACTOR_CLASS
META_BACKGROUND_ACTOR_GET_CLASS
META_IS_BACKGROUND_ACTOR
META_IS_BACKGROUND_ACTOR_CLASS
META_TYPE_BACKGROUND_ACTOR
MetaBackgroundActorPrivate
meta_background_actor_get_type
</SECTION>
<SECTION>
<FILE>meta-background-group</FILE>
<TITLE>MetaBackgroundGroup</TITLE>
MetaBackgroundGroupClass
meta_background_group_new
<SUBSECTION Standard>
META_BACKGROUND_GROUP
META_BACKGROUND_GROUP_CLASS
META_BACKGROUND_GROUP_GET_CLASS
META_IS_BACKGROUND_GROUP
META_IS_BACKGROUND_GROUP_CLASS
META_TYPE_BACKGROUND_GROUP
MetaBackgroundGroupPrivate
meta_background_group_get_type
</SECTION>
<SECTION>
<FILE>meta-plugin</FILE>
<TITLE>MetaPlugin</TITLE>
MetaPlugin
MetaPluginClass
MetaPluginInfo
meta_plugin_running
meta_plugin_debug_mode
meta_plugin_get_info
MetaPluginVersion
META_PLUGIN_DECLARE
meta_plugin_switch_workspace_completed
meta_plugin_minimize_completed
meta_plugin_unminimize_completed
meta_plugin_maximize_completed
meta_plugin_unmaximize_completed
meta_plugin_map_completed
meta_plugin_destroy_completed
MetaModalOptions
meta_plugin_begin_modal
meta_plugin_end_modal
meta_plugin_get_screen
meta_plugin_manager_set_plugin_type
<SUBSECTION Standard>
META_IS_PLUGIN
META_IS_PLUGIN_CLASS
META_PLUGIN
META_PLUGIN_CLASS
META_PLUGIN_GET_CLASS
META_TYPE_PLUGIN
MetaPluginPrivate
meta_plugin_get_type
</SECTION>
<SECTION>
<FILE>meta-shadow-factory</FILE>
MetaShadowParams
meta_shadow_factory_get_default
meta_shadow_factory_set_params
meta_shadow_factory_get_params
MetaShadowFactory
MetaShadowFactoryClass
<SUBSECTION Standard>
META_IS_SHADOW_FACTORY
META_IS_SHADOW_FACTORY_CLASS
META_SHADOW_FACTORY
META_SHADOW_FACTORY_CLASS
META_SHADOW_FACTORY_GET_CLASS
META_TYPE_SHADOW_FACTORY
meta_shadow_factory_get_type
</SECTION>
<SECTION>
<FILE>meta-shaped-texture</FILE>
<TITLE>MetaShapedTexture</TITLE>
MetaShapedTexture
MetaShapedTextureClass
meta_shaped_texture_new
meta_shaped_texture_set_create_mipmaps
meta_shaped_texture_update_area
meta_shaped_texture_set_pixmap
meta_shaped_texture_get_texture
meta_shaped_texture_set_mask_texture
meta_shaped_texture_set_clip_region
meta_shaped_texture_get_image
<SUBSECTION Standard>
META_IS_SHAPED_TEXTURE
META_IS_SHAPED_TEXTURE_CLASS
META_SHAPED_TEXTURE
META_SHAPED_TEXTURE_CLASS
META_SHAPED_TEXTURE_GET_CLASS
META_TYPE_SHAPED_TEXTURE
MetaShapedTexturePrivate
meta_shaped_texture_get_type
</SECTION>
<SECTION>
<FILE>meta-window-actor</FILE>
<TITLE>MetaWindowActor</TITLE>
MetaWindowActor
MetaWindowActorClass
meta_window_actor_get_x_window
meta_window_actor_get_workspace
meta_window_actor_get_meta_window
meta_window_actor_get_texture
meta_window_actor_is_override_redirect
meta_window_actor_get_description
meta_window_actor_showing_on_its_workspace
meta_window_actor_is_destroyed
<SUBSECTION Standard>
META_IS_WINDOW_ACTOR
META_IS_WINDOW_ACTOR_CLASS
META_TYPE_WINDOW_ACTOR
META_WINDOW_ACTOR
META_WINDOW_ACTOR_CLASS
META_WINDOW_ACTOR_GET_CLASS
MetaWindowActorPrivate
meta_window_actor_get_type
</SECTION>
<SECTION>
<FILE>meta-cullable</FILE>
<TITLE>MetaCullable</TITLE>
MetaCullable
MetaCullableInterface
meta_cullable_cull_out
meta_cullable_reset_culling
meta_cullable_cull_out_children
meta_cullable_reset_culling_children
<SUBSECTION Standard>
META_TYPE_CULLABLE
META_CULLABLE
META_IS_CULLABLE
META_CULLABLE_GET_IFACE
meta_cullable_get_type
</SECTION>
<SECTION>
<FILE>prefs</FILE>
MetaPreference
MetaPrefsChangedFunc
meta_prefs_add_listener
meta_prefs_remove_listener
meta_prefs_init
meta_prefs_override_preference_schema
meta_preference_to_string
meta_prefs_get_mouse_button_mods
meta_prefs_get_mouse_button_resize
meta_prefs_get_mouse_button_menu
meta_prefs_get_focus_mode
meta_prefs_get_focus_new_windows
meta_prefs_get_attach_modal_dialogs
meta_prefs_get_raise_on_click
meta_prefs_get_theme
meta_prefs_get_titlebar_font
meta_prefs_get_num_workspaces
meta_prefs_get_dynamic_workspaces
meta_prefs_get_disable_workarounds
meta_prefs_get_auto_raise
meta_prefs_get_auto_raise_delay
meta_prefs_get_focus_change_on_pointer_rest
meta_prefs_get_gnome_accessibility
meta_prefs_get_gnome_animations
meta_prefs_get_edge_tiling
meta_prefs_get_auto_maximize
meta_prefs_get_button_layout
meta_prefs_get_action_double_click_titlebar
meta_prefs_get_action_middle_click_titlebar
meta_prefs_get_action_right_click_titlebar
meta_prefs_set_num_workspaces
meta_prefs_get_workspace_name
meta_prefs_change_workspace_name
meta_prefs_get_cursor_theme
meta_prefs_get_cursor_size
meta_prefs_get_compositing_manager
meta_prefs_get_force_fullscreen
meta_prefs_set_force_fullscreen
meta_prefs_get_workspaces_only_on_primary
meta_prefs_get_no_tab_popup
meta_prefs_set_no_tab_popup
meta_prefs_get_draggable_border_width
meta_prefs_get_ignore_request_hide_titlebar
meta_prefs_set_ignore_request_hide_titlebar
MetaKeyBindingAction
MetaKeyBindingFlags
MetaKeyCombo
MetaKeyHandlerFunc
meta_prefs_get_keybindings
meta_prefs_get_keybinding_action
meta_prefs_get_window_binding
meta_prefs_get_overlay_binding
meta_prefs_get_visual_bell
meta_prefs_bell_is_audible
meta_prefs_get_visual_bell_type
MetaKeyHandler
<SUBSECTION Standard>
meta_key_binding_get_type
</SECTION>
<SECTION>
<FILE>screen</FILE>
MetaScreen
MetaScreenClass
meta_screen_get_screen_number
meta_screen_get_display
meta_screen_get_xroot
meta_screen_get_size
meta_screen_get_compositor_data
meta_screen_set_compositor_data
meta_screen_for_x_screen
meta_screen_set_cm_selection
meta_screen_unset_cm_selection
meta_screen_get_startup_sequences
meta_screen_get_workspaces
meta_screen_get_n_workspaces
meta_screen_get_workspace_by_index
meta_screen_remove_workspace
meta_screen_append_new_workspace
meta_screen_get_active_workspace_index
meta_screen_get_active_workspace
meta_screen_get_n_monitors
meta_screen_get_primary_monitor
meta_screen_get_current_monitor
meta_screen_get_monitor_geometry
meta_screen_get_monitor_index_for_rect
meta_screen_focus_default_window
MetaScreenCorner
meta_screen_override_workspace_layout
<SUBSECTION Standard>
META_IS_SCREEN
META_IS_SCREEN_CLASS
META_SCREEN
META_SCREEN_CLASS
META_SCREEN_GET_CLASS
META_TYPE_SCREEN
meta_screen_get_type
</SECTION>
<SECTION>
<FILE>util</FILE>
meta_is_verbose
meta_set_verbose
meta_is_debugging
meta_set_debugging
meta_is_syncing
meta_set_syncing
meta_set_replace_current_wm
meta_debug_spew_real
meta_verbose_real
meta_bug
meta_warning
meta_fatal
MetaDebugTopic
meta_topic_real
meta_add_verbose_topic
meta_remove_verbose_topic
meta_push_no_msg_prefix
meta_pop_no_msg_prefix
meta_unsigned_long_equal
meta_unsigned_long_hash
meta_frame_type_to_string
meta_gravity_to_string
_
N_
meta_g_utf8_strndup
meta_free_gslist_and_elements
meta_show_dialog
meta_debug_spew
meta_verbose
meta_topic
MetaLaterType
meta_later_add
meta_later_remove
</SECTION>
<SECTION>
<FILE>window</FILE>
MetaWindow
MetaWindowClass
MetaWindowType
MetaMaximizeFlags
meta_window_get_frame
meta_window_has_focus
meta_window_appears_focused
meta_window_is_shaded
meta_window_is_monitor_sized
meta_window_is_override_redirect
meta_window_is_skip_taskbar
meta_window_get_rect
meta_window_get_buffer_rect
meta_window_get_frame_rect
meta_window_client_rect_to_frame_rect
meta_window_frame_rect_to_client_rect
meta_window_get_screen
meta_window_get_display
meta_window_get_xwindow
meta_window_get_window_type
meta_window_get_window_type_atom
meta_window_get_workspace
meta_window_get_monitor
meta_window_is_on_all_workspaces
meta_window_located_on_workspace
meta_window_is_hidden
meta_window_activate
meta_window_activate_with_workspace
meta_window_get_description
meta_window_get_wm_class
meta_window_get_wm_class_instance
meta_window_showing_on_its_workspace
meta_window_get_gtk_application_id
meta_window_get_gtk_unique_bus_name
meta_window_get_gtk_application_object_path
meta_window_get_gtk_window_object_path
meta_window_get_gtk_app_menu_object_path
meta_window_get_gtk_menubar_object_path
meta_window_move
meta_window_move_frame
meta_window_move_resize_frame
meta_window_move_to_monitor
meta_window_resize
meta_window_set_demands_attention
meta_window_unset_demands_attention
meta_window_get_startup_id
meta_window_change_workspace_by_index
meta_window_change_workspace
meta_window_get_compositor_private
meta_window_set_compositor_private
meta_window_configure_notify
meta_window_get_role
meta_window_get_layer
meta_window_find_root_ancestor
meta_window_is_ancestor_of_transient
MetaWindowForeachFunc
meta_window_foreach_transient
meta_window_foreach_ancestor
meta_window_get_maximized
meta_window_is_fullscreen
meta_window_is_on_primary_monitor
meta_window_requested_bypass_compositor
meta_window_requested_dont_bypass_compositor
meta_window_is_mapped
meta_window_toplevel_is_mapped
meta_window_get_icon_geometry
meta_window_set_icon_geometry
meta_window_maximize
meta_window_unmaximize
meta_window_minimize
meta_window_unminimize
meta_window_raise
meta_window_lower
meta_window_get_title
meta_window_get_transient_for
meta_window_get_transient_for_as_xid
meta_window_delete
meta_window_get_stable_sequence
meta_window_get_user_time
meta_window_get_pid
meta_window_get_client_machine
meta_window_is_remote
meta_window_is_modal
meta_window_is_attached_dialog
meta_window_get_mutter_hints
meta_window_get_frame_type
meta_window_get_frame_bounds
meta_window_get_tile_match
meta_window_make_fullscreen
meta_window_unmake_fullscreen
meta_window_make_above
meta_window_unmake_above
meta_window_shade
meta_window_unshade
meta_window_stick
meta_window_unstick
meta_window_kill
meta_window_focus
meta_window_check_alive
meta_window_get_work_area_current_monitor
meta_window_get_work_area_for_monitor
meta_window_get_work_area_all_monitors
meta_window_begin_grab_op
<SUBSECTION Standard>
META_IS_WINDOW
META_IS_WINDOW_CLASS
META_TYPE_WINDOW
META_WINDOW
META_WINDOW_CLASS
META_WINDOW_GET_CLASS
meta_window_get_type
</SECTION>
<SECTION>
<FILE>workspace</FILE>
MetaWorkspace
MetaWorkspaceClass
meta_workspace_index
meta_workspace_get_screen
meta_workspace_list_windows
meta_workspace_get_work_area_for_monitor
meta_workspace_get_work_area_all_monitors
meta_workspace_activate
meta_workspace_activate_with_focus
meta_workspace_update_window_hints
meta_workspace_set_builtin_struts
meta_workspace_get_neighbor
<SUBSECTION Standard>
META_IS_WORKSPACE
META_IS_WORKSPACE_CLASS
META_TYPE_WORKSPACE
META_WORKSPACE
META_WORKSPACE_CLASS
META_WORKSPACE_GET_CLASS
meta_workspace_get_type
</SECTION>

View File

@@ -0,0 +1,15 @@
<part id="mutter-overview">
<title>Overview</title>
<partintro>
<para>Mutter is a GObject-based library for creating compositing window managers.</para>
<para>Compositors that wish to use Mutter must implement a subclass of #MetaPlugin and register it with meta_plugin_manager_set_plugin_type() before calling meta_init() but after g_type_init().</para>
<para>#MetaPlugin provides virtual functions that allow to override default behavior in the window management code, such as the effect to perform when a window is created or when switching workspaces.</para>
</partintro>
</part>

View File

@@ -0,0 +1,100 @@
<part id="running-mutter">
<title>Running Mutter</title>
<partintro>
<section id="environment-variables">
<title>Environment Variables</title>
<para>
Mutter automatically checks environment variables during
its initialization. These environment variables are meant
as debug tools or overrides for default behaviours:
</para>
<variablelist>
<varlistentry>
<term>MUTTER_VERBOSE</term>
<listitem>
<para>Enable verbose mode, in which more information is printed to the console. Mutter needs to be built with the --enable-verbose-mode option (enabled by default). For more fine-grained control of the output, see meta_add_verbose_topic().</para>
</listitem>
</varlistentry>
<varlistentry>
<term>MUTTER_DEBUG</term>
<listitem>
<para>Traps and prints X errors to the console.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>MUTTER_G_FATAL_WARNINGS</term>
<listitem>
<para>Causes any logging from the domains Mutter, Gtk, Gdk, Pango or GLib to terminate the process (only when using the log functions in GLib).</para>
</listitem>
</varlistentry>
<varlistentry>
<term>MUTTER_USE_LOGFILE</term>
<listitem>
<para>Log all messages to a temporary file.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>MUTTER_DEBUG_XINERAMA</term>
<listitem>
<para>Log extra information about support of the XINERAMA extension.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>MUTTER_DEBUG_SM</term>
<listitem>
<para>Log extra information about session management.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>MUTTER_DEBUG_BUTTON_GRABS</term>
<listitem>
<para>Log extra information about button grabs.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>MUTTER_SYNC</term>
<listitem>
<para>Call XSync after each X call.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>MUTTER_DISPLAY</term>
<listitem>
<para>Name of the X11 display to use.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>META_DISABLE_MIPMAPS</term>
<listitem>
<para>Disable use of mipmaps for the textures that back window pixmaps.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>MUTTER_USE_STATIC_GRAVITY</term>
<listitem>
<para>Enable support for clients with static bit-gravity.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>MUTTER_WM_CLASS_FILTER</term>
<listitem>
<para>Comma-separated list of WM_CLASS names to which to restrict Mutter to.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>MUTTER_DISABLE_FALLBACK_COLOR</term>
<listitem>
<para>Disable fallback for themed colors, for easier detection of typographical errors.</para>
</listitem>
</varlistentry>
</variablelist>
</section>
</partintro>
</part>

View File

@@ -30,91 +30,91 @@ msgstr "Navigace"
#: ../data/50-mutter-navigation.xml.in.h:2
msgid "Move window to workspace 1"
msgstr "Přesunout okno na pracovní plochu 1"
msgstr "Přesunout okno na plochu 1"
#: ../data/50-mutter-navigation.xml.in.h:3
msgid "Move window to workspace 2"
msgstr "Přesunout okno na pracovní plochu 2"
msgstr "Přesunout okno na plochu 2"
#: ../data/50-mutter-navigation.xml.in.h:4
msgid "Move window to workspace 3"
msgstr "Přesunout okno na pracovní plochu 3"
msgstr "Přesunout okno na plochu 3"
#: ../data/50-mutter-navigation.xml.in.h:5
msgid "Move window to workspace 4"
msgstr "Přesunout okno na pracovní plochu 4"
msgstr "Přesunout okno na plochu 4"
#: ../data/50-mutter-navigation.xml.in.h:6
msgid "Move window to last workspace"
msgstr "Přesunout okno na poslední pracovní plochu"
msgstr "Přesunout okno na poslední plochu"
#: ../data/50-mutter-navigation.xml.in.h:7
msgid "Move window one workspace to the left"
msgstr "Přesunout okno o jednu pracovní plochu doleva"
msgstr "Přesunout okno o plochu doleva"
#: ../data/50-mutter-navigation.xml.in.h:8
msgid "Move window one workspace to the right"
msgstr "Přesunout okno o jednu pracovní plochu doprava"
msgstr "Přesunout okno o plochu doprava"
#: ../data/50-mutter-navigation.xml.in.h:9
msgid "Move window one workspace up"
msgstr "Přesunout okno o jednu pracovní plochu nahoru"
msgstr "Přesunout okno o plochu nahoru"
#: ../data/50-mutter-navigation.xml.in.h:10
msgid "Move window one workspace down"
msgstr "Přesunout okno o jednu pracovní plochu dolů"
msgstr "Přesunout okno o plochu dolů"
#: ../data/50-mutter-navigation.xml.in.h:11
msgid "Move window one monitor to the left"
msgstr "Přesunout okno o jeden monitor doleva"
msgstr "Přesunout okno o monitor doleva"
#: ../data/50-mutter-navigation.xml.in.h:12
msgid "Move window one monitor to the right"
msgstr "Přesunout okno o jeden monitor doprava"
msgstr "Přesunout okno o monitor doprava"
#: ../data/50-mutter-navigation.xml.in.h:13
msgid "Move window one monitor up"
msgstr "Přesunout okno o jeden monitor nahoru"
msgstr "Přesunout okno o monitor nahoru"
#: ../data/50-mutter-navigation.xml.in.h:14
msgid "Move window one monitor down"
msgstr "Přesunout okno o jeden monitor dolů"
msgstr "Přesunout okno o monitor dolů"
#: ../data/50-mutter-navigation.xml.in.h:15
msgid "Switch applications"
msgstr "Přepnout do jiné aplikace"
msgstr "Přepnout mezi aplikacemi"
#: ../data/50-mutter-navigation.xml.in.h:16
msgid "Switch to previous application"
msgstr "Přepnout do předchozí aplikaci"
msgstr "Přepnout na předchozí aplikaci"
#: ../data/50-mutter-navigation.xml.in.h:17
msgid "Switch windows"
msgstr "Přepnout do jiného okna"
msgstr "Přepnout mezi okny"
#: ../data/50-mutter-navigation.xml.in.h:18
msgid "Switch to previous window"
msgstr "Přepnout do minulého okna"
msgstr "Přepnout na předchozí okno"
#: ../data/50-mutter-navigation.xml.in.h:19
msgid "Switch windows of an application"
msgstr "Přepnout do jiného okna aplikace"
msgstr "Přepnout mezi okny aplikace"
#: ../data/50-mutter-navigation.xml.in.h:20
msgid "Switch to previous window of an application"
msgstr "Přepnout do předchozího okna aplikace"
msgstr "Přepnout na předchozí okno aplikace"
#: ../data/50-mutter-navigation.xml.in.h:21
msgid "Switch system controls"
msgstr "Přepnout na systémový ovládací prvek"
msgstr "Přepnout mezi systémovými ovládacími prvky"
#: ../data/50-mutter-navigation.xml.in.h:22
msgid "Switch to previous system control"
msgstr "Přepnout na minulý systémový ovládací prvek"
msgstr "Přepnout na předchozí systémové ovládací prvky"
#: ../data/50-mutter-navigation.xml.in.h:23
msgid "Switch windows directly"
msgstr "Přepnout do minulého okna"
msgstr "Přepnout přímo mezi okny"
#: ../data/50-mutter-navigation.xml.in.h:24
msgid "Switch directly to previous window"
@@ -122,15 +122,15 @@ msgstr "Přepnout přímo na předchozí okno"
#: ../data/50-mutter-navigation.xml.in.h:25
msgid "Switch windows of an app directly"
msgstr "Přepnout do jiného okna aplikace"
msgstr "Přepnout přímo mezi okny aplikace"
#: ../data/50-mutter-navigation.xml.in.h:26
msgid "Switch directly to previous window of an app"
msgstr "Přepnout do předchozího okna aplikace"
msgstr "Přepnout přímo na předchozí okno aplikace"
#: ../data/50-mutter-navigation.xml.in.h:27
msgid "Switch system controls directly"
msgstr "Přepnout na minulý systémový ovládací prvek"
msgstr "Přepnout přímo mezi systémovými ovládacími prvky"
#: ../data/50-mutter-navigation.xml.in.h:28
msgid "Switch directly to previous system control"
@@ -198,7 +198,7 @@ msgstr "Aktivovat nabídku okna"
#: ../data/50-mutter-windows.xml.in.h:3
msgid "Toggle fullscreen mode"
msgstr "Přepnout režim celé obrazovky"
msgstr "Přepnout režim na celou obrazovku"
#: ../data/50-mutter-windows.xml.in.h:4
msgid "Toggle maximization state"
@@ -210,7 +210,7 @@ msgstr "Maximalizovat okno"
#: ../data/50-mutter-windows.xml.in.h:6
msgid "Restore window"
msgstr "Obnovit velikost okna"
msgstr "Obnovit okno"
#: ../data/50-mutter-windows.xml.in.h:7
msgid "Toggle shaded state"
@@ -234,20 +234,20 @@ msgstr "Změnit velikost okna"
#: ../data/50-mutter-windows.xml.in.h:12
msgid "Toggle window on all workspaces or one"
msgstr "Přepnout okno na všechny/jednu pracovní plochu"
msgstr "Přepnout výskyt okna na všech plochách nebo jen na jedné"
#: ../data/50-mutter-windows.xml.in.h:13
msgid "Raise window if covered, otherwise lower it"
msgstr ""
"Když je okno zakryté vynést jej do popředí, jinak odsunout do pozadí"
"Přenést okno do popředí, pokud je zakryté, jinak jej odsunout do pozadí"
#: ../data/50-mutter-windows.xml.in.h:14
msgid "Raise window above other windows"
msgstr "Vynést okno do popředí nad ostatní okna"
msgstr "Přenést okno do popředí nad ostatní okna"
#: ../data/50-mutter-windows.xml.in.h:15
msgid "Lower window below other windows"
msgstr "Odsunout okno do pozadí za ostatní okna"
msgstr "Odsunout okno do pozadí pod ostatní okna"
#: ../data/50-mutter-windows.xml.in.h:16
msgid "Maximize window vertically"
@@ -259,11 +259,11 @@ msgstr "Maximalizovat okno vodorovně"
#: ../data/50-mutter-windows.xml.in.h:18
msgid "View split on left"
msgstr "Rozdělit okno přes levou půlku obrazovky"
msgstr "Zobrazit rozdělení nalevo"
#: ../data/50-mutter-windows.xml.in.h:19
msgid "View split on right"
msgstr "Rozdělit okno přes pravou půlku obrazovky"
msgstr "Zobrazit rozdělení napravo"
#: ../data/mutter.desktop.in.h:1
msgid "Mutter"

1283
po/de.po

File diff suppressed because it is too large Load Diff

1867
po/lv.po

File diff suppressed because it is too large Load Diff

View File

@@ -15,8 +15,8 @@ msgid ""
msgstr ""
"Project-Id-Version: mutter\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-08-26 18:49+0200\n"
"PO-Revision-Date: 2015-08-26 18:50+0200\n"
"POT-Creation-Date: 2015-03-05 00:23+0100\n"
"PO-Revision-Date: 2015-03-05 00:24+0100\n"
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
"Language-Team: Polish <gnomepl@aviary.pl>\n"
"Language: pl\n"
@@ -285,9 +285,9 @@ msgid ""
"\"Windows key\" on PC hardware. It's expected that this binding either the "
"default or set to the empty string."
msgstr ""
"Ten klawisz inicjuje tryb overlay, który jest połączeniem podglądu okien i "
"systemu uruchamiania programów. Domyślnie jest przeznaczony do powiązania z "
"klawiszem Windows na komputerach typu PC. Ustawienie tego powiązania "
"Ten klawisz inicjuje tryb \"overlay\", który jest połączeniem podglądu okien "
"i systemu uruchamiania programów. Domyślnie jest przeznaczony do powiązania "
"z klawiszem \"Windows\" na komputerach typu PC. Ustawienie tego powiązania "
"powinno być domyślne lub puste."
#: ../data/org.gnome.mutter.gschema.xml.in.h:3
@@ -300,9 +300,9 @@ msgid ""
"attached to the titlebar of the parent window and are moved together with "
"the parent window."
msgstr ""
"Jeśli wynosi wartość „true, to modalne okna dialogowe pojawiają się "
"dołączone do paska tytułowego okna nadrzędnego zamiast posiadać oddzielne "
"paski tytułowe i są przenoszone razem z nim."
"Jeśli wynosi \"true\", to modalne okna dialogowe pojawiają się dołączone do "
"paska tytułowego okna nadrzędnego zamiast posiadać oddzielne paski tytułowe "
"i są przenoszone razem z nim."
#: ../data/org.gnome.mutter.gschema.xml.in.h:5
msgid "Enable edge tiling when dropping windows on screen edges"
@@ -332,7 +332,7 @@ msgid ""
"gnome.desktop.wm.preferences)."
msgstr ""
"Określa, czy obszary robocze są zarządzane dynamicznie, czy istnieje "
"statyczna liczba obszarów (określona przez klucz num-workspaces w org."
"statyczna liczba obszarów (określona przez klucz \"num-workspaces\" w org."
"gnome.desktop.wm.preferences)."
#: ../data/org.gnome.mutter.gschema.xml.in.h:9
@@ -369,9 +369,9 @@ msgid ""
"the focus will not be changed immediately when entering a window, but only "
"after the pointer stops moving."
msgstr ""
"Jeśli jest ustawione na wartość true, a tryb aktywności to sloppy” lub "
"mouse, to aktywność nie będzie zmieniana od razu po przejściu do okna, ale "
"dopiero po zatrzymaniu ruchu kursora."
"Jeśli jest ustawione na wartość \"true\", a tryb aktywności to \"sloppy\" "
"lub \"mouse\", to aktywność nie będzie zmieniana od razu po przejściu do "
"okna, ale dopiero po zatrzymaniu ruchu kursora."
#: ../data/org.gnome.mutter.gschema.xml.in.h:15
msgid "Draggable border width"
@@ -409,7 +409,7 @@ msgid ""
"When true, the new windows will always be put in the center of the active "
"screen of the monitor."
msgstr ""
"Jeśli wynosi wartość „true, to nowe okna będą zawsze umieszczane na środku "
"Jeśli wynosi \"true\", to nowe okna będą zawsze umieszczane na środku "
"aktywnego ekranu monitora."
#: ../data/org.gnome.mutter.gschema.xml.in.h:21
@@ -468,22 +468,22 @@ msgstr "Przełączenie na 11. konsolę wirtualną"
msgid "Switch to VT 12"
msgstr "Przełączenie na 12. konsolę wirtualną"
#: ../src/backends/meta-monitor-manager.c:500
#: ../src/backends/meta-monitor-manager.c:364
msgid "Built-in display"
msgstr "Wbudowany ekran"
#: ../src/backends/meta-monitor-manager.c:526
#: ../src/backends/meta-monitor-manager.c:391
msgid "Unknown"
msgstr "Nieznany"
#: ../src/backends/meta-monitor-manager.c:528
#: ../src/backends/meta-monitor-manager.c:393
msgid "Unknown Display"
msgstr "Nieznany ekran"
#. TRANSLATORS: this is a monitor vendor name, followed by a
#. * size in inches, like 'Dell 15"'
#.
#: ../src/backends/meta-monitor-manager.c:536
#: ../src/backends/meta-monitor-manager.c:401
#, c-format
msgid "%s %s"
msgstr "%s %s"
@@ -496,7 +496,7 @@ msgid ""
"Another compositing manager is already running on screen %i on display \"%s"
"\"."
msgstr ""
"Inny menedżer składania jest już uruchomiony na podekranie %i ekranu „%s”."
"Inny menedżer składania jest już uruchomiony na podekranie %i ekranu \"%s\"."
#: ../src/core/bell.c:185
msgid "Bell event"
@@ -505,7 +505,7 @@ msgstr "Zdarzenie sygnału dźwiękowego"
#: ../src/core/delete.c:127
#, c-format
msgid "“%s” is not responding."
msgstr "Okno „%s” nie odpowiada."
msgstr "Okno \"%s\" nie odpowiada."
#: ../src/core/delete.c:129
msgid "Application is not responding."
@@ -525,10 +525,11 @@ msgstr "_Czekaj"
msgid "_Force Quit"
msgstr "_Zakończ"
#: ../src/core/display.c:563
#: ../src/core/display.c:562
#, c-format
msgid "Failed to open X Window System display '%s'\n"
msgstr "Otwarcie połączenia z ekranem „%s” systemu X Window się nie powiodło\n"
msgstr ""
"Otwarcie połączenia z ekranem \"%s\" systemu X Window się nie powiodło\n"
#: ../src/core/main.c:176
msgid "Disable connection to session manager"
@@ -572,7 +573,7 @@ msgid ""
"PARTICULAR PURPOSE.\n"
msgstr ""
"mutter %s\n"
"Copyright (C) 2001%d Havoc Pennington, Red Hat, Inc., oraz inni\n"
"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., oraz inni\n"
"Niniejszy program jest wolnym oprogramowaniem, aby poznać warunki, pod\n"
"jakimi dopuszczalne jest kopiowanie programu, zajrzyj do jego źródeł.\n"
"Na program nie udziela się ŻADNYCH GWARANCJI, nawet domyślnej gwarancji\n"
@@ -597,13 +598,13 @@ msgid ""
"Display \"%s\" already has a window manager; try using the --replace option "
"to replace the current window manager."
msgstr ""
"Na ekranie „%s” działa już menedżer okien. Aby zastąpić działającego "
"Na ekranie \"%s\" działa już menedżer okien. Aby zastąpić działającego "
"menedżera okien, proszę spróbować użyć opcji --replace."
#: ../src/core/screen.c:607
#, c-format
msgid "Screen %d on display '%s' is invalid\n"
msgstr "Podekran %d ekranu „%s” jest nieprawidłowy\n"
msgstr "Podekran %d ekranu \"%s\" jest nieprawidłowy\n"
#: ../src/core/util.c:118
msgid "Mutter was compiled without support for verbose mode\n"
@@ -615,7 +616,7 @@ msgid ""
"These windows do not support &quot;save current setup&quot; and will have to "
"be restarted manually next time you log in."
msgstr ""
"Te okna nie obsługują opcji zapisu obecnego stanu (save current setup), "
"Te okna nie obsługują opcji zapisu obecnego stanu (\"save current setup\"), "
"więc przy następnym zalogowaniu będą musiały zostać uruchomione ręcznie."
#: ../src/x11/window-props.c:549

2516
po/pt.po

File diff suppressed because it is too large Load Diff

3900
po/th.po

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,7 @@ msgstr ""
"Project-Id-Version: metacity 3.3.4\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
"product=mutter&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2015-07-21 10:52+0000\n"
"POT-Creation-Date: 2015-02-20 23:22+0000\n"
"PO-Revision-Date: 2015-02-21 16:33+0800\n"
"Last-Translator: Chao-Hsiung Liao <j_h_liau@yahoo.com.tw>\n"
"Language-Team: Chinese (Taiwan) <zh-l10n@lists.linux.org.tw>\n"
@@ -439,22 +439,22 @@ msgstr "切換至 VT 11"
msgid "Switch to VT 12"
msgstr "切換至 VT 12"
#: ../src/backends/meta-monitor-manager.c:500
#: ../src/backends/meta-monitor-manager.c:364
msgid "Built-in display"
msgstr "內建顯示"
#: ../src/backends/meta-monitor-manager.c:526
#: ../src/backends/meta-monitor-manager.c:391
msgid "Unknown"
msgstr "不明"
#: ../src/backends/meta-monitor-manager.c:528
#: ../src/backends/meta-monitor-manager.c:393
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:536
#: ../src/backends/meta-monitor-manager.c:401
#, c-format
msgid "%s %s"
msgstr "%s %s"
@@ -462,7 +462,7 @@ msgstr "%s %s"
# FIXME: I'm still unclear about the meaning of XGetSelectionOwner -- Abel
#. 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:451
#: ../src/compositor/compositor.c:456
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display \"%s"
@@ -496,14 +496,14 @@ msgstr "等待(_W)"
msgid "_Force Quit"
msgstr "強制結束(_F)"
#: ../src/core/display.c:563
#: ../src/core/display.c:562
#, c-format
msgid "Failed to open X Window System display '%s'\n"
msgstr "無法開啟 X Window 畫面‘%s\n"
#: ../src/core/main.c:176
msgid "Disable connection to session manager"
msgstr "停用到作業階段管理的連線"
msgstr "停用到作業階段管理程式的連線"
#: ../src/core/main.c:182
msgid "Replace the running window manager"
@@ -1053,9 +1053,9 @@ msgstr "%s在 %s"
#~ msgid ""
#~ "\"%s\" found in configuration database is not a valid value for mouse "
#~ "button modifier\n"
#~ msgstr "設定資料庫中的“%s”設定值不是有效的滑鼠按鈕修改功能鍵\n"
#~ msgstr "組態資料庫中的“%s”設定值不是有效的滑鼠按鈕修改功能鍵\n"
#~ msgid ""
#~ "\"%s\" found in configuration database is not a valid value for "
#~ "keybinding \"%s\"\n"
#~ msgstr "設定資料庫中的“%s”不是按鍵組合“%s”的有效設定值\n"
#~ msgstr "組態資料庫中的“%s”不是按鍵組合“%s”的有效設定值\n"

View File

@@ -41,6 +41,9 @@ endif
# Some random test programs for bits of the code
testboxes_SOURCES = core/testboxes.c
testboxes_LDADD = $(MUTTER_LIBS) libmutter.la
testasyncgetprop_SOURCES = x11/testasyncgetprop.c
noinst_PROGRAMS += testboxes
noinst_PROGRAMS+=testboxes testasyncgetprop
testboxes_LDADD = $(MUTTER_LIBS) libmutter.la
testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter.la

View File

@@ -39,14 +39,12 @@ mutter_built_sources = \
$(dbus_idle_built_sources) \
$(dbus_display_config_built_sources) \
$(dbus_login1_built_sources) \
meta/meta-enum-types.h \
meta-enum-types.c \
mutter-enum-types.h \
mutter-enum-types.c \
$(NULL)
if HAVE_WAYLAND
mutter_built_sources += \
pointer-gestures-protocol.c \
pointer-gestures-server-protocol.h \
gtk-shell-protocol.c \
gtk-shell-server-protocol.h \
xdg-shell-protocol.c \
@@ -55,7 +53,6 @@ mutter_built_sources += \
endif
wayland_protocols = \
wayland/protocol/pointer-gestures.xml \
wayland/protocol/gtk-shell.xml \
wayland/protocol/xdg-shell.xml \
$(NULL)
@@ -68,6 +65,7 @@ libmutter_la_SOURCES = \
backends/meta-barrier-private.h \
backends/meta-cursor.c \
backends/meta-cursor.h \
backends/meta-cursor-private.h \
backends/meta-cursor-tracker.c \
backends/meta-cursor-tracker-private.h \
backends/meta-cursor-renderer.c \
@@ -96,8 +94,6 @@ libmutter_la_SOURCES = \
backends/x11/meta-barrier-x11.h \
backends/x11/meta-cursor-renderer-x11.c \
backends/x11/meta-cursor-renderer-x11.h \
backends/x11/nested/meta-cursor-renderer-x11-nested.c \
backends/x11/nested/meta-cursor-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 \
@@ -136,14 +132,13 @@ libmutter_la_SOURCES = \
compositor/meta-plugin-manager.c \
compositor/meta-plugin-manager.h \
compositor/meta-shadow-factory.c \
compositor/meta-shadow-factory-private.h \
compositor/meta-shaped-texture.c \
compositor/meta-shaped-texture-private.h \
compositor/meta-surface-actor.c \
compositor/meta-surface-actor.h \
compositor/meta-surface-actor-x11.c \
compositor/meta-surface-actor-x11.h \
compositor/meta-sync-ring.c \
compositor/meta-sync-ring.h \
compositor/meta-texture-rectangle.c \
compositor/meta-texture-rectangle.h \
compositor/meta-texture-tower.c \
@@ -153,6 +148,7 @@ libmutter_la_SOURCES = \
compositor/meta-window-group.c \
compositor/meta-window-group.h \
compositor/meta-window-shape.c \
compositor/meta-window-shape.h \
compositor/region-utils.c \
compositor/region-utils.h \
meta/compositor.h \
@@ -163,7 +159,6 @@ libmutter_la_SOURCES = \
meta/meta-plugin.h \
meta/meta-shadow-factory.h \
meta/meta-window-actor.h \
meta/meta-window-shape.h \
meta/compositor-mutter.h \
core/constraints.c \
core/constraints.h \
@@ -215,7 +210,10 @@ libmutter_la_SOURCES = \
meta/theme.h \
ui/theme-private.h \
ui/ui.c \
x11/atomnames.h \
x11/iconcache.c \
x11/iconcache.h \
x11/async-getprop.c \
x11/async-getprop.h \
x11/events.c \
x11/events.h \
x11/group-private.h \
@@ -223,8 +221,6 @@ libmutter_la_SOURCES = \
x11/group-props.h \
x11/group.c \
meta/group.h \
x11/iconcache.c \
x11/iconcache.h \
x11/session.c \
x11/session.h \
x11/window-props.c \
@@ -246,8 +242,6 @@ libmutter_la_SOURCES += \
wayland/meta-wayland-private.h \
wayland/meta-xwayland.c \
wayland/meta-xwayland.h \
wayland/meta-xwayland-selection.c \
wayland/meta-xwayland-selection-private.h \
wayland/meta-xwayland-private.h \
wayland/meta-wayland-buffer.c \
wayland/meta-wayland-buffer.h \
@@ -255,13 +249,6 @@ libmutter_la_SOURCES += \
wayland/meta-wayland-region.h \
wayland/meta-wayland-data-device.c \
wayland/meta-wayland-data-device.h \
wayland/meta-wayland-data-device-private.h \
wayland/meta-wayland-pointer-gestures.c \
wayland/meta-wayland-pointer-gestures.h \
wayland/meta-wayland-pointer-gesture-swipe.c \
wayland/meta-wayland-pointer-gesture-swipe.h \
wayland/meta-wayland-pointer-gesture-pinch.c \
wayland/meta-wayland-pointer-gesture-pinch.h \
wayland/meta-wayland-keyboard.c \
wayland/meta-wayland-keyboard.h \
wayland/meta-wayland-pointer.c \
@@ -278,8 +265,8 @@ libmutter_la_SOURCES += \
wayland/meta-wayland-versions.h \
wayland/meta-wayland-outputs.c \
wayland/meta-wayland-outputs.h \
wayland/meta-window-wayland.c \
wayland/meta-window-wayland.h \
wayland/window-wayland.c \
wayland/window-wayland.h \
$(NULL)
endif
@@ -335,7 +322,6 @@ libmutterinclude_headers = \
meta/meta-shaped-texture.h \
meta/meta-shadow-factory.h \
meta/meta-window-actor.h \
meta/meta-window-shape.h \
meta/prefs.h \
meta/screen.h \
meta/theme.h \
@@ -346,18 +332,22 @@ libmutterinclude_headers = \
$(NULL)
libmutterinclude_built_headers = \
meta/meta-version.h \
meta/meta-enum-types.h \
$(NULL)
meta/meta-version.h
libmutterinclude_base_headers = \
$(libmutterinclude_headers) \
$(libmutterinclude_built_headers)
# Excluded from scanning for introspection but installed
# atomnames.h: macros cause problems for scanning process
libmutterinclude_extra_headers = \
meta/atomnames.h
libmutterincludedir = $(includedir)/mutter/meta
libmutterinclude_HEADERS = \
$(libmutterinclude_headers)
$(libmutterinclude_headers) \
$(libmutterinclude_extra_headers)
nodist_libmutterinclude_HEADERS = \
$(libmutterinclude_built_headers)
@@ -400,6 +390,7 @@ Meta-$(api_version).gir: libmutter.la
@META_GIR@_CFLAGS = $(AM_CPPFLAGS)
@META_GIR@_LIBS = libmutter.la
@META_GIR@_FILES = \
mutter-enum-types.h \
$(libmutterinclude_base_headers) \
$(filter %.c,$(libmutter_la_SOURCES) $(nodist_libmutter_la_SOURCES))
@META_GIR@_SCANNERFLAGS = --warn-all --warn-error
@@ -422,8 +413,8 @@ pkgconfig_DATA = libmutter.pc
EXTRA_DIST += \
$(wayland_protocols) \
libmutter.pc.in \
meta-enum-types.h.in \
meta-enum-types.c.in \
mutter-enum-types.h.in \
mutter-enum-types.c.in \
org.freedesktop.login1.xml \
org.gnome.Mutter.DisplayConfig.xml \
org.gnome.Mutter.IdleMonitor.xml \
@@ -433,26 +424,26 @@ BUILT_SOURCES = \
$(mutter_built_sources) \
$(libmutterinclude_built_headers)
MUTTER_STAMP_FILES = stamp-meta-enum-types.h
MUTTER_STAMP_FILES = stamp-mutter-enum-types.h
CLEANFILES += $(MUTTER_STAMP_FILES)
meta/meta-enum-types.h: stamp-meta-enum-types.h Makefile
mutter-enum-types.h: stamp-mutter-enum-types.h Makefile
@true
stamp-meta-enum-types.h: $(libmutterinclude_headers) meta-enum-types.h.in
stamp-mutter-enum-types.h: $(libmutterinclude_base_headers) mutter-enum-types.h.in
$(AM_V_GEN) ( cd $(srcdir) && \
$(GLIB_MKENUMS) \
--template meta-enum-types.h.in \
--template mutter-enum-types.h.in \
$(libmutterinclude_base_headers) ) >> xgen-teth && \
(cmp -s xgen-teth meta/meta-enum-types.h || cp xgen-teth meta/meta-enum-types.h) && \
(cmp -s xgen-teth mutter-enum-types.h || cp xgen-teth mutter-enum-types.h) && \
rm -f xgen-teth && \
echo timestamp > $(@F)
meta-enum-types.c: stamp-meta-enum-types.h meta-enum-types.c.in
mutter-enum-types.c: stamp-mutter-enum-types.h mutter-enum-types.c.in
$(AM_V_GEN) ( cd $(srcdir) && \
$(GLIB_MKENUMS) \
--template meta-enum-types.c.in \
--template mutter-enum-types.c.in \
$(libmutterinclude_base_headers) ) >> xgen-tetc && \
cp xgen-tetc meta-enum-types.c && \
cp xgen-tetc mutter-enum-types.c && \
rm -f xgen-tetc
dbus_display_config_built_sources = meta-dbus-display-config.c meta-dbus-display-config.h

View File

@@ -16,7 +16,7 @@
#include "backends/native/meta-barrier-native.h"
#include "backends/x11/meta-backend-x11.h"
#include "backends/x11/meta-barrier-x11.h"
#include <meta/meta-enum-types.h>
#include "mutter-enum-types.h"
G_DEFINE_TYPE (MetaBarrier, meta_barrier, G_TYPE_OBJECT)
G_DEFINE_TYPE (MetaBarrierImpl, meta_barrier_impl, G_TYPE_OBJECT)

View File

@@ -0,0 +1,59 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright 2013 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 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: Giovanni Campagna <gcampagn@redhat.com>
*/
#ifndef META_CURSOR_PRIVATE_H
#define META_CURSOR_PRIVATE_H
#include "meta-cursor.h"
#include <cogl/cogl.h>
#ifdef HAVE_NATIVE_BACKEND
#include <gbm.h>
#endif
typedef struct {
CoglTexture2D *texture;
int hot_x, hot_y;
#ifdef HAVE_NATIVE_BACKEND
struct gbm_bo *bo;
#endif
} MetaCursorImage;
struct _MetaCursorReference {
int ref_count;
MetaCursor cursor;
MetaCursorImage image;
};
CoglTexture *meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor,
int *hot_x,
int *hot_y);
#ifdef HAVE_NATIVE_BACKEND
struct gbm_bo *meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
int *hot_x,
int *hot_y);
#endif
#endif /* META_CURSOR_PRIVATE_H */

View File

@@ -25,6 +25,7 @@
#include "config.h"
#include "meta-cursor-renderer.h"
#include "meta-cursor-private.h"
#include <meta/meta-backend.h>
#include <meta/util.h>
@@ -37,8 +38,9 @@
struct _MetaCursorRendererPrivate
{
int current_x, current_y;
MetaRectangle current_rect;
MetaCursorSprite *displayed_cursor;
MetaCursorReference *displayed_cursor;
gboolean handled_by_backend;
};
typedef struct _MetaCursorRendererPrivate MetaCursorRendererPrivate;
@@ -46,33 +48,27 @@ typedef struct _MetaCursorRendererPrivate MetaCursorRendererPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRenderer, meta_cursor_renderer, G_TYPE_OBJECT);
static void
queue_redraw (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
queue_redraw (MetaCursorRenderer *renderer)
{
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
MetaBackend *backend = meta_get_backend ();
ClutterActor *stage = meta_backend_get_stage (backend);
CoglTexture *texture;
MetaRectangle rect = { 0 };
if (cursor_sprite)
rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
/* During early initialization, we can have no stage */
if (!stage)
return;
if (cursor_sprite && !priv->handled_by_backend)
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
if (priv->displayed_cursor && !priv->handled_by_backend)
texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, NULL, NULL);
else
texture = NULL;
meta_stage_set_cursor (META_STAGE (stage), texture, &rect);
meta_stage_set_cursor (META_STAGE (stage), texture, &priv->current_rect);
}
static gboolean
meta_cursor_renderer_real_update_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
meta_cursor_renderer_real_update_cursor (MetaCursorRenderer *renderer)
{
return FALSE;
}
@@ -88,50 +84,34 @@ meta_cursor_renderer_init (MetaCursorRenderer *renderer)
{
}
MetaRectangle
meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
{
MetaCursorRendererPrivate *priv =
meta_cursor_renderer_get_instance_private (renderer);
CoglTexture *texture;
int hot_x, hot_y;
int width, height;
float texture_scale;
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
if (!texture)
return (MetaRectangle) { 0 };
meta_cursor_sprite_get_hotspot (cursor_sprite, &hot_x, &hot_y);
texture_scale = meta_cursor_sprite_get_texture_scale (cursor_sprite);
width = cogl_texture_get_width (texture);
height = cogl_texture_get_height (texture);
return (MetaRectangle) {
.x = (int)roundf (priv->current_x - (hot_x * texture_scale)),
.y = (int)roundf (priv->current_y - (hot_y * texture_scale)),
.width = (int)roundf (width * texture_scale),
.height = (int)roundf (height * texture_scale),
};
}
static void
update_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
update_cursor (MetaCursorRenderer *renderer)
{
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
gboolean handled_by_backend;
gboolean should_redraw = FALSE;
if (cursor_sprite)
meta_cursor_sprite_prepare_at (cursor_sprite,
priv->current_x,
priv->current_y);
if (priv->displayed_cursor)
{
CoglTexture *texture;
int hot_x, hot_y;
handled_by_backend =
META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer,
cursor_sprite);
texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, &hot_x, &hot_y);
priv->current_rect.x = priv->current_x - hot_x;
priv->current_rect.y = priv->current_y - hot_y;
priv->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (texture));
priv->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (texture));
}
else
{
priv->current_rect.x = 0;
priv->current_rect.y = 0;
priv->current_rect.width = 0;
priv->current_rect.height = 0;
}
handled_by_backend = META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer);
if (handled_by_backend != priv->handled_by_backend)
{
priv->handled_by_backend = handled_by_backend;
@@ -142,7 +122,7 @@ update_cursor (MetaCursorRenderer *renderer,
should_redraw = TRUE;
if (should_redraw)
queue_redraw (renderer, cursor_sprite);
queue_redraw (renderer);
}
MetaCursorRenderer *
@@ -152,25 +132,16 @@ meta_cursor_renderer_new (void)
}
void
meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
MetaCursorReference *cursor)
{
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
if (priv->displayed_cursor == cursor_sprite)
if (priv->displayed_cursor == cursor)
return;
priv->displayed_cursor = cursor_sprite;
update_cursor (renderer, cursor_sprite);
}
void
meta_cursor_renderer_force_update (MetaCursorRenderer *renderer)
{
MetaCursorRendererPrivate *priv =
meta_cursor_renderer_get_instance_private (renderer);
update_cursor (renderer, priv->displayed_cursor);
priv->displayed_cursor = cursor;
update_cursor (renderer);
}
void
@@ -184,10 +155,10 @@ meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
priv->current_x = x;
priv->current_y = y;
update_cursor (renderer, priv->displayed_cursor);
update_cursor (renderer);
}
MetaCursorSprite *
MetaCursorReference *
meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer)
{
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
@@ -195,27 +166,10 @@ meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer)
return priv->displayed_cursor;
}
#ifdef HAVE_WAYLAND
void
meta_cursor_renderer_realize_cursor_from_wl_buffer (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
struct wl_resource *buffer)
const MetaRectangle *
meta_cursor_renderer_get_rect (MetaCursorRenderer *renderer)
{
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_GET_CLASS (renderer);
if (renderer_class->realize_cursor_from_wl_buffer)
renderer_class->realize_cursor_from_wl_buffer (renderer, cursor_sprite, buffer);
}
#endif
void
meta_cursor_renderer_realize_cursor_from_xcursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
XcursorImage *xc_image)
{
MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_GET_CLASS (renderer);
if (renderer_class->realize_cursor_from_xcursor)
renderer_class->realize_cursor_from_xcursor (renderer, cursor_sprite, xc_image);
return &priv->current_rect;
}

View File

@@ -26,56 +26,43 @@
#define META_CURSOR_RENDERER_H
#include <glib-object.h>
#include <X11/Xcursor/Xcursor.h>
#ifdef HAVE_WAYLAND
#include <wayland-server.h>
#endif
#include <meta/screen.h>
#include "meta-cursor.h"
#define META_TYPE_CURSOR_RENDERER (meta_cursor_renderer_get_type ())
G_DECLARE_DERIVABLE_TYPE (MetaCursorRenderer, meta_cursor_renderer,
META, CURSOR_RENDERER, GObject);
#define META_TYPE_CURSOR_RENDERER (meta_cursor_renderer_get_type ())
#define META_CURSOR_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CURSOR_RENDERER, MetaCursorRenderer))
#define META_CURSOR_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_CURSOR_RENDERER, MetaCursorRendererClass))
#define META_IS_CURSOR_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_CURSOR_RENDERER))
#define META_IS_CURSOR_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_CURSOR_RENDERER))
#define META_CURSOR_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_CURSOR_RENDERER, MetaCursorRendererClass))
typedef struct _MetaCursorRenderer MetaCursorRenderer;
typedef struct _MetaCursorRendererClass MetaCursorRendererClass;
struct _MetaCursorRenderer
{
GObject parent;
};
struct _MetaCursorRendererClass
{
GObjectClass parent_class;
gboolean (* update_cursor) (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite);
#ifdef HAVE_WAYLAND
void (* realize_cursor_from_wl_buffer) (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
struct wl_resource *buffer);
#endif
void (* realize_cursor_from_xcursor) (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
XcursorImage *xc_image);
gboolean (* update_cursor) (MetaCursorRenderer *renderer);
};
GType meta_cursor_renderer_get_type (void) G_GNUC_CONST;
MetaCursorRenderer * meta_cursor_renderer_new (void);
void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite);
void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
MetaCursorReference *cursor);
void meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
int x, int y);
void meta_cursor_renderer_force_update (MetaCursorRenderer *renderer);
MetaCursorSprite * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer);
MetaRectangle meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite);
#ifdef HAVE_WAYLAND
void meta_cursor_renderer_realize_cursor_from_wl_buffer (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
struct wl_resource *buffer);
#endif
void meta_cursor_renderer_realize_cursor_from_xcursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
XcursorImage *xc_image);
MetaCursorReference * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer);
const MetaRectangle * meta_cursor_renderer_get_rect (MetaCursorRenderer *renderer);
#endif /* META_CURSOR_RENDERER_H */

View File

@@ -34,7 +34,7 @@ struct _MetaCursorTracker {
gboolean is_showing;
MetaCursorSprite *displayed_cursor;
MetaCursorReference *displayed_cursor;
/* Wayland clients can set a NULL buffer as their cursor
* explicitly, which means that we shouldn't display anything.
@@ -42,12 +42,12 @@ struct _MetaCursorTracker {
* determine an unset window cursor; we need an extra boolean.
*/
gboolean has_window_cursor;
MetaCursorSprite *window_cursor;
MetaCursorReference *window_cursor;
MetaCursorSprite *root_cursor;
MetaCursorReference *root_cursor;
/* The cursor from the X11 server. */
MetaCursorSprite *xfixes_cursor;
MetaCursorReference *xfixes_cursor;
};
struct _MetaCursorTrackerClass {
@@ -57,16 +57,16 @@ struct _MetaCursorTrackerClass {
gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
XEvent *xevent);
void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
MetaCursorSprite *cursor_sprite);
void meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker);
void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
MetaCursorSprite *cursor_sprite);
void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
MetaCursorReference *cursor);
void meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker);
void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
MetaCursorReference *cursor);
void meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
int new_x,
int new_y);
MetaCursorSprite * meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker);
MetaCursorReference * meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker);
#endif

View File

@@ -43,6 +43,7 @@
#include <X11/extensions/Xfixes.h>
#include "meta-backend-private.h"
#include "meta-cursor-private.h"
G_DEFINE_TYPE (MetaCursorTracker, meta_cursor_tracker, G_TYPE_OBJECT);
@@ -53,7 +54,7 @@ enum {
static guint signals[LAST_SIGNAL];
static MetaCursorSprite *
static MetaCursorReference *
get_displayed_cursor (MetaCursorTracker *tracker)
{
MetaDisplay *display = meta_get_display ();
@@ -79,14 +80,14 @@ update_displayed_cursor (MetaCursorTracker *tracker)
static void
sync_cursor (MetaCursorTracker *tracker)
{
MetaCursorSprite *displayed_cursor = get_displayed_cursor (tracker);
MetaCursorReference *displayed_cursor = get_displayed_cursor (tracker);
if (tracker->displayed_cursor == displayed_cursor)
return;
g_clear_object (&tracker->displayed_cursor);
g_clear_pointer (&tracker->displayed_cursor, meta_cursor_reference_unref);
if (displayed_cursor)
tracker->displayed_cursor = g_object_ref (displayed_cursor);
tracker->displayed_cursor = meta_cursor_reference_ref (displayed_cursor);
update_displayed_cursor (tracker);
g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
@@ -107,9 +108,9 @@ meta_cursor_tracker_finalize (GObject *object)
MetaCursorTracker *self = META_CURSOR_TRACKER (object);
if (self->displayed_cursor)
g_object_unref (self->displayed_cursor);
meta_cursor_reference_unref (self->displayed_cursor);
if (self->root_cursor)
g_object_unref (self->root_cursor);
meta_cursor_reference_unref (self->root_cursor);
G_OBJECT_CLASS (meta_cursor_tracker_parent_class)->finalize (object);
}
@@ -155,13 +156,13 @@ meta_cursor_tracker_get_for_screen (MetaScreen *screen)
}
static void
set_window_cursor (MetaCursorTracker *tracker,
gboolean has_cursor,
MetaCursorSprite *cursor_sprite)
set_window_cursor (MetaCursorTracker *tracker,
gboolean has_cursor,
MetaCursorReference *cursor)
{
g_clear_object (&tracker->window_cursor);
if (cursor_sprite)
tracker->window_cursor = g_object_ref (cursor_sprite);
g_clear_pointer (&tracker->window_cursor, meta_cursor_reference_unref);
if (cursor)
tracker->window_cursor = meta_cursor_reference_ref (cursor);
tracker->has_window_cursor = has_cursor;
sync_cursor (tracker);
}
@@ -183,12 +184,28 @@ meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
if (notify_event->subtype != XFixesDisplayCursorNotify)
return FALSE;
g_clear_object (&tracker->xfixes_cursor);
g_clear_pointer (&tracker->xfixes_cursor, meta_cursor_reference_unref);
g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
return TRUE;
}
static MetaCursorReference *
meta_cursor_reference_take_texture (CoglTexture2D *texture,
int hot_x,
int hot_y)
{
MetaCursorReference *self;
self = g_slice_new0 (MetaCursorReference);
self->ref_count = 1;
self->image.texture = texture;
self->image.hot_x = hot_x;
self->image.hot_y = hot_y;
return self;
}
static void
ensure_xfixes_cursor (MetaCursorTracker *tracker)
{
@@ -246,13 +263,10 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
if (sprite != NULL)
{
MetaCursorSprite *cursor_sprite = meta_cursor_sprite_new ();
meta_cursor_sprite_set_texture (cursor_sprite,
sprite,
cursor_image->xhot,
cursor_image->yhot);
cogl_object_unref (sprite);
tracker->xfixes_cursor = cursor_sprite;
MetaCursorReference *cursor = meta_cursor_reference_take_texture (sprite,
cursor_image->xhot,
cursor_image->yhot);
tracker->xfixes_cursor = cursor;
}
XFree (cursor_image);
}
@@ -265,22 +279,22 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
CoglTexture *
meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker)
{
MetaCursorSprite *cursor_sprite;
MetaCursorReference *cursor;
g_return_val_if_fail (META_IS_CURSOR_TRACKER (tracker), NULL);
if (meta_is_wayland_compositor ())
{
cursor_sprite = tracker->displayed_cursor;
cursor = tracker->displayed_cursor;
}
else
{
ensure_xfixes_cursor (tracker);
cursor_sprite = tracker->xfixes_cursor;
cursor = tracker->xfixes_cursor;
}
if (cursor_sprite)
return meta_cursor_sprite_get_cogl_texture (cursor_sprite);
if (cursor)
return meta_cursor_reference_get_cogl_texture (cursor, NULL, NULL);
else
return NULL;
}
@@ -297,22 +311,22 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
int *x,
int *y)
{
MetaCursorSprite *cursor_sprite;
MetaCursorReference *cursor;
g_return_if_fail (META_IS_CURSOR_TRACKER (tracker));
if (meta_is_wayland_compositor ())
{
cursor_sprite = tracker->displayed_cursor;
cursor = tracker->displayed_cursor;
}
else
{
ensure_xfixes_cursor (tracker);
cursor_sprite = tracker->xfixes_cursor;
cursor = tracker->xfixes_cursor;
}
if (cursor_sprite)
meta_cursor_sprite_get_hotspot (cursor_sprite, x, y);
if (cursor)
meta_cursor_reference_get_cogl_texture (cursor, x, y);
else
{
if (x)
@@ -323,10 +337,10 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
}
void
meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
MetaCursorSprite *cursor_sprite)
meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
MetaCursorReference *cursor)
{
set_window_cursor (tracker, TRUE, cursor_sprite);
set_window_cursor (tracker, TRUE, cursor);
}
void
@@ -336,12 +350,12 @@ meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker)
}
void
meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
MetaCursorSprite *cursor_sprite)
meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
MetaCursorReference *cursor)
{
g_clear_object (&tracker->root_cursor);
if (cursor_sprite)
tracker->root_cursor = g_object_ref (cursor_sprite);
g_clear_pointer (&tracker->root_cursor, meta_cursor_reference_unref);
if (cursor)
tracker->root_cursor = meta_cursor_reference_ref (cursor);
sync_cursor (tracker);
}
@@ -424,7 +438,7 @@ meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker,
sync_cursor (tracker);
}
MetaCursorSprite *
MetaCursorReference *
meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker)
{
return tracker->displayed_cursor;

View File

@@ -21,7 +21,7 @@
#include "config.h"
#include "meta-cursor.h"
#include "meta-cursor-private.h"
#include <meta/errors.h>
@@ -29,38 +29,56 @@
#include "screen-private.h"
#include "meta-backend-private.h"
#ifdef HAVE_NATIVE_BACKEND
#include "backends/native/meta-cursor-renderer-native.h"
#endif
#include <string.h>
#include <X11/cursorfont.h>
#include <X11/extensions/Xfixes.h>
#include <X11/Xcursor/Xcursor.h>
enum {
PREPARE_AT,
#ifdef HAVE_WAYLAND
#include <cogl/cogl-wayland-server.h>
#endif
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL];
struct _MetaCursorSprite
MetaCursorReference *
meta_cursor_reference_ref (MetaCursorReference *self)
{
GObject parent;
g_assert (self->ref_count > 0);
self->ref_count++;
MetaCursor cursor;
return self;
}
CoglTexture2D *texture;
float texture_scale;
int hot_x, hot_y;
static void
meta_cursor_image_free (MetaCursorImage *image)
{
if (image->texture)
cogl_object_unref (image->texture);
int current_frame;
XcursorImages *xcursor_images;
#ifdef HAVE_NATIVE_BACKEND
if (image->bo)
gbm_bo_destroy (image->bo);
#endif
}
int theme_scale;
gboolean theme_dirty;
};
static void
meta_cursor_reference_free (MetaCursorReference *self)
{
meta_cursor_image_free (&self->image);
g_slice_free (MetaCursorReference, self);
}
G_DEFINE_TYPE (MetaCursorSprite, meta_cursor_sprite, G_TYPE_OBJECT)
void
meta_cursor_reference_unref (MetaCursorReference *self)
{
self->ref_count--;
if (self->ref_count == 0)
meta_cursor_reference_free (self);
}
static const char *
translate_meta_cursor (MetaCursor cursor)
@@ -117,27 +135,93 @@ meta_cursor_create_x_cursor (Display *xdisplay,
return XcursorLibraryLoadCursor (xdisplay, translate_meta_cursor (cursor));
}
static XcursorImages *
load_cursor_on_client (MetaCursor cursor, int scale)
static XcursorImage *
load_cursor_on_client (MetaCursor cursor)
{
return XcursorLibraryLoadImages (translate_meta_cursor (cursor),
meta_prefs_get_cursor_theme (),
meta_prefs_get_cursor_size () * scale);
return XcursorLibraryLoadImage (translate_meta_cursor (cursor),
meta_prefs_get_cursor_theme (),
meta_prefs_get_cursor_size ());
}
#ifdef HAVE_NATIVE_BACKEND
static void
meta_cursor_sprite_load_from_xcursor_image (MetaCursorSprite *self,
XcursorImage *xc_image)
get_hardware_cursor_size (uint64_t *cursor_width, uint64_t *cursor_height)
{
MetaBackend *meta_backend = meta_get_backend ();
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (meta_backend);
if (META_IS_CURSOR_RENDERER_NATIVE (renderer))
{
meta_cursor_renderer_native_get_cursor_size (META_CURSOR_RENDERER_NATIVE (renderer), cursor_width, cursor_height);
return;
}
g_assert_not_reached ();
}
#endif
#ifdef HAVE_NATIVE_BACKEND
static void
meta_cursor_image_load_gbm_buffer (struct gbm_device *gbm,
MetaCursorImage *image,
uint8_t *pixels,
uint width,
uint height,
int rowstride,
uint32_t gbm_format)
{
uint64_t cursor_width, cursor_height;
get_hardware_cursor_size (&cursor_width, &cursor_height);
if (width > cursor_width || height > cursor_height)
{
meta_warning ("Invalid theme cursor size (must be at most %ux%u)\n",
(unsigned int)cursor_width, (unsigned int)cursor_height);
return;
}
if (gbm_device_is_format_supported (gbm, gbm_format,
GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE))
{
uint8_t buf[4 * cursor_width * cursor_height];
uint i;
image->bo = gbm_bo_create (gbm, cursor_width, cursor_height,
gbm_format, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
memset (buf, 0, sizeof(buf));
for (i = 0; i < height; i++)
memcpy (buf + i * 4 * cursor_width, pixels + i * rowstride, width * 4);
gbm_bo_write (image->bo, buf, cursor_width * cursor_height * 4);
}
else
meta_warning ("HW cursor for format %d not supported\n", gbm_format);
}
#endif
#ifdef HAVE_NATIVE_BACKEND
static struct gbm_device *
get_gbm_device (void)
{
MetaBackend *meta_backend = meta_get_backend ();
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (meta_backend);
if (META_IS_CURSOR_RENDERER_NATIVE (renderer))
return meta_cursor_renderer_native_get_gbm_device (META_CURSOR_RENDERER_NATIVE (renderer));
else
return NULL;
}
#endif
static void
meta_cursor_image_load_from_xcursor_image (MetaCursorImage *image,
XcursorImage *xc_image)
{
uint width, height, rowstride;
CoglPixelFormat cogl_format;
ClutterBackend *clutter_backend;
CoglContext *cogl_context;
CoglTexture *texture;
g_assert (self->texture == NULL);
width = xc_image->width;
height = xc_image->height;
@@ -149,210 +233,196 @@ meta_cursor_sprite_load_from_xcursor_image (MetaCursorSprite *self,
cogl_format = COGL_PIXEL_FORMAT_ARGB_8888;
#endif
image->hot_x = xc_image->xhot;
image->hot_y = xc_image->yhot;
clutter_backend = clutter_get_default_backend ();
cogl_context = clutter_backend_get_cogl_context (clutter_backend);
texture = cogl_texture_2d_new_from_data (cogl_context,
width, height,
cogl_format,
rowstride,
(uint8_t *) xc_image->pixels,
NULL);
meta_cursor_sprite_set_texture (self, texture,
xc_image->xhot, xc_image->yhot);
cogl_object_unref (texture);
image->texture = cogl_texture_2d_new_from_data (cogl_context,
width, height,
cogl_format,
rowstride,
(uint8_t *) xc_image->pixels,
NULL);
meta_cursor_renderer_realize_cursor_from_xcursor (renderer, self, xc_image);
}
static XcursorImage *
meta_cursor_sprite_get_current_frame_image (MetaCursorSprite *self)
{
return self->xcursor_images->images[self->current_frame];
}
void
meta_cursor_sprite_tick_frame (MetaCursorSprite *self)
{
XcursorImage *image;
if (!meta_cursor_sprite_is_animated (self))
return;
self->current_frame++;
if (self->current_frame >= self->xcursor_images->nimage)
self->current_frame = 0;
image = meta_cursor_sprite_get_current_frame_image (self);
g_clear_pointer (&self->texture, cogl_object_unref);
meta_cursor_sprite_load_from_xcursor_image (self, image);
}
guint
meta_cursor_sprite_get_current_frame_time (MetaCursorSprite *self)
{
if (!meta_cursor_sprite_is_animated (self))
return 0;
return self->xcursor_images->images[self->current_frame]->delay;
}
gboolean
meta_cursor_sprite_is_animated (MetaCursorSprite *self)
{
return (self->xcursor_images &&
self->xcursor_images->nimage > 1);
}
MetaCursorSprite *
meta_cursor_sprite_new (void)
{
return g_object_new (META_TYPE_CURSOR_SPRITE, NULL);
#ifdef HAVE_NATIVE_BACKEND
struct gbm_device *gbm = get_gbm_device ();
if (gbm)
meta_cursor_image_load_gbm_buffer (gbm,
image,
(uint8_t *) xc_image->pixels,
width, height, rowstride,
GBM_FORMAT_ARGB8888);
#endif
}
static void
meta_cursor_sprite_load_from_theme (MetaCursorSprite *self)
load_cursor_image (MetaCursorReference *cursor)
{
XcursorImage *image;
g_assert (self->cursor != META_CURSOR_NONE);
/* Either cursors are loaded from X cursors or buffers. Since
* buffers are converted over immediately, we can make sure to
* load this directly. */
g_assert (cursor->cursor != META_CURSOR_NONE);
/* We might be reloading with a different scale. If so clear the old data. */
if (self->xcursor_images)
{
g_clear_pointer (&self->texture, cogl_object_unref);
XcursorImagesDestroy (self->xcursor_images);
}
image = load_cursor_on_client (cursor->cursor);
if (!image)
return;
self->current_frame = 0;
self->xcursor_images = load_cursor_on_client (self->cursor,
self->theme_scale);
if (!self->xcursor_images)
meta_fatal ("Could not find cursor. Perhaps set XCURSOR_PATH?");
image = meta_cursor_sprite_get_current_frame_image (self);
meta_cursor_sprite_load_from_xcursor_image (self, image);
self->theme_dirty = FALSE;
meta_cursor_image_load_from_xcursor_image (&cursor->image, image);
XcursorImageDestroy (image);
}
MetaCursorSprite *
meta_cursor_sprite_from_theme (MetaCursor cursor)
MetaCursorReference *
meta_cursor_reference_from_theme (MetaCursor cursor)
{
MetaCursorSprite *self;
self = meta_cursor_sprite_new ();
MetaCursorReference *self = g_slice_new0 (MetaCursorReference);
self->ref_count = 1;
self->cursor = cursor;
self->theme_dirty = TRUE;
return self;
}
void
meta_cursor_sprite_set_texture (MetaCursorSprite *self,
CoglTexture *texture,
int hot_x,
int hot_y)
#ifdef HAVE_WAYLAND
static void
meta_cursor_image_load_from_buffer (MetaCursorImage *image,
struct wl_resource *buffer,
int hot_x,
int hot_y)
{
g_clear_pointer (&self->texture, cogl_object_unref);
if (texture)
self->texture = cogl_object_ref (texture);
self->hot_x = hot_x;
self->hot_y = hot_y;
ClutterBackend *backend;
CoglContext *cogl_context;
image->hot_x = hot_x;
image->hot_y = hot_y;
backend = clutter_get_default_backend ();
cogl_context = clutter_backend_get_cogl_context (backend);
image->texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context, buffer, NULL);
#ifdef HAVE_NATIVE_BACKEND
struct gbm_device *gbm = get_gbm_device ();
if (gbm)
{
uint32_t gbm_format;
uint64_t cursor_width, cursor_height;
uint width, height;
width = cogl_texture_get_width (COGL_TEXTURE (image->texture));
height = cogl_texture_get_height (COGL_TEXTURE (image->texture));
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (buffer);
if (shm_buffer)
{
int rowstride = wl_shm_buffer_get_stride (shm_buffer);
wl_shm_buffer_begin_access (shm_buffer);
switch (wl_shm_buffer_get_format (shm_buffer))
{
#if G_BYTE_ORDER == G_BIG_ENDIAN
case WL_SHM_FORMAT_ARGB8888:
gbm_format = GBM_FORMAT_ARGB8888;
break;
case WL_SHM_FORMAT_XRGB8888:
gbm_format = GBM_FORMAT_XRGB8888;
break;
#else
case WL_SHM_FORMAT_ARGB8888:
gbm_format = GBM_FORMAT_ARGB8888;
break;
case WL_SHM_FORMAT_XRGB8888:
gbm_format = GBM_FORMAT_XRGB8888;
break;
#endif
default:
g_warn_if_reached ();
gbm_format = GBM_FORMAT_ARGB8888;
}
meta_cursor_image_load_gbm_buffer (gbm,
image,
(uint8_t *) wl_shm_buffer_get_data (shm_buffer),
width, height, rowstride,
gbm_format);
wl_shm_buffer_end_access (shm_buffer);
}
else
{
/* HW cursors have a predefined size (at least 64x64), which usually is bigger than cursor theme
size, so themed cursors must be padded with transparent pixels to fill the
overlay. This is trivial if we have CPU access to the data, but it's not
possible if the buffer is in GPU memory (and possibly tiled too), so if we
don't get the right size, we fallback to GL.
*/
get_hardware_cursor_size (&cursor_width, &cursor_height);
if (width != cursor_width || height != cursor_height)
{
meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n");
return;
}
image->bo = gbm_bo_import (gbm, GBM_BO_IMPORT_WL_BUFFER, buffer, GBM_BO_USE_CURSOR);
if (!image->bo)
meta_warning ("Importing HW cursor from wl_buffer failed\n");
}
}
#endif
}
void
meta_cursor_sprite_set_texture_scale (MetaCursorSprite *self,
float scale)
MetaCursorReference *
meta_cursor_reference_from_buffer (struct wl_resource *buffer,
int hot_x,
int hot_y)
{
self->texture_scale = scale;
}
MetaCursorReference *self;
void
meta_cursor_sprite_set_theme_scale (MetaCursorSprite *self,
int theme_scale)
{
if (self->theme_scale != theme_scale)
self->theme_dirty = TRUE;
self->theme_scale = theme_scale;
self = g_slice_new0 (MetaCursorReference);
self->ref_count = 1;
meta_cursor_image_load_from_buffer (&self->image, buffer, hot_x, hot_y);
return self;
}
#endif
CoglTexture *
meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *self)
meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor,
int *hot_x,
int *hot_y)
{
return COGL_TEXTURE (self->texture);
if (!cursor->image.texture)
load_cursor_image (cursor);
if (hot_x)
*hot_x = cursor->image.hot_x;
if (hot_y)
*hot_y = cursor->image.hot_y;
return COGL_TEXTURE (cursor->image.texture);
}
#ifdef HAVE_NATIVE_BACKEND
struct gbm_bo *
meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
int *hot_x,
int *hot_y)
{
if (!cursor->image.bo)
load_cursor_image (cursor);
if (hot_x)
*hot_x = cursor->image.hot_x;
if (hot_y)
*hot_y = cursor->image.hot_y;
return cursor->image.bo;
}
#endif
MetaCursor
meta_cursor_sprite_get_meta_cursor (MetaCursorSprite *self)
meta_cursor_reference_get_meta_cursor (MetaCursorReference *cursor)
{
return self->cursor;
}
void
meta_cursor_sprite_get_hotspot (MetaCursorSprite *self,
int *hot_x,
int *hot_y)
{
*hot_x = self->hot_x;
*hot_y = self->hot_y;
}
float
meta_cursor_sprite_get_texture_scale (MetaCursorSprite *self)
{
return self->texture_scale;
}
void
meta_cursor_sprite_prepare_at (MetaCursorSprite *self,
int x,
int y)
{
g_signal_emit (self, signals[PREPARE_AT], 0, x, y);
}
void
meta_cursor_sprite_realize_texture (MetaCursorSprite *self)
{
if (self->theme_dirty)
meta_cursor_sprite_load_from_theme (self);
}
static void
meta_cursor_sprite_init (MetaCursorSprite *self)
{
self->texture_scale = 1.0f;
}
static void
meta_cursor_sprite_finalize (GObject *object)
{
MetaCursorSprite *self = META_CURSOR_SPRITE (object);
if (self->xcursor_images)
XcursorImagesDestroy (self->xcursor_images);
g_clear_pointer (&self->texture, cogl_object_unref);
G_OBJECT_CLASS (meta_cursor_sprite_parent_class)->finalize (object);
}
static void
meta_cursor_sprite_class_init (MetaCursorSpriteClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = meta_cursor_sprite_finalize;
signals[PREPARE_AT] = g_signal_new ("prepare-at",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 2,
G_TYPE_INT,
G_TYPE_INT);
return cursor->cursor;
}

View File

@@ -22,54 +22,25 @@
#ifndef META_CURSOR_H
#define META_CURSOR_H
typedef struct _MetaCursorReference MetaCursorReference;
MetaCursorReference * meta_cursor_reference_ref (MetaCursorReference *cursor);
void meta_cursor_reference_unref (MetaCursorReference *cursor);
#include <meta/common.h>
#include <meta/boxes.h>
typedef struct _MetaCursorSprite MetaCursorSprite;
MetaCursorReference * meta_cursor_reference_from_theme (MetaCursor cursor);
#define META_TYPE_CURSOR_SPRITE (meta_cursor_sprite_get_type ())
G_DECLARE_FINAL_TYPE (MetaCursorSprite,
meta_cursor_sprite,
META, CURSOR_SPRITE,
GObject);
#ifdef HAVE_WAYLAND
#include <wayland-server.h>
MetaCursorReference * meta_cursor_reference_from_buffer (struct wl_resource *buffer,
int hot_x,
int hot_y);
#endif
MetaCursorSprite * meta_cursor_sprite_new (void);
MetaCursorSprite * meta_cursor_sprite_from_theme (MetaCursor cursor);
void meta_cursor_sprite_set_theme_scale (MetaCursorSprite *self,
int scale);
MetaCursor meta_cursor_sprite_get_meta_cursor (MetaCursorSprite *self);
MetaCursor meta_cursor_reference_get_meta_cursor (MetaCursorReference *cursor);
Cursor meta_cursor_create_x_cursor (Display *xdisplay,
MetaCursor cursor);
void meta_cursor_sprite_prepare_at (MetaCursorSprite *self,
int x,
int y);
void meta_cursor_sprite_realize_texture (MetaCursorSprite *self);
void meta_cursor_sprite_set_texture (MetaCursorSprite *self,
CoglTexture *texture,
int hot_x,
int hot_y);
void meta_cursor_sprite_set_texture_scale (MetaCursorSprite *self,
float scale);
CoglTexture *meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *self);
void meta_cursor_sprite_get_hotspot (MetaCursorSprite *self,
int *hot_x,
int *hot_y);
float meta_cursor_sprite_get_texture_scale (MetaCursorSprite *self);
gboolean meta_cursor_sprite_is_animated (MetaCursorSprite *self);
void meta_cursor_sprite_tick_frame (MetaCursorSprite *self);
guint meta_cursor_sprite_get_current_frame_time (MetaCursorSprite *self);
#endif /* META_CURSOR_H */

View File

@@ -523,13 +523,15 @@ update_trackball_scroll_button (MetaInputSettings *input_settings,
}
else if (!device)
{
MetaInputSettingsPrivate *priv;
const GSList *devices;
priv = meta_input_settings_get_instance_private (input_settings);
devices = clutter_device_manager_peek_devices (priv->device_manager);
while (devices)
{
device = devices->data;
ClutterInputDevice *device = devices->data;
if (device_is_trackball (device))
input_settings_class->set_scroll_button (input_settings, device, button);

View File

@@ -65,7 +65,6 @@ typedef struct {
gboolean is_primary;
gboolean is_presentation;
gboolean is_underscanning;
} MetaOutputConfig;
typedef struct {
@@ -83,8 +82,7 @@ struct _MetaMonitorConfig {
gboolean current_is_for_laptop_lid;
MetaConfiguration *previous;
GFile *user_file;
GFile *system_file;
GFile *file;
GCancellable *save_cancellable;
UpClient *up_client;
@@ -240,7 +238,6 @@ meta_monitor_config_init (MetaMonitorConfig *self)
{
const char *filename;
char *path;
const char * const *system_dirs;
self->configs = g_hash_table_new_full (config_hash, config_equal, NULL, (GDestroyNotify) config_unref);
@@ -249,17 +246,9 @@ meta_monitor_config_init (MetaMonitorConfig *self)
filename = "monitors.xml";
path = g_build_filename (g_get_user_config_dir (), filename, NULL);
self->user_file = g_file_new_for_path (path);
self->file = g_file_new_for_path (path);
g_free (path);
for (system_dirs = g_get_system_config_dirs (); !self->system_file && *system_dirs; system_dirs++)
{
path = g_build_filename (*system_dirs, filename, NULL);
if (g_file_test (path, G_FILE_TEST_EXISTS))
self->system_file = g_file_new_for_path (path);
g_free (path);
}
self->up_client = up_client_new ();
self->lid_is_closed = up_client_get_lid_is_closed (self->up_client);
@@ -404,8 +393,7 @@ handle_start_element (GMarkupParseContext *context,
strcmp (element_name, "reflect_x") == 0 ||
strcmp (element_name, "reflect_y") == 0 ||
strcmp (element_name, "primary") == 0 ||
strcmp (element_name, "presentation") == 0 ||
strcmp (element_name, "underscanning") == 0) && parser->unknown_count == 0)
strcmp (element_name, "presentation") == 0) && parser->unknown_count == 0)
{
parser->state = STATE_OUTPUT_FIELD;
@@ -489,8 +477,8 @@ handle_end_element (GMarkupParseContext *context,
}
else
{
if (parser->output.rect.width == 0 ||
parser->output.rect.height == 0)
if (parser->output.rect.width == 0 &&
parser->output.rect.width == 0)
parser->output.enabled = FALSE;
else
parser->output.enabled = TRUE;
@@ -712,8 +700,6 @@ handle_text (GMarkupParseContext *context,
parser->output.is_primary = read_bool (text, text_len, error);
else if (strcmp (parser->output_field, "presentation") == 0)
parser->output.is_presentation = read_bool (text, text_len, error);
else if (strcmp (parser->output_field, "underscanning") == 0)
parser->output.is_underscanning = read_bool (text, text_len, error);
else
g_assert_not_reached ();
return;
@@ -731,8 +717,8 @@ static const GMarkupParser config_parser = {
.text = handle_text,
};
static gboolean
load_config_file (MetaMonitorConfig *self, GFile *file)
static void
meta_monitor_config_load (MetaMonitorConfig *self)
{
char *contents;
gsize size;
@@ -750,12 +736,14 @@ load_config_file (MetaMonitorConfig *self, GFile *file)
*/
error = NULL;
ok = g_file_load_contents (file, NULL, &contents, &size, NULL, &error);
ok = g_file_load_contents (self->file, NULL, &contents, &size, NULL, &error);
if (!ok)
{
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
meta_warning ("Failed to load stored monitor configuration: %s\n", error->message);
g_error_free (error);
return FALSE;
return;
}
memset (&parser, 0, sizeof (ConfigParser));
@@ -784,17 +772,6 @@ load_config_file (MetaMonitorConfig *self, GFile *file)
g_markup_parse_context_free (context);
g_free (contents);
return ok;
}
static void
meta_monitor_config_load (MetaMonitorConfig *self)
{
if (self->user_file && load_config_file (self, self->user_file))
return;
if (self->system_file && load_config_file (self, self->system_file))
return;
}
MetaMonitorConfig *
@@ -886,14 +863,14 @@ apply_configuration (MetaMonitorConfig *self,
MetaConfiguration *config,
MetaMonitorManager *manager)
{
g_autoptr(GPtrArray) crtcs = NULL;
g_autoptr(GPtrArray) outputs = NULL;
GPtrArray *crtcs, *outputs;
gboolean ret = FALSE;
crtcs = g_ptr_array_new_full (config->n_outputs, (GDestroyNotify)meta_crtc_info_free);
outputs = g_ptr_array_new_full (config->n_outputs, (GDestroyNotify)meta_output_info_free);
if (!meta_monitor_config_assign_crtcs (config, manager, crtcs, outputs))
return FALSE;
goto out;
meta_monitor_manager_apply_configuration (manager,
(MetaCRTCInfo**)crtcs->pdata, crtcs->len,
@@ -905,7 +882,12 @@ apply_configuration (MetaMonitorConfig *self,
* inside turn_off_laptop_display / apply_configuration_with_lid */
self->current_is_for_laptop_lid = FALSE;
return TRUE;
ret = TRUE;
out:
g_ptr_array_unref (crtcs);
g_ptr_array_unref (outputs);
return ret;
}
static gboolean
@@ -1074,12 +1056,12 @@ meta_monitor_config_apply_stored (MetaMonitorConfig *self,
* which are internal monitors), or failing that, the one with the
* best resolution
*/
static int
static MetaOutput *
find_primary_output (MetaOutput *outputs,
unsigned n_outputs)
{
unsigned i;
int best;
MetaOutput *best;
int best_width, best_height;
g_assert (n_outputs >= 1);
@@ -1087,23 +1069,23 @@ find_primary_output (MetaOutput *outputs,
for (i = 0; i < n_outputs; i++)
{
if (outputs[i].is_primary)
return i;
return &outputs[i];
}
for (i = 0; i < n_outputs; i++)
{
if (output_is_laptop (&outputs[i]))
return i;
return &outputs[i];
}
best = -1;
best = NULL;
best_width = 0; best_height = 0;
for (i = 0; i < n_outputs; i++)
{
if (outputs[i].preferred_mode->width * outputs[i].preferred_mode->height >
best_width * best_height)
{
best = i;
best = &outputs[i];
best_width = outputs[i].preferred_mode->width;
best_height = outputs[i].preferred_mode->height;
}
@@ -1141,7 +1123,7 @@ make_suggested_config (MetaMonitorConfig *self,
MetaConfiguration *config)
{
unsigned int i;
int primary;
MetaOutput *primary;
GList *region = NULL;
g_return_val_if_fail (config != NULL, FALSE);
@@ -1149,7 +1131,7 @@ make_suggested_config (MetaMonitorConfig *self,
for (i = 0; i < n_outputs; i++)
{
gboolean is_primary = ((int)i == primary);
gboolean is_primary = (&outputs[i] == primary);
if (outputs[i].suggested_x < 0 || outputs[i].suggested_y < 0)
return FALSE;
@@ -1176,81 +1158,6 @@ make_suggested_config (MetaMonitorConfig *self,
return TRUE;
}
static void
config_one_untiled_output (MetaOutput *outputs,
MetaConfiguration *config,
int idx, gboolean is_primary,
int *x, unsigned long *output_configured_bitmap)
{
MetaOutput *output = &outputs[idx];
if (*output_configured_bitmap & (1 << idx))
return;
init_config_from_preferred_mode (&config->outputs[idx], output);
config->outputs[idx].is_primary = is_primary;
config->outputs[idx].rect.x = *x;
*x += config->outputs[idx].rect.width;
*output_configured_bitmap |= (1 << idx);
}
static void
config_one_tiled_group (MetaOutput *outputs,
MetaConfiguration *config,
int base_idx, gboolean is_primary,
int n_outputs,
int *x, unsigned long *output_configured_bitmap)
{
guint32 num_h_tile, num_v_tile, ht, vt;
int j;
int cur_x, cur_y, addx = 0;
if (*output_configured_bitmap & (1 << base_idx))
return;
if (outputs[base_idx].tile_info.group_id == 0)
return;
cur_x = cur_y = 0;
num_h_tile = outputs[base_idx].tile_info.max_h_tiles;
num_v_tile = outputs[base_idx].tile_info.max_v_tiles;
/* iterate over horizontal tiles */
cur_x = *x;
for (ht = 0; ht < num_h_tile; ht++)
{
cur_y = 0;
addx = 0;
for (vt = 0; vt < num_v_tile; vt++)
{
for (j = 0; j < n_outputs; j++)
{
if (outputs[j].tile_info.group_id != outputs[base_idx].tile_info.group_id)
continue;
if (outputs[j].tile_info.loc_h_tile != ht ||
outputs[j].tile_info.loc_v_tile != vt)
continue;
if (ht == 0 && vt == 0 && is_primary)
config->outputs[j].is_primary = TRUE;
init_config_from_preferred_mode (&config->outputs[j], &outputs[j]);
config->outputs[j].rect.x = cur_x;
config->outputs[j].rect.y = cur_y;
*output_configured_bitmap |= (1 << j);
cur_y += outputs[j].tile_info.tile_h;
if (vt == 0)
addx += outputs[j].tile_info.tile_w;
}
}
cur_x += addx;
}
*x = cur_x;
}
static void
make_linear_config (MetaMonitorConfig *self,
MetaOutput *outputs,
@@ -1259,41 +1166,31 @@ make_linear_config (MetaMonitorConfig *self,
int max_height,
MetaConfiguration *config)
{
unsigned long output_configured_bitmap = 0;
MetaOutput *primary;
unsigned i;
int x;
int primary;
g_return_if_fail (config != NULL);
primary = find_primary_output (outputs, n_outputs);
x = 0;
/* set the primary up first at 0 */
if (outputs[primary].tile_info.group_id)
{
config_one_tiled_group (outputs, config, primary, TRUE, n_outputs,
&x, &output_configured_bitmap);
}
else
{
config_one_untiled_output (outputs, config, primary, TRUE,
&x, &output_configured_bitmap);
}
/* then add other tiled monitors */
x = primary->preferred_mode->width;
for (i = 0; i < n_outputs; i++)
{
config_one_tiled_group (outputs, config, i, FALSE, n_outputs,
&x, &output_configured_bitmap);
}
gboolean is_primary = (&outputs[i] == primary);
/* then add remaining monitors */
for (i = 0; i < n_outputs; i++)
{
config_one_untiled_output (outputs, config, i, FALSE,
&x, &output_configured_bitmap);
init_config_from_preferred_mode (&config->outputs[i], &outputs[i]);
config->outputs[i].is_primary = is_primary;
if (is_primary)
{
config->outputs[i].rect.x = 0;
}
else
{
config->outputs[i].rect.x = x;
x += config->outputs[i].rect.width;
}
}
}
@@ -1417,7 +1314,7 @@ ensure_at_least_one_output (MetaMonitorConfig *self,
unsigned n_outputs)
{
MetaConfiguration *config;
int primary;
MetaOutput *primary;
unsigned i;
/* Check that we have at least one active output */
@@ -1435,7 +1332,7 @@ ensure_at_least_one_output (MetaMonitorConfig *self,
for (i = 0; i < n_outputs; i++)
{
gboolean is_primary = ((int)i == primary);
gboolean is_primary = (&outputs[i] == primary);
if (is_primary)
{
@@ -1511,7 +1408,6 @@ init_config_from_output (MetaOutputConfig *config,
config->transform = output->crtc->transform;
config->is_primary = output->is_primary;
config->is_presentation = output->is_presentation;
config->is_underscanning = output->is_underscanning;
}
void
@@ -1702,8 +1598,7 @@ meta_monitor_config_save (MetaMonitorConfig *self)
" <reflect_x>%s</reflect_x>\n"
" <reflect_y>no</reflect_y>\n"
" <primary>%s</primary>\n"
" <presentation>%s</presentation>\n"
" <underscanning>%s</underscanning>\n",
" <presentation>%s</presentation>\n",
output->rect.width,
output->rect.height,
refresh_rate,
@@ -1712,8 +1607,7 @@ meta_monitor_config_save (MetaMonitorConfig *self)
rotation_map[output->transform & 0x3],
output->transform >= META_MONITOR_TRANSFORM_FLIPPED ? "yes" : "no",
output->is_primary ? "yes" : "no",
output->is_presentation ? "yes" : "no",
output->is_underscanning ? "yes" : "no");
output->is_presentation ? "yes" : "no");
}
g_string_append (buffer, " </output>\n");
@@ -1728,7 +1622,7 @@ meta_monitor_config_save (MetaMonitorConfig *self)
closure->config = g_object_ref (self);
closure->buffer = buffer;
g_file_replace_contents_async (self->user_file,
g_file_replace_contents_async (self->file,
buffer->str, buffer->len,
NULL, /* etag */
TRUE,
@@ -1846,7 +1740,7 @@ crtc_assignment_assign (CrtcAssignment *assign,
}
else
{
info = g_slice_new0 (MetaCRTCInfo);
MetaCRTCInfo *info = g_slice_new0 (MetaCRTCInfo);
info->crtc = crtc;
info->mode = mode;
@@ -1920,6 +1814,7 @@ real_assign_crtcs (CrtcAssignment *assignment,
MetaOutputKey *output_key;
MetaOutputConfig *output_config;
unsigned int i;
gboolean success;
if (output_num == assignment->config->n_outputs)
return TRUE;
@@ -1936,6 +1831,8 @@ real_assign_crtcs (CrtcAssignment *assignment,
&crtcs, &n_crtcs,
&outputs, &n_outputs);
success = FALSE;
for (i = 0; i < n_crtcs; i++)
{
MetaCRTC *crtc = &crtcs[i];
@@ -1982,7 +1879,10 @@ real_assign_crtcs (CrtcAssignment *assignment,
output))
{
if (real_assign_crtcs (assignment, output_num + 1))
return TRUE;
{
success = TRUE;
goto out;
}
crtc_assignment_unassign (assignment, crtc, output);
}
@@ -1991,7 +1891,8 @@ real_assign_crtcs (CrtcAssignment *assignment,
}
}
return FALSE;
out:
return success;
}
static gboolean
@@ -2040,7 +1941,6 @@ meta_monitor_config_assign_crtcs (MetaConfiguration *config,
&config->keys[i]);
output_info->is_primary = output_config->is_primary;
output_info->is_presentation = output_config->is_presentation;
output_info->is_underscanning = output_config->is_underscanning;
g_ptr_array_add (outputs, output_info);
}

View File

@@ -27,10 +27,6 @@
#include "meta-monitor-manager-dummy.h"
#include <stdlib.h>
#include <meta/util.h>
#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
struct _MetaMonitorManagerDummy
@@ -48,69 +44,9 @@ G_DEFINE_TYPE (MetaMonitorManagerDummy, meta_monitor_manager_dummy, META_TYPE_MO
static void
meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
{
unsigned int num_monitors = 1;
int *monitor_scales = NULL;
const char *num_monitors_str;
const char *monitor_scales_str;
unsigned int i;
int current_x = 0;
/* To control what monitor configuration is generated, there are two available
* environmental variables that can be used:
*
* MUTTER_DEBUG_NUM_DUMMY_MONITORS
*
* Specifies the number of dummy monitors to include in the stage. Every
* monitor is 1024x786 pixels and they are placed on a horizontal row.
*
* MUTTER_DEBUG_DUMMY_MONITOR_SCALES
*
* A comma separated list that specifies the scales of the dummy monitors.
*
* For example the following configuration results in two monitors, where the
* first one has the monitor scale 1, and the other the monitor scale 2.
*
* MUTTER_DEBUG_NUM_DUMMY_MONITORS=2
* MUTTER_DEBUG_DUMMY_MONITOR_SCALES=1,2
*/
num_monitors_str = getenv ("MUTTER_DEBUG_NUM_DUMMY_MONITORS");
if (num_monitors_str)
{
num_monitors = g_ascii_strtoll (num_monitors_str, NULL, 10);
if (num_monitors <= 0)
{
meta_warning ("Invalid number of dummy monitors");
num_monitors = 1;
}
}
monitor_scales = g_newa (int, num_monitors);
for (i = 0; i < num_monitors; i++)
monitor_scales[i] = 1;
monitor_scales_str = getenv ("MUTTER_DEBUG_DUMMY_MONITOR_SCALES");
if (monitor_scales_str)
{
gchar **scales_str_list;
scales_str_list = g_strsplit (monitor_scales_str, ",", -1);
if (g_strv_length (scales_str_list) != num_monitors)
meta_warning ("Number of specified monitor scales differ from number "
"of monitors (defaults to 1).\n");
for (i = 0; i < num_monitors && scales_str_list[i]; i++)
{
int scale = g_ascii_strtoll (scales_str_list[i], NULL, 10);
if (scale == 1 || scale == 2)
monitor_scales[i] = scale;
else
meta_warning ("Invalid dummy monitor scale");
}
g_strfreev (scales_str_list);
}
manager->max_screen_width = 65535;
manager->max_screen_height = 65535;
manager->screen_width = 1024 * num_monitors;
manager->screen_width = 1024;
manager->screen_height = 768;
manager->modes = g_new0 (MetaMonitorMode, 1);
@@ -121,52 +57,46 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
manager->modes[0].height = 768;
manager->modes[0].refresh_rate = 60.0;
manager->crtcs = g_new0 (MetaCRTC, num_monitors);
manager->n_crtcs = num_monitors;
manager->outputs = g_new0 (MetaOutput, num_monitors);
manager->n_outputs = num_monitors;
manager->crtcs = g_new0 (MetaCRTC, 1);
manager->n_crtcs = 1;
for (i = 0; i < num_monitors; i++)
{
manager->crtcs[i].crtc_id = i + 1;
manager->crtcs[i].rect.x = current_x;
manager->crtcs[i].rect.y = 0;
manager->crtcs[i].rect.width = manager->modes[0].width;
manager->crtcs[i].rect.height = manager->modes[0].height;
manager->crtcs[i].current_mode = &manager->modes[0];
manager->crtcs[i].transform = META_MONITOR_TRANSFORM_NORMAL;
manager->crtcs[i].all_transforms = ALL_TRANSFORMS;
manager->crtcs[i].is_dirty = FALSE;
manager->crtcs[i].logical_monitor = NULL;
manager->crtcs[0].crtc_id = 1;
manager->crtcs[0].rect.x = 0;
manager->crtcs[0].rect.y = 0;
manager->crtcs[0].rect.width = manager->modes[0].width;
manager->crtcs[0].rect.height = manager->modes[0].height;
manager->crtcs[0].current_mode = &manager->modes[0];
manager->crtcs[0].transform = META_MONITOR_TRANSFORM_NORMAL;
manager->crtcs[0].all_transforms = ALL_TRANSFORMS;
manager->crtcs[0].is_dirty = FALSE;
manager->crtcs[0].logical_monitor = NULL;
current_x += manager->crtcs[i].rect.width;
manager->outputs = g_new0 (MetaOutput, 1);
manager->n_outputs = 1;
manager->outputs[i].crtc = &manager->crtcs[i];
manager->outputs[i].winsys_id = i + 1;
manager->outputs[i].name = g_strdup_printf ("LVDS%d", i + 1);
manager->outputs[i].vendor = g_strdup ("MetaProducts Inc.");
manager->outputs[i].product = g_strdup ("unknown");
manager->outputs[i].serial = g_strdup ("0xC0FFEE");
manager->outputs[i].suggested_x = -1;
manager->outputs[i].suggested_y = -1;
manager->outputs[i].width_mm = 222;
manager->outputs[i].height_mm = 125;
manager->outputs[i].subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
manager->outputs[i].preferred_mode = &manager->modes[0];
manager->outputs[i].n_modes = 1;
manager->outputs[i].modes = g_new0 (MetaMonitorMode *, 1);
manager->outputs[i].modes[0] = &manager->modes[0];
manager->outputs[i].n_possible_crtcs = 1;
manager->outputs[i].possible_crtcs = g_new0 (MetaCRTC *, 1);
manager->outputs[i].possible_crtcs[0] = &manager->crtcs[i];
manager->outputs[i].n_possible_clones = 0;
manager->outputs[i].possible_clones = g_new0 (MetaOutput *, 0);
manager->outputs[i].backlight = -1;
manager->outputs[i].backlight_min = 0;
manager->outputs[i].backlight_max = 0;
manager->outputs[i].connector_type = META_CONNECTOR_TYPE_LVDS;
manager->outputs[i].scale = monitor_scales[i];
}
manager->outputs[0].crtc = &manager->crtcs[0];
manager->outputs[0].winsys_id = 1;
manager->outputs[0].name = g_strdup ("LVDS");
manager->outputs[0].vendor = g_strdup ("MetaProducts Inc.");
manager->outputs[0].product = g_strdup ("unknown");
manager->outputs[0].serial = g_strdup ("0xC0FFEE");
manager->outputs[0].width_mm = 222;
manager->outputs[0].height_mm = 125;
manager->outputs[0].subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
manager->outputs[0].preferred_mode = &manager->modes[0];
manager->outputs[0].n_modes = 1;
manager->outputs[0].modes = g_new0 (MetaMonitorMode *, 1);
manager->outputs[0].modes[0] = &manager->modes[0];
manager->outputs[0].n_possible_crtcs = 1;
manager->outputs[0].possible_crtcs = g_new0 (MetaCRTC *, 1);
manager->outputs[0].possible_crtcs[0] = &manager->crtcs[0];
manager->outputs[0].n_possible_clones = 0;
manager->outputs[0].possible_clones = g_new0 (MetaOutput *, 0);
manager->outputs[0].backlight = -1;
manager->outputs[0].backlight_min = 0;
manager->outputs[0].backlight_max = 0;
manager->outputs[0].connector_type = META_CONNECTOR_TYPE_LVDS;
manager->outputs[0].scale = 1;
}
static void
@@ -197,7 +127,7 @@ meta_monitor_manager_dummy_apply_config (MetaMonitorManager *manager,
{
MetaMonitorMode *mode;
MetaOutput *output;
unsigned int j;
int i, n_outputs;
int width, height;
mode = crtc_info->mode;
@@ -223,9 +153,10 @@ meta_monitor_manager_dummy_apply_config (MetaMonitorManager *manager,
screen_width = MAX (screen_width, crtc_info->x + width);
screen_height = MAX (screen_height, crtc_info->y + height);
for (j = 0; j < crtc_info->outputs->len; j++)
n_outputs = crtc_info->outputs->len;
for (i = 0; i < n_outputs; i++)
{
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
output = ((MetaOutput**)crtc_info->outputs->pdata)[i];
output->is_dirty = TRUE;
output->crtc = crtc;

View File

@@ -56,7 +56,6 @@ typedef struct _MetaMonitorMode MetaMonitorMode;
typedef struct _MetaMonitorInfo MetaMonitorInfo;
typedef struct _MetaCRTCInfo MetaCRTCInfo;
typedef struct _MetaOutputInfo MetaOutputInfo;
typedef struct _MetaTileInfo MetaTileInfo;
typedef enum {
META_MONITOR_TRANSFORM_NORMAL,
@@ -90,17 +89,6 @@ typedef enum {
META_CONNECTOR_TYPE_DSI = 16,
} MetaConnectorType;
struct _MetaTileInfo {
guint32 group_id;
guint32 flags;
guint32 max_h_tiles;
guint32 max_v_tiles;
guint32 loc_h_tile;
guint32 loc_v_tile;
guint32 tile_w;
guint32 tile_h;
};
struct _MetaOutput
{
/* The CRTC driving this output, NULL if the output is not enabled */
@@ -144,8 +132,6 @@ struct _MetaOutput
*/
gboolean is_primary;
gboolean is_presentation;
gboolean is_underscanning;
gboolean supports_underscanning;
gpointer driver_private;
GDestroyNotify driver_notify;
@@ -154,8 +140,6 @@ struct _MetaOutput
gboolean hotplug_mode_update;
gint suggested_x;
gint suggested_y;
MetaTileInfo tile_info;
};
struct _MetaCRTC
@@ -174,11 +158,7 @@ struct _MetaCRTC
/* Used when changing configuration */
gboolean is_dirty;
/* Used by cursor renderer backend */
void *cursor_renderer_private;
gpointer driver_private;
GDestroyNotify driver_notify;
MetaCursorReference *cursor;
};
struct _MetaMonitorMode
@@ -195,7 +175,6 @@ struct _MetaMonitorMode
GDestroyNotify driver_notify;
};
#define META_MAX_OUTPUTS_PER_MONITOR 4
/**
* MetaMonitorInfo:
*
@@ -211,14 +190,9 @@ struct _MetaMonitorInfo
int number;
int xinerama_index;
MetaRectangle rect;
/* for tiled monitors these are calculated, from untiled just copied */
float refresh_rate;
int width_mm;
int height_mm;
gboolean is_primary;
gboolean is_presentation; /* XXX: not yet used */
gboolean in_fullscreen;
int scale;
/* 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.
@@ -229,12 +203,6 @@ struct _MetaMonitorInfo
the primary one).
*/
glong winsys_id;
guint32 tile_group_id;
int monitor_winsys_xid;
int n_outputs;
MetaOutput *outputs[META_MAX_OUTPUTS_PER_MONITOR];
};
/*
@@ -262,7 +230,6 @@ struct _MetaOutputInfo {
MetaOutput *output;
gboolean is_primary;
gboolean is_presentation;
gboolean is_underscanning;
};
#define META_TYPE_MONITOR_MANAGER (meta_monitor_manager_get_type ())
@@ -352,13 +319,6 @@ struct _MetaMonitorManagerClass
unsigned short *,
unsigned short *,
unsigned short *);
void (*add_monitor) (MetaMonitorManager *,
MetaMonitorInfo *);
void (*delete_monitor) (MetaMonitorManager *,
int monitor_winsys_xid);
};
void meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager);

View File

@@ -71,98 +71,6 @@ meta_monitor_manager_init (MetaMonitorManager *manager)
{
}
/*
* rules for constructing a tiled monitor
* 1. find a tile_group_id
* 2. iterate over all outputs for that tile group id
* 3. see if output has a crtc and if it is configured for the tile size
* 4. calculate the total tile size
* 5. set tile finished size
* 6. check for more tile_group_id
*/
static void
construct_tile_monitor (MetaMonitorManager *manager,
GArray *monitor_infos,
guint32 tile_group_id)
{
MetaMonitorInfo info;
unsigned i;
for (i = 0; i < monitor_infos->len; i++)
{
MetaMonitorInfo *pinfo = &g_array_index (monitor_infos, MetaMonitorInfo, i);
if (pinfo->tile_group_id == tile_group_id)
return;
}
/* didn't find it */
info.number = monitor_infos->len;
info.tile_group_id = tile_group_id;
info.is_presentation = FALSE;
info.refresh_rate = 0.0;
info.width_mm = 0;
info.height_mm = 0;
info.is_primary = FALSE;
info.rect.x = INT_MAX;
info.rect.y = INT_MAX;
info.rect.width = 0;
info.rect.height = 0;
info.winsys_id = 0;
info.n_outputs = 0;
info.monitor_winsys_xid = 0;
for (i = 0; i < manager->n_outputs; i++)
{
MetaOutput *output = &manager->outputs[i];
if (!output->tile_info.group_id)
continue;
if (output->tile_info.group_id != tile_group_id)
continue;
if (!output->crtc)
continue;
if (output->crtc->rect.width != (int)output->tile_info.tile_w ||
output->crtc->rect.height != (int)output->tile_info.tile_h)
continue;
if (output->tile_info.loc_h_tile == 0 && output->tile_info.loc_v_tile == 0)
{
info.refresh_rate = output->crtc->current_mode->refresh_rate;
info.width_mm = output->width_mm;
info.height_mm = output->height_mm;
info.winsys_id = output->winsys_id;
}
/* hack */
if (output->crtc->rect.x < info.rect.x)
info.rect.x = output->crtc->rect.x;
if (output->crtc->rect.y < info.rect.y)
info.rect.y = output->crtc->rect.y;
if (output->tile_info.loc_h_tile == 0)
info.rect.height += output->tile_info.tile_h;
if (output->tile_info.loc_v_tile == 0)
info.rect.width += output->tile_info.tile_w;
if (info.n_outputs > META_MAX_OUTPUTS_PER_MONITOR)
continue;
info.outputs[info.n_outputs++] = output;
}
/* if we don't have a winsys id, i.e. we haven't found tile 0,0
don't try and add this to the monitor infos */
if (!info.winsys_id)
return;
g_array_append_val (monitor_infos, info);
}
/*
* make_logical_config:
*
@@ -173,7 +81,6 @@ construct_tile_monitor (MetaMonitorManager *manager,
static void
make_logical_config (MetaMonitorManager *manager)
{
MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_GET_CLASS (manager);
GArray *monitor_infos;
unsigned int i, j;
@@ -184,15 +91,6 @@ make_logical_config (MetaMonitorManager *manager)
for each of them, unless they reference a rectangle that
is already there.
*/
/* for tiling we need to work out how many tiled outputs there are */
for (i = 0; i < manager->n_outputs; i++)
{
MetaOutput *output = &manager->outputs[i];
if (output->tile_info.group_id)
construct_tile_monitor (manager, monitor_infos, output->tile_info.group_id);
}
for (i = 0; i < manager->n_crtcs; i++)
{
MetaCRTC *crtc = &manager->crtcs[i];
@@ -204,8 +102,8 @@ make_logical_config (MetaMonitorManager *manager)
for (j = 0; j < monitor_infos->len; j++)
{
MetaMonitorInfo *info = &g_array_index (monitor_infos, MetaMonitorInfo, j);
if (meta_rectangle_contains_rect (&info->rect,
&crtc->rect))
if (meta_rectangle_equal (&crtc->rect,
&info->rect))
{
crtc->logical_monitor = info;
break;
@@ -217,10 +115,7 @@ make_logical_config (MetaMonitorManager *manager)
MetaMonitorInfo info;
info.number = monitor_infos->len;
info.tile_group_id = 0;
info.rect = crtc->rect;
info.refresh_rate = crtc->current_mode->refresh_rate;
info.scale = 1;
info.is_primary = FALSE;
/* This starts true because we want
is_presentation only if all outputs are
@@ -230,8 +125,7 @@ make_logical_config (MetaMonitorManager *manager)
info.is_presentation = TRUE;
info.in_fullscreen = -1;
info.winsys_id = 0;
info.n_outputs = 0;
info.monitor_winsys_xid = 0;
g_array_append_val (monitor_infos, info);
crtc->logical_monitor = &g_array_index (monitor_infos, MetaMonitorInfo,
@@ -253,9 +147,6 @@ make_logical_config (MetaMonitorManager *manager)
if (output->crtc == NULL)
continue;
if (output->tile_info.group_id)
continue;
/* We must have a logical monitor on every CRTC at this point */
g_assert (output->crtc->logical_monitor != NULL);
@@ -264,17 +155,8 @@ make_logical_config (MetaMonitorManager *manager)
info->is_primary = info->is_primary || output->is_primary;
info->is_presentation = info->is_presentation && output->is_presentation;
info->width_mm = output->width_mm;
info->height_mm = output->height_mm;
info->outputs[0] = output;
info->n_outputs = 1;
if (output->is_primary || info->winsys_id == 0)
{
info->scale = output->scale;
info->winsys_id = output->winsys_id;
}
info->winsys_id = output->winsys_id;
if (info->is_primary)
manager->primary_monitor_index = info->number;
@@ -282,10 +164,6 @@ make_logical_config (MetaMonitorManager *manager)
manager->n_monitor_infos = monitor_infos->len;
manager->monitor_infos = (void*)g_array_free (monitor_infos, FALSE);
if (manager_class->add_monitor)
for (i = 0; i < manager->n_monitor_infos; i++)
manager_class->add_monitor (manager, &manager->monitor_infos[i]);
}
static void
@@ -386,21 +264,6 @@ meta_monitor_manager_free_mode_array (MetaMonitorMode *old_modes,
g_free (old_modes);
}
static void
meta_monitor_manager_free_crtc_array (MetaCRTC *old_crtcs,
int n_old_crtcs)
{
int i;
for (i = 0; i < n_old_crtcs; i++)
{
if (old_crtcs[i].driver_notify)
old_crtcs[i].driver_notify (&old_crtcs[i]);
}
g_free (old_crtcs);
}
static void
meta_monitor_manager_finalize (GObject *object)
{
@@ -408,8 +271,8 @@ meta_monitor_manager_finalize (GObject *object)
meta_monitor_manager_free_output_array (manager->outputs, manager->n_outputs);
meta_monitor_manager_free_mode_array (manager->modes, manager->n_modes);
meta_monitor_manager_free_crtc_array (manager->crtcs, manager->n_crtcs);
g_free (manager->monitor_infos);
g_free (manager->crtcs);
G_OBJECT_CLASS (meta_monitor_manager_parent_class)->finalize (object);
}
@@ -490,14 +353,16 @@ static char *
make_display_name (MetaMonitorManager *manager,
MetaOutput *output)
{
g_autofree char *inches = NULL;
g_autofree char *vendor_name = NULL;
char *inches = NULL;
char *vendor_name = NULL;
char *ret;
switch (output->connector_type)
{
case META_CONNECTOR_TYPE_LVDS:
case META_CONNECTOR_TYPE_eDP:
return g_strdup (_("Built-in display"));
ret = g_strdup (_("Built-in display"));
goto out;
default:
break;
}
@@ -533,12 +398,18 @@ make_display_name (MetaMonitorManager *manager,
/* TRANSLATORS: this is a monitor vendor name, followed by a
* size in inches, like 'Dell 15"'
*/
return g_strdup_printf (_("%s %s"), vendor_name, inches);
ret = g_strdup_printf (_("%s %s"), vendor_name, inches);
}
else
{
return g_strdup (vendor_name);
ret = g_strdup (vendor_name);
}
out:
g_free (inches);
g_free (vendor_name);
return ret;
}
static const char *
@@ -649,10 +520,6 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
g_variant_new_boolean (output->is_presentation));
g_variant_builder_add (&properties, "{sv}", "connector-type",
g_variant_new_string (get_connector_type_name (output->connector_type)));
g_variant_builder_add (&properties, "{sv}", "underscanning",
g_variant_new_boolean (output->is_underscanning));
g_variant_builder_add (&properties, "{sv}", "supports-underscanning",
g_variant_new_boolean (output->supports_underscanning));
edid_file = manager_class->get_edid_file (manager, output);
if (edid_file)
@@ -673,20 +540,6 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
}
}
if (output->tile_info.group_id)
{
g_variant_builder_add (&properties, "{sv}", "tile",
g_variant_new ("(uuuuuuuu)",
output->tile_info.group_id,
output->tile_info.flags,
output->tile_info.max_h_tiles,
output->tile_info.max_v_tiles,
output->tile_info.loc_h_tile,
output->tile_info.loc_v_tile,
output->tile_info.tile_w,
output->tile_info.tile_h));
}
g_variant_builder_add (&output_builder, "(uxiausauaua{sv})",
i, /* ID */
(gint64)output->winsys_id,
@@ -884,7 +737,8 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
crtc_info->y = 0;
}
if (transform > META_MONITOR_TRANSFORM_FLIPPED_270 ||
if (transform < META_MONITOR_TRANSFORM_NORMAL ||
transform > META_MONITOR_TRANSFORM_FLIPPED_270 ||
((crtc->all_transforms & (1 << transform)) == 0))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
@@ -954,7 +808,7 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
while (g_variant_iter_loop (&output_iter, "(u@a{sv})", &output_index, &properties))
{
MetaOutputInfo *output_info;
gboolean primary, presentation, underscanning;
gboolean primary, presentation;
if (output_index >= manager->n_outputs)
{
@@ -973,9 +827,6 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
if (g_variant_lookup (properties, "presentation", "b", &presentation))
output_info->is_presentation = presentation;
if (g_variant_lookup (properties, "underscanning", "b", &underscanning))
output_info->is_underscanning = underscanning;
g_ptr_array_add (output_infos, output_info);
}
@@ -1343,58 +1194,37 @@ meta_monitor_manager_read_current_config (MetaMonitorManager *manager)
MetaOutput *old_outputs;
MetaCRTC *old_crtcs;
MetaMonitorMode *old_modes;
unsigned int n_old_outputs, n_old_crtcs, n_old_modes;
unsigned int n_old_outputs, n_old_modes;
/* Some implementations of read_current use the existing information
* we have available, so don't free the old configuration until after
* read_current finishes. */
old_outputs = manager->outputs;
n_old_outputs = manager->n_outputs;
old_crtcs = manager->crtcs;
n_old_crtcs = manager->n_crtcs;
old_modes = manager->modes;
n_old_modes = manager->n_modes;
old_crtcs = manager->crtcs;
manager->serial++;
META_MONITOR_MANAGER_GET_CLASS (manager)->read_current (manager);
meta_monitor_manager_free_output_array (old_outputs, n_old_outputs);
meta_monitor_manager_free_mode_array (old_modes, n_old_modes);
meta_monitor_manager_free_crtc_array (old_crtcs, n_old_crtcs);
g_free (old_crtcs);
}
void
meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager)
{
MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_GET_CLASS (manager);
MetaMonitorInfo *old_monitor_infos;
unsigned old_n_monitor_infos;
unsigned i, j;
old_monitor_infos = manager->monitor_infos;
old_n_monitor_infos = manager->n_monitor_infos;
if (manager->in_init)
return;
make_logical_config (manager);
if (manager_class->delete_monitor)
{
for (i = 0; i < old_n_monitor_infos; i++)
{
gboolean delete_mon = TRUE;
for (j = 0; j < manager->n_monitor_infos; j++)
{
if (manager->monitor_infos[j].monitor_winsys_xid == old_monitor_infos[i].monitor_winsys_xid)
{
delete_mon = FALSE;
break;
}
}
if (delete_mon)
manager_class->delete_monitor (manager, old_monitor_infos[i].monitor_winsys_xid);
}
}
g_signal_emit_by_name (manager, "monitors-changed");
g_free (old_monitor_infos);
@@ -1415,35 +1245,25 @@ meta_output_parse_edid (MetaOutput *meta_output,
if (parsed_edid)
{
meta_output->vendor = g_strndup (parsed_edid->manufacturer_code, 4);
if (!g_utf8_validate (meta_output->vendor, -1, NULL))
g_clear_pointer (&meta_output->vendor, g_free);
meta_output->product = g_strndup (parsed_edid->dsc_product_name, 14);
if (!g_utf8_validate (meta_output->product, -1, NULL) ||
meta_output->product[0] == '\0')
{
g_clear_pointer (&meta_output->product, g_free);
meta_output->product = g_strdup_printf ("0x%04x", (unsigned) parsed_edid->product_code);
}
meta_output->serial = g_strndup (parsed_edid->dsc_serial_number, 14);
if (!g_utf8_validate (meta_output->serial, -1, NULL) ||
meta_output->serial[0] == '\0')
{
g_clear_pointer (&meta_output->serial, g_free);
meta_output->serial = g_strdup_printf ("0x%08x", parsed_edid->serial_number);
}
if (parsed_edid->dsc_product_name[0])
meta_output->product = g_strndup (parsed_edid->dsc_product_name, 14);
else
meta_output->product = g_strdup_printf ("0x%04x", (unsigned) parsed_edid->product_code);
if (parsed_edid->dsc_serial_number[0])
meta_output->serial = g_strndup (parsed_edid->dsc_serial_number, 14);
else
meta_output->serial = g_strdup_printf ("0x%08x", parsed_edid->serial_number);
g_free (parsed_edid);
}
out:
if (!meta_output->vendor)
meta_output->vendor = g_strdup ("unknown");
if (!meta_output->product)
meta_output->product = g_strdup ("unknown");
if (!meta_output->serial)
meta_output->serial = g_strdup ("unknown");
{
meta_output->vendor = g_strdup ("unknown");
meta_output->product = g_strdup ("unknown");
meta_output->serial = g_strdup ("unknown");
}
}
void

View File

@@ -24,6 +24,7 @@
#include "meta-stage.h"
#include "meta-cursor-private.h"
#include <meta/meta-backend.h>
#include <meta/util.h>

View File

@@ -29,7 +29,6 @@
#include <meta/main.h>
#include <clutter/evdev/clutter-evdev.h>
#include <libupower-glib/upower.h>
#include "meta-barrier-native.h"
#include "meta-idle-monitor-native.h"
@@ -40,11 +39,10 @@
struct _MetaBackendNativePrivate
{
MetaLauncher *launcher;
MetaBarrierManagerNative *barrier_manager;
UpClient *up_client;
guint sleep_signal_id;
GCancellable *cancellable;
GDBusConnection *system_bus;
GSettings *keyboard_settings;
};
typedef struct _MetaBackendNativePrivate MetaBackendNativePrivate;
@@ -58,69 +56,9 @@ meta_backend_native_finalize (GObject *object)
meta_launcher_free (priv->launcher);
g_object_unref (priv->up_client);
if (priv->sleep_signal_id)
g_dbus_connection_signal_unsubscribe (priv->system_bus, priv->sleep_signal_id);
g_cancellable_cancel (priv->cancellable);
g_clear_object (&priv->cancellable);
g_clear_object (&priv->system_bus);
G_OBJECT_CLASS (meta_backend_native_parent_class)->finalize (object);
}
static void
prepare_for_sleep_cb (GDBusConnection *connection,
const gchar *sender_name,
const gchar *object_path,
const gchar *interface_name,
const gchar *signal_name,
GVariant *parameters,
gpointer user_data)
{
gboolean suspending;
g_variant_get (parameters, "(b)", &suspending);
if (suspending)
return;
meta_idle_monitor_native_reset_idletime (meta_idle_monitor_get_core ());
}
static void
system_bus_gotten_cb (GObject *object,
GAsyncResult *res,
gpointer user_data)
{
MetaBackendNativePrivate *priv;
GDBusConnection *bus;
bus = g_bus_get_finish (res, NULL);
if (!bus)
return;
priv = meta_backend_native_get_instance_private (META_BACKEND_NATIVE (user_data));
priv->system_bus = bus;
priv->sleep_signal_id = g_dbus_connection_signal_subscribe (priv->system_bus,
"org.freedesktop.login1",
"org.freedesktop.login1.Manager",
"PrepareForSleep",
"/org/freedesktop/login1",
NULL,
G_DBUS_SIGNAL_FLAGS_NONE,
prepare_for_sleep_cb,
NULL,
NULL);
}
static void
lid_is_closed_changed_cb (UpClient *client,
GParamSpec *pspec,
gpointer user_data)
{
if (up_client_get_lid_is_closed (client))
return;
meta_idle_monitor_native_reset_idletime (meta_idle_monitor_get_core ());
}
static void
constrain_to_barriers (ClutterInputDevice *device,
guint32 time,
@@ -328,18 +266,10 @@ meta_backend_native_init (MetaBackendNative *native)
{
MetaBackendNativePrivate *priv = meta_backend_native_get_instance_private (native);
/* We're a display server, so start talking to weston-launch. */
priv->launcher = meta_launcher_new ();
priv->barrier_manager = meta_barrier_manager_native_new ();
priv->up_client = up_client_new ();
g_signal_connect (priv->up_client, "notify::lid-is-closed",
G_CALLBACK (lid_is_closed_changed_cb), NULL);
priv->cancellable = g_cancellable_new ();
g_bus_get (G_BUS_TYPE_SYSTEM,
priv->cancellable,
system_bus_gotten_cb,
native);
}
gboolean

View File

@@ -26,16 +26,11 @@
#include "meta-cursor-renderer-native.h"
#include <string.h>
#include <gbm.h>
#include <xf86drm.h>
#include <errno.h>
#include <meta/util.h>
#include <meta/meta-backend.h>
#include "meta-cursor-private.h"
#include "meta-monitor-manager-private.h"
#include "meta/boxes.h"
#ifndef DRM_CAP_CURSOR_WIDTH
#define DRM_CAP_CURSOR_WIDTH 0x8
@@ -44,28 +39,10 @@
#define DRM_CAP_CURSOR_HEIGHT 0x9
#endif
/* When animating a cursor, we usually call drmModeSetCursor2 once per frame.
* Though, testing shows that we need to triple buffer the cursor buffer in
* order to avoid glitches when animating the cursor, at least when running on
* Intel. The reason for this might be (but is not confirmed to be) due to
* the user space gbm_bo cache, making us reuse and overwrite the kernel side
* buffer content before it was scanned out. To avoid this, we keep a user space
* reference to each buffer we set until at least one frame after it was drawn.
* In effect, this means we three active cursor gbm_bo's: one that that just has
* been set, one that was previously set and may or may not have been scanned
* out, and one pending that will be replaced if the cursor sprite changes.
*/
#define HW_CURSOR_BUFFER_COUNT 3
static GQuark quark_cursor_sprite = 0;
struct _MetaCursorRendererNativePrivate
{
gboolean has_hw_cursor;
MetaCursorSprite *last_cursor;
guint animation_timeout_id;
int drm_fd;
struct gbm_device *gbm;
@@ -74,170 +51,77 @@ struct _MetaCursorRendererNativePrivate
};
typedef struct _MetaCursorRendererNativePrivate MetaCursorRendererNativePrivate;
typedef enum _MetaCursorGbmBoState
{
META_CURSOR_GBM_BO_STATE_NONE,
META_CURSOR_GBM_BO_STATE_SET,
META_CURSOR_GBM_BO_STATE_INVALIDATED,
} MetaCursorGbmBoState;
typedef struct _MetaCursorNativePrivate
{
guint active_bo;
MetaCursorGbmBoState pending_bo_state;
struct gbm_bo *bos[HW_CURSOR_BUFFER_COUNT];
} MetaCursorNativePrivate;
G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererNative, meta_cursor_renderer_native, META_TYPE_CURSOR_RENDERER);
static MetaCursorNativePrivate *
ensure_cursor_priv (MetaCursorSprite *cursor_sprite);
static void
meta_cursor_renderer_native_finalize (GObject *object)
{
MetaCursorRendererNative *renderer = META_CURSOR_RENDERER_NATIVE (object);
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (renderer);
if (priv->animation_timeout_id)
g_source_remove (priv->animation_timeout_id);
if (priv->gbm)
gbm_device_destroy (priv->gbm);
G_OBJECT_CLASS (meta_cursor_renderer_native_parent_class)->finalize (object);
}
static guint
get_pending_cursor_sprite_gbm_bo_index (MetaCursorSprite *cursor_sprite)
{
MetaCursorNativePrivate *cursor_priv =
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
return (cursor_priv->active_bo + 1) % HW_CURSOR_BUFFER_COUNT;
}
static struct gbm_bo *
get_pending_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite)
{
MetaCursorNativePrivate *cursor_priv =
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
guint pending_bo;
if (!cursor_priv)
return NULL;
pending_bo = get_pending_cursor_sprite_gbm_bo_index (cursor_sprite);
return cursor_priv->bos[pending_bo];
}
static struct gbm_bo *
get_active_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite)
{
MetaCursorNativePrivate *cursor_priv =
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
if (!cursor_priv)
return NULL;
return cursor_priv->bos[cursor_priv->active_bo];
}
static void
set_pending_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite,
struct gbm_bo *bo)
{
MetaCursorNativePrivate *cursor_priv;
guint pending_bo;
cursor_priv = ensure_cursor_priv (cursor_sprite);
pending_bo = get_pending_cursor_sprite_gbm_bo_index (cursor_sprite);
cursor_priv->bos[pending_bo] = bo;
cursor_priv->pending_bo_state = META_CURSOR_GBM_BO_STATE_SET;
}
static void
set_crtc_cursor (MetaCursorRendererNative *native,
MetaCRTC *crtc,
MetaCursorSprite *cursor_sprite,
MetaCursorReference *cursor,
gboolean force)
{
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
if (cursor_sprite)
if (crtc->cursor == cursor && !force)
return;
crtc->cursor = cursor;
if (cursor)
{
MetaCursorNativePrivate *cursor_priv =
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
struct gbm_bo *bo;
union gbm_bo_handle handle;
int hot_x, hot_y;
if (cursor_priv->pending_bo_state == META_CURSOR_GBM_BO_STATE_SET)
bo = get_pending_cursor_sprite_gbm_bo (cursor_sprite);
else
bo = get_active_cursor_sprite_gbm_bo (cursor_sprite);
if (!force && bo == crtc->cursor_renderer_private)
return;
crtc->cursor_renderer_private = bo;
bo = meta_cursor_reference_get_gbm_bo (cursor, &hot_x, &hot_y);
handle = gbm_bo_get_handle (bo);
meta_cursor_sprite_get_hotspot (cursor_sprite, &hot_x, &hot_y);
drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, handle.u32,
priv->cursor_width, priv->cursor_height, hot_x, hot_y);
if (cursor_priv->pending_bo_state == META_CURSOR_GBM_BO_STATE_SET)
{
cursor_priv->active_bo =
(cursor_priv->active_bo + 1) % HW_CURSOR_BUFFER_COUNT;
cursor_priv->pending_bo_state = META_CURSOR_GBM_BO_STATE_NONE;
}
}
else
{
if (force || crtc->cursor_renderer_private != NULL)
{
drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, 0, 0, 0, 0, 0);
crtc->cursor_renderer_private = NULL;
}
drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, 0, 0, 0, 0, 0);
}
}
static void
update_hw_cursor (MetaCursorRendererNative *native,
MetaCursorSprite *cursor_sprite,
gboolean force)
{
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
const MetaRectangle *cursor_rect = meta_cursor_renderer_get_rect (renderer);
MetaCursorReference *cursor = meta_cursor_renderer_get_cursor (renderer);
MetaMonitorManager *monitors;
MetaCRTC *crtcs;
unsigned int i, n_crtcs;
MetaRectangle rect;
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++)
{
gboolean crtc_should_use_cursor;
MetaCursorSprite *crtc_cursor;
gboolean crtc_should_have_cursor;
MetaCursorReference *crtc_cursor;
MetaRectangle *crtc_rect;
crtc_rect = &crtcs[i].rect;
crtc_should_use_cursor = (priv->has_hw_cursor &&
meta_rectangle_overlap (&rect, crtc_rect));
if (crtc_should_use_cursor)
crtc_cursor = cursor_sprite;
crtc_should_have_cursor = (priv->has_hw_cursor && meta_rectangle_overlap (cursor_rect, crtc_rect));
if (crtc_should_have_cursor)
crtc_cursor = cursor;
else
crtc_cursor = NULL;
@@ -246,350 +130,34 @@ update_hw_cursor (MetaCursorRendererNative *native,
if (crtc_cursor)
{
drmModeMoveCursor (priv->drm_fd, crtcs[i].crtc_id,
rect.x - crtc_rect->x,
rect.y - crtc_rect->y);
cursor_rect->x - crtc_rect->x,
cursor_rect->y - crtc_rect->y);
}
}
}
static gboolean
has_valid_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite)
should_have_hw_cursor (MetaCursorRenderer *renderer)
{
MetaCursorNativePrivate *cursor_priv =
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
MetaCursorReference *cursor = meta_cursor_renderer_get_cursor (renderer);
switch (cursor_priv->pending_bo_state)
{
case META_CURSOR_GBM_BO_STATE_NONE:
return get_active_cursor_sprite_gbm_bo (cursor_sprite) != NULL;
case META_CURSOR_GBM_BO_STATE_SET:
return TRUE;
case META_CURSOR_GBM_BO_STATE_INVALIDATED:
return FALSE;
}
g_assert_not_reached ();
return FALSE;
if (cursor)
return (meta_cursor_reference_get_gbm_bo (cursor, NULL, NULL) != NULL);
else
return FALSE;
}
static gboolean
should_have_hw_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
{
CoglTexture *texture;
if (!cursor_sprite)
return FALSE;
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
if (!texture)
return FALSE;
if (meta_cursor_sprite_get_texture_scale (cursor_sprite) != 1)
return FALSE;
if (!has_valid_cursor_sprite_gbm_bo (cursor_sprite))
return FALSE;
return TRUE;
}
static gboolean
meta_cursor_renderer_native_update_animation (MetaCursorRendererNative *native)
{
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
MetaCursorSprite *cursor_sprite = meta_cursor_renderer_get_cursor (renderer);
priv->animation_timeout_id = 0;
meta_cursor_sprite_tick_frame (cursor_sprite);
meta_cursor_renderer_force_update (renderer);
return G_SOURCE_REMOVE;
}
static void
meta_cursor_renderer_native_trigger_frame (MetaCursorRendererNative *native,
MetaCursorSprite *cursor_sprite)
{
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
gboolean cursor_change;
guint delay;
cursor_change = cursor_sprite != priv->last_cursor;
priv->last_cursor = cursor_sprite;
if (!cursor_change && priv->animation_timeout_id)
return;
if (priv->animation_timeout_id)
{
g_source_remove (priv->animation_timeout_id);
priv->animation_timeout_id = 0;
}
if (cursor_sprite && meta_cursor_sprite_is_animated (cursor_sprite))
{
delay = meta_cursor_sprite_get_current_frame_time (cursor_sprite);
if (delay == 0)
return;
priv->animation_timeout_id =
g_timeout_add (delay,
(GSourceFunc) meta_cursor_renderer_native_update_animation,
native);
g_source_set_name_by_id (priv->animation_timeout_id,
"[mutter] meta_cursor_renderer_native_update_animation");
}
}
static gboolean
meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer)
{
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
if (cursor_sprite)
meta_cursor_sprite_realize_texture (cursor_sprite);
meta_cursor_renderer_native_trigger_frame (native, cursor_sprite);
priv->has_hw_cursor = should_have_hw_cursor (renderer, cursor_sprite);
update_hw_cursor (native, cursor_sprite, FALSE);
priv->has_hw_cursor = should_have_hw_cursor (renderer);
update_hw_cursor (native, FALSE);
return priv->has_hw_cursor;
}
static void
get_hardware_cursor_size (MetaCursorRendererNative *native,
uint64_t *width, uint64_t *height)
{
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
*width = priv->cursor_width;
*height = priv->cursor_height;
}
static void
cursor_priv_free (gpointer data)
{
MetaCursorNativePrivate *cursor_priv = data;
guint i;
if (!data)
return;
for (i = 0; i < HW_CURSOR_BUFFER_COUNT; i++)
g_clear_pointer (&cursor_priv->bos[0], (GDestroyNotify) gbm_bo_destroy);
g_slice_free (MetaCursorNativePrivate, cursor_priv);
}
static MetaCursorNativePrivate *
ensure_cursor_priv (MetaCursorSprite *cursor_sprite)
{
MetaCursorNativePrivate *cursor_priv =
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
if (!cursor_priv)
{
cursor_priv = g_slice_new0 (MetaCursorNativePrivate);
g_object_set_qdata_full (G_OBJECT (cursor_sprite),
quark_cursor_sprite,
cursor_priv,
cursor_priv_free);
}
return cursor_priv;
}
static void
load_cursor_sprite_gbm_buffer (MetaCursorRendererNative *native,
MetaCursorSprite *cursor_sprite,
uint8_t *pixels,
uint width,
uint height,
int rowstride,
uint32_t gbm_format)
{
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
uint64_t cursor_width, cursor_height;
get_hardware_cursor_size (native, &cursor_width, &cursor_height);
if (width > cursor_width || height > cursor_height)
{
meta_warning ("Invalid theme cursor size (must be at most %ux%u)\n",
(unsigned int)cursor_width, (unsigned int)cursor_height);
return;
}
if (gbm_device_is_format_supported (priv->gbm, gbm_format,
GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE))
{
struct gbm_bo *bo;
uint8_t buf[4 * cursor_width * cursor_height];
uint i;
bo = gbm_bo_create (priv->gbm, cursor_width, cursor_height,
gbm_format, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
if (!bo)
{
meta_warning ("Failed to allocate HW cursor buffer\n");
return;
}
memset (buf, 0, sizeof(buf));
for (i = 0; i < height; i++)
memcpy (buf + i * 4 * cursor_width, pixels + i * rowstride, width * 4);
if (gbm_bo_write (bo, buf, cursor_width * cursor_height * 4) != 0)
{
meta_warning ("Failed to write cursors buffer data: %s",
g_strerror (errno));
gbm_bo_destroy (bo);
return;
}
set_pending_cursor_sprite_gbm_bo (cursor_sprite, bo);
}
else
{
meta_warning ("HW cursor for format %d not supported\n", gbm_format);
}
}
static void
invalidate_pending_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite)
{
MetaCursorNativePrivate *cursor_priv =
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
guint pending_bo;
if (!cursor_priv)
return;
pending_bo = get_pending_cursor_sprite_gbm_bo_index (cursor_sprite);
g_clear_pointer (&cursor_priv->bos[pending_bo],
(GDestroyNotify) gbm_bo_destroy);
cursor_priv->pending_bo_state = META_CURSOR_GBM_BO_STATE_INVALIDATED;
}
#ifdef HAVE_WAYLAND
static void
meta_cursor_renderer_native_realize_cursor_from_wl_buffer (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
struct wl_resource *buffer)
{
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
uint32_t gbm_format;
uint64_t cursor_width, cursor_height;
CoglTexture *texture;
uint width, height;
/* Destroy any previous pending cursor buffer; we'll always either fail (which
* should unset, or succeed, which will set new buffer.
*/
invalidate_pending_cursor_sprite_gbm_bo (cursor_sprite);
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
width = cogl_texture_get_width (texture);
height = cogl_texture_get_height (texture);
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (buffer);
if (shm_buffer)
{
int rowstride = wl_shm_buffer_get_stride (shm_buffer);
uint8_t *buffer_data;
wl_shm_buffer_begin_access (shm_buffer);
switch (wl_shm_buffer_get_format (shm_buffer))
{
#if G_BYTE_ORDER == G_BIG_ENDIAN
case WL_SHM_FORMAT_ARGB8888:
gbm_format = GBM_FORMAT_ARGB8888;
break;
case WL_SHM_FORMAT_XRGB8888:
gbm_format = GBM_FORMAT_XRGB8888;
break;
#else
case WL_SHM_FORMAT_ARGB8888:
gbm_format = GBM_FORMAT_ARGB8888;
break;
case WL_SHM_FORMAT_XRGB8888:
gbm_format = GBM_FORMAT_XRGB8888;
break;
#endif
default:
g_warn_if_reached ();
gbm_format = GBM_FORMAT_ARGB8888;
}
buffer_data = wl_shm_buffer_get_data (shm_buffer);
load_cursor_sprite_gbm_buffer (native,
cursor_sprite,
buffer_data,
width, height, rowstride,
gbm_format);
wl_shm_buffer_end_access (shm_buffer);
}
else
{
struct gbm_bo *bo;
/* HW cursors have a predefined size (at least 64x64), which usually is
* bigger than cursor theme size, so themed cursors must be padded with
* transparent pixels to fill the overlay. This is trivial if we have CPU
* access to the data, but it's not possible if the buffer is in GPU
* memory (and possibly tiled too), so if we don't get the right size, we
* fallback to GL. */
get_hardware_cursor_size (native, &cursor_width, &cursor_height);
if (width != cursor_width || height != cursor_height)
{
meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n");
return;
}
bo = gbm_bo_import (priv->gbm,
GBM_BO_IMPORT_WL_BUFFER,
buffer,
GBM_BO_USE_CURSOR);
if (!bo)
{
meta_warning ("Importing HW cursor from wl_buffer failed\n");
return;
}
set_pending_cursor_sprite_gbm_bo (cursor_sprite, bo);
}
}
#endif
static void
meta_cursor_renderer_native_realize_cursor_from_xcursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
XcursorImage *xc_image)
{
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
invalidate_pending_cursor_sprite_gbm_bo (cursor_sprite);
load_cursor_sprite_gbm_buffer (native,
cursor_sprite,
(uint8_t *) xc_image->pixels,
xc_image->width,
xc_image->height,
xc_image->width * 4,
GBM_FORMAT_ARGB8888);
}
static void
meta_cursor_renderer_native_class_init (MetaCursorRendererNativeClass *klass)
{
@@ -598,22 +166,6 @@ meta_cursor_renderer_native_class_init (MetaCursorRendererNativeClass *klass)
object_class->finalize = meta_cursor_renderer_native_finalize;
renderer_class->update_cursor = meta_cursor_renderer_native_update_cursor;
#ifdef HAVE_WAYLAND
renderer_class->realize_cursor_from_wl_buffer =
meta_cursor_renderer_native_realize_cursor_from_wl_buffer;
#endif
renderer_class->realize_cursor_from_xcursor =
meta_cursor_renderer_native_realize_cursor_from_xcursor;
quark_cursor_sprite = g_quark_from_static_string ("-meta-cursor-native");
}
static void
force_update_hw_cursor (MetaCursorRendererNative *native)
{
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
update_hw_cursor (native, meta_cursor_renderer_get_cursor (renderer), TRUE);
}
static void
@@ -621,7 +173,7 @@ on_monitors_changed (MetaMonitorManager *monitors,
MetaCursorRendererNative *native)
{
/* Our tracking is all messed up, so force an update. */
force_update_hw_cursor (native);
update_hw_cursor (native, TRUE);
}
static void
@@ -666,8 +218,18 @@ meta_cursor_renderer_native_get_gbm_device (MetaCursorRendererNative *native)
return priv->gbm;
}
void
meta_cursor_renderer_native_get_cursor_size (MetaCursorRendererNative *native,
uint64_t *width, uint64_t *height)
{
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
*width = priv->cursor_width;
*height = priv->cursor_height;
}
void
meta_cursor_renderer_native_force_update (MetaCursorRendererNative *native)
{
force_update_hw_cursor (native);
update_hw_cursor (native, TRUE);
}

View File

@@ -37,14 +37,12 @@
#include <unistd.h>
#include <systemd/sd-login.h>
#include <gudev/gudev.h>
#include "dbus-utils.h"
#include "meta-dbus-login1.h"
#include "backends/meta-backend-private.h"
#include "meta-cursor-renderer-native.h"
#include "meta-idle-monitor-native.h"
struct _MetaLauncher
{
@@ -54,27 +52,12 @@ struct _MetaLauncher
gboolean session_active;
};
static void
report_error_and_die (const char *prefix,
GError *error)
{
/* if a function returns due to g_return_val_if_fail,
* then the error may not be set */
if (error)
g_error ("%s: %s", prefix, error->message);
else
g_error ("%s", prefix);
/* the error is not freed, but it is ok as g_error aborts the process */
}
static Login1Session *
get_session_proxy (GCancellable *cancellable)
{
char *proxy_path;
char *session_id;
Login1Session *session_proxy;
GError *error = NULL;
if (sd_pid_get_session (getpid (), &session_id) < 0)
return NULL;
@@ -85,10 +68,7 @@ get_session_proxy (GCancellable *cancellable)
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
"org.freedesktop.login1",
proxy_path,
cancellable, &error);
if (!session_proxy)
report_error_and_die ("Failed getting session proxy", error);
cancellable, NULL);
free (proxy_path);
return session_proxy;
@@ -97,27 +77,22 @@ get_session_proxy (GCancellable *cancellable)
static Login1Seat *
get_seat_proxy (GCancellable *cancellable)
{
GError *error = NULL;
Login1Seat *seat = login1_seat_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
"org.freedesktop.login1",
"/org/freedesktop/login1/seat/self",
cancellable, &error);
if (!seat)
report_error_and_die ("Could not get seat proxy", error);
return seat;
return login1_seat_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
"org.freedesktop.login1",
"/org/freedesktop/login1/seat/self",
cancellable, NULL);
}
static void
session_unpause (void)
{
ClutterBackend *clutter_backend;
ClutterBackend *backend;
CoglContext *cogl_context;
CoglDisplay *cogl_display;
clutter_backend = clutter_get_default_backend ();
cogl_context = clutter_backend_get_cogl_context (clutter_backend);
backend = clutter_get_default_backend ();
cogl_context = clutter_backend_get_cogl_context (backend);
cogl_display = cogl_context_get_display (cogl_context);
cogl_kms_display_queue_modes_reset (cogl_display);
@@ -135,7 +110,6 @@ session_unpause (void)
clutter_actor_queue_redraw (stage);
meta_cursor_renderer_native_force_update (META_CURSOR_RENDERER_NATIVE (renderer));
meta_idle_monitor_native_reset_idletime (meta_idle_monitor_get_core ());
}
}
@@ -154,8 +128,9 @@ take_device (Login1Session *session_proxy,
GCancellable *cancellable,
GError **error)
{
g_autoptr (GVariant) fd_variant = NULL;
g_autoptr (GUnixFDList) fd_list = NULL;
gboolean ret = FALSE;
GVariant *fd_variant = NULL;
GUnixFDList *fd_list = NULL;
int fd = -1;
if (!login1_session_call_take_device_sync (session_proxy,
@@ -167,14 +142,21 @@ take_device (Login1Session *session_proxy,
&fd_list,
cancellable,
error))
return FALSE;
goto out;
fd = g_unix_fd_list_get (fd_list, g_variant_get_handle (fd_variant), error);
if (fd == -1)
return FALSE;
goto out;
*out_fd = fd;
return TRUE;
ret = TRUE;
out:
if (fd_variant)
g_variant_unref (fd_variant);
if (fd_list)
g_object_unref (fd_list);
return ret;
}
static gboolean
@@ -182,16 +164,22 @@ get_device_info_from_path (const char *path,
int *out_major,
int *out_minor)
{
gboolean ret = FALSE;
int r;
struct stat st;
r = stat (path, &st);
if (r < 0 || !S_ISCHR (st.st_mode))
return FALSE;
if (r < 0)
goto out;
if (!S_ISCHR (st.st_mode))
goto out;
*out_major = major (st.st_rdev);
*out_minor = minor (st.st_rdev);
return TRUE;
ret = TRUE;
out:
return ret;
}
static gboolean
@@ -199,16 +187,22 @@ get_device_info_from_fd (int fd,
int *out_major,
int *out_minor)
{
gboolean ret = FALSE;
int r;
struct stat st;
r = fstat (fd, &st);
if (r < 0 || !S_ISCHR (st.st_mode))
return FALSE;
if (r < 0)
goto out;
if (!S_ISCHR (st.st_mode))
goto out;
*out_major = major (st.st_rdev);
*out_minor = minor (st.st_rdev);
return TRUE;
ret = TRUE;
out:
return ret;
}
static int
@@ -247,7 +241,7 @@ on_evdev_device_close (int fd,
if (!get_device_info_from_fd (fd, &major, &minor))
{
g_warning ("Could not get device info for fd %d: %m", fd);
goto out;
return;
}
if (!login1_session_call_release_device_sync (self->session_proxy,
@@ -256,9 +250,6 @@ on_evdev_device_close (int fd,
{
g_warning ("Could not release device %d,%d: %s", major, minor, error->message);
}
out:
close (fd);
}
static void
@@ -286,115 +277,31 @@ on_active_changed (Login1Session *session,
sync_active (self);
}
static gchar *
get_primary_gpu_path (const gchar *seat_name)
{
const gchar *subsystems[] = {"drm", NULL};
gchar *path = NULL;
GList *devices, *tmp;
GUdevClient *gudev_client = g_udev_client_new (subsystems);
GUdevEnumerator *enumerator = g_udev_enumerator_new (gudev_client);
g_udev_enumerator_add_match_name (enumerator, "card*");
g_udev_enumerator_add_match_tag (enumerator, "seat");
devices = g_udev_enumerator_execute (enumerator);
if (!devices)
goto out;
for (tmp = devices; tmp != NULL; tmp = tmp->next)
{
GUdevDevice *pci_device;
GUdevDevice *dev = tmp->data;
gint boot_vga;
const gchar *device_seat;
/* filter out devices that are not character device, like card0-VGA-1 */
if (g_udev_device_get_device_type (dev) != G_UDEV_DEVICE_TYPE_CHAR)
continue;
device_seat = g_udev_device_get_property (dev, "ID_SEAT");
if (!device_seat)
{
/* when ID_SEAT is not set, it means seat0 */
device_seat = "seat0";
}
else if (g_strcmp0 (device_seat, "seat0") != 0)
{
/* if the device has been explicitly assigned other seat
* than seat0, it is probably the right device to use */
path = g_strdup (g_udev_device_get_device_file (dev));
break;
}
/* skip devices that do not belong to our seat */
if (g_strcmp0 (seat_name, device_seat))
continue;
pci_device = g_udev_device_get_parent_with_subsystem (dev, "pci", NULL);
if (!pci_device)
continue;
/* get value of boot_vga attribute or 0 if the device has no boot_vga */
boot_vga = g_udev_device_get_sysfs_attr_as_int (pci_device, "boot_vga");
g_object_unref (pci_device);
if (boot_vga == 1)
{
/* found the boot_vga device */
path = g_strdup (g_udev_device_get_device_file (dev));
break;
}
}
g_list_free_full (devices, g_object_unref);
out:
g_object_unref (enumerator);
g_object_unref (gudev_client);
return path;
}
static void
static gboolean
get_kms_fd (Login1Session *session_proxy,
const gchar *seat_id,
int *fd_out)
{
int major, minor;
int fd;
gchar *path;
GError *error = NULL;
path = get_primary_gpu_path (seat_id);
if (!path)
g_error ("could not find drm kms device");
if (!get_device_info_from_path (path, &major, &minor))
g_error ("Could not stat %s: %m", path);
g_free (path);
/* XXX -- use udev to find the DRM master device */
if (!get_device_info_from_path ("/dev/dri/card0", &major, &minor))
{
g_warning ("Could not stat /dev/dri/card0: %m");
return FALSE;
}
if (!take_device (session_proxy, major, minor, &fd, NULL, &error))
report_error_and_die ("Could not open DRM device", error);
{
g_warning ("Could not open DRM device: %s\n", error->message);
g_error_free (error);
return FALSE;
}
*fd_out = fd;
}
static gchar *
get_seat_id (void)
{
char *session_id, *seat_id = NULL;
if (sd_pid_get_session (0, &session_id) < 0)
return NULL;
/* on error the seat_id will remain NULL */
sd_session_get_seat (session_id, &seat_id);
free (session_id);
return seat_id;
return TRUE;
}
MetaLauncher *
@@ -402,23 +309,22 @@ meta_launcher_new (void)
{
MetaLauncher *self = NULL;
Login1Session *session_proxy;
char *seat_id;
GError *error = NULL;
int kms_fd;
session_proxy = get_session_proxy (NULL);
if (!login1_session_call_take_control_sync (session_proxy, FALSE, NULL, &error))
report_error_and_die ("Could not take control", error);
{
g_warning ("Could not take control: %s", error->message);
g_error_free (error);
goto out;
}
seat_id = get_seat_id ();
if (!seat_id)
g_error ("Failed getting seat id");
get_kms_fd (session_proxy, seat_id, &kms_fd);
free (seat_id);
if (!get_kms_fd (session_proxy, &kms_fd))
goto out;
self = g_slice_new0 (MetaLauncher);
self->session_proxy = session_proxy;
self->session_proxy = g_object_ref (session_proxy);
self->seat_proxy = get_seat_proxy (NULL);
self->session_active = TRUE;
@@ -430,6 +336,9 @@ meta_launcher_new (void)
g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self);
out:
g_object_unref (session_proxy);
return self;
}

View File

@@ -55,19 +55,8 @@ typedef struct {
uint32_t dpms_prop_id;
uint32_t edid_blob_id;
uint32_t tile_blob_id;
int suggested_x;
int suggested_y;
uint32_t hotplug_mode_update;
} MetaOutputKms;
typedef struct {
uint32_t underscan_prop_id;
uint32_t underscan_hborder_prop_id;
uint32_t underscan_vborder_prop_id;
} MetaCRTCKms;
struct _MetaMonitorManagerKms
{
MetaMonitorManager parent_instance;
@@ -115,7 +104,7 @@ make_output_name (drmModeConnector *connector)
static const char * const connector_type_names[] = {
"unknown", "VGA", "DVII", "DVID", "DVID", "Composite",
"SVIDEO", "LVDS", "Component", "9PinDIN", "DisplayPort",
"HDMIA", "HDMIB", "TV", "eDP", "Virtual", "DSI"
"HDMIA", "HDMIB", "TV", "eDP"
};
const char *connector_type_name;
@@ -148,12 +137,6 @@ meta_monitor_mode_destroy_notify (MetaMonitorMode *output)
g_slice_free (drmModeModeInfo, output->driver_private);
}
static void
meta_crtc_destroy_notify (MetaCRTC *crtc)
{
g_free (crtc->driver_private);
}
static gboolean
drm_mode_equal (gconstpointer one,
gconstpointer two)
@@ -198,67 +181,24 @@ drm_mode_hash (gconstpointer ptr)
}
static void
find_connector_properties (MetaMonitorManagerKms *manager_kms,
MetaOutputKms *output_kms)
find_properties (MetaMonitorManagerKms *manager_kms,
MetaOutputKms *output_kms)
{
drmModePropertyPtr prop;
int i;
output_kms->hotplug_mode_update = 0;
output_kms->suggested_x = -1;
output_kms->suggested_y = -1;
for (i = 0; i < output_kms->connector->count_props; i++)
{
drmModePropertyPtr prop = drmModeGetProperty (manager_kms->fd, output_kms->connector->props[i]);
prop = drmModeGetProperty (manager_kms->fd, output_kms->connector->props[i]);
if (!prop)
continue;
if ((prop->flags & DRM_MODE_PROP_ENUM) && strcmp (prop->name, "DPMS") == 0)
if ((prop->flags & DRM_MODE_PROP_ENUM) &&
strcmp(prop->name, "DPMS") == 0)
output_kms->dpms_prop_id = prop->prop_id;
else if ((prop->flags & DRM_MODE_PROP_BLOB) && strcmp (prop->name, "EDID") == 0)
output_kms->edid_blob_id = output_kms->connector->prop_values[i];
else if ((prop->flags & DRM_MODE_PROP_BLOB) &&
strcmp (prop->name, "TILE") == 0)
output_kms->tile_blob_id = output_kms->connector->prop_values[i];
else if ((prop->flags & DRM_MODE_PROP_RANGE) &&
strcmp (prop->name, "suggested X") == 0)
output_kms->suggested_x = output_kms->connector->prop_values[i];
else if ((prop->flags & DRM_MODE_PROP_RANGE) &&
strcmp (prop->name, "suggested Y") == 0)
output_kms->suggested_y = output_kms->connector->prop_values[i];
else if ((prop->flags & DRM_MODE_PROP_RANGE) &&
strcmp (prop->name, "hotplug_mode_update") == 0)
output_kms->hotplug_mode_update = output_kms->connector->prop_values[i];
drmModeFreeProperty (prop);
}
}
static void
find_crtc_properties (MetaMonitorManagerKms *manager_kms,
MetaCRTC *meta_crtc)
{
MetaCRTCKms *crtc_kms;
drmModeObjectPropertiesPtr props;
size_t i;
crtc_kms = meta_crtc->driver_private;
props = drmModeObjectGetProperties (manager_kms->fd, meta_crtc->crtc_id, DRM_MODE_OBJECT_CRTC);
if (!props)
return;
for (i = 0; i < props->count_props; i++)
{
drmModePropertyPtr prop = drmModeGetProperty (manager_kms->fd, props->props[i]);
if (!prop)
continue;
if ((prop->flags & DRM_MODE_PROP_ENUM) && strcmp (prop->name, "underscan") == 0)
crtc_kms->underscan_prop_id = prop->prop_id;
else if ((prop->flags & DRM_MODE_PROP_RANGE) && strcmp (prop->name, "underscan hborder") == 0)
crtc_kms->underscan_hborder_prop_id = prop->prop_id;
else if ((prop->flags & DRM_MODE_PROP_RANGE) && strcmp (prop->name, "underscan vborder") == 0)
crtc_kms->underscan_vborder_prop_id = prop->prop_id;
strcmp (prop->name, "EDID") == 0)
output_kms->edid_blob_id = output_kms->connector->prop_values[i];
drmModeFreeProperty (prop);
}
@@ -293,47 +233,6 @@ read_output_edid (MetaMonitorManagerKms *manager_kms,
}
}
static gboolean
output_get_tile_info (MetaMonitorManagerKms *manager_kms,
MetaOutput *output)
{
MetaOutputKms *output_kms = output->driver_private;
drmModePropertyBlobPtr tile_blob = NULL;
int ret;
if (output_kms->tile_blob_id == 0)
return FALSE;
tile_blob = drmModeGetPropertyBlob (manager_kms->fd, output_kms->tile_blob_id);
if (!tile_blob)
{
meta_warning ("Failed to read TILE of output %s: %s\n", output->name, strerror(errno));
return FALSE;
}
if (tile_blob->length > 0)
{
ret = sscanf ((char *)tile_blob->data, "%d:%d:%d:%d:%d:%d:%d:%d",
&output->tile_info.group_id,
&output->tile_info.flags,
&output->tile_info.max_h_tiles,
&output->tile_info.max_v_tiles,
&output->tile_info.loc_h_tile,
&output->tile_info.loc_v_tile,
&output->tile_info.tile_w,
&output->tile_info.tile_h);
if (ret != 8)
return FALSE;
return TRUE;
}
else
{
drmModeFreePropertyBlob (tile_blob);
return FALSE;
}
}
static MetaMonitorMode *
find_meta_mode (MetaMonitorManager *manager,
const drmModeModeInfo *drm_mode)
@@ -543,10 +442,6 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
height = MAX (height, meta_crtc->rect.y + meta_crtc->rect.height);
}
meta_crtc->driver_private = g_new0 (MetaCRTCKms, 1);
meta_crtc->driver_notify = (GDestroyNotify) meta_crtc_destroy_notify;
find_crtc_properties (manager_kms, meta_crtc);
drmModeFreeCrtc (crtc);
}
@@ -577,6 +472,8 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
meta_output->name = make_output_name (connector);
meta_output->width_mm = connector->mmWidth;
meta_output->height_mm = connector->mmHeight;
meta_output->suggested_x = -1;
meta_output->suggested_y = -1;
switch (connector->subpixel)
{
@@ -601,17 +498,11 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
break;
}
meta_output->preferred_mode = NULL;
meta_output->n_modes = connector->count_modes;
meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
for (j = 0; j < meta_output->n_modes; j++) {
for (j = 0; j < meta_output->n_modes; j++)
meta_output->modes[j] = find_meta_mode (manager, &connector->modes[j]);
if (connector->modes[j].type & DRM_MODE_TYPE_PREFERRED)
meta_output->preferred_mode = meta_output->modes[j];
}
if (!meta_output->preferred_mode)
meta_output->preferred_mode = meta_output->modes[0];
meta_output->preferred_mode = meta_output->modes[0];
output_kms->connector = connector;
output_kms->n_encoders = connector->count_encoders;
@@ -676,11 +567,8 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
meta_output->is_presentation = FALSE;
}
find_connector_properties (manager_kms, output_kms);
meta_output->suggested_x = output_kms->suggested_x;
meta_output->suggested_y = output_kms->suggested_y;
meta_output->hotplug_mode_update = output_kms->hotplug_mode_update;
find_properties (manager_kms, output_kms);
edid = read_output_edid (manager_kms, meta_output);
meta_output_parse_edid (meta_output, edid);
g_bytes_unref (edid);
@@ -690,8 +578,6 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
meta_output->scale = get_output_scale (manager, meta_output);
output_get_tile_info (manager_kms, meta_output);
/* FIXME: backlight is a very driver specific thing unfortunately,
every DDX does its own thing, and the dumb KMS API does not include it.
@@ -837,9 +723,8 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
if (output_kms->dpms_prop_id != 0)
{
int ok = drmModeObjectSetProperty (manager_kms->fd, meta_output->winsys_id,
DRM_MODE_OBJECT_CONNECTOR,
output_kms->dpms_prop_id, state);
int ok = drmModeConnectorSetProperty(manager_kms->fd, meta_output->winsys_id,
output_kms->dpms_prop_id, state);
if (ok < 0)
meta_warning ("Failed to set power save mode for output %s: %s\n",
@@ -863,48 +748,6 @@ crtc_free (CoglKmsCrtc *crtc)
g_slice_free (CoglKmsCrtc, crtc);
}
static void
set_underscan (MetaMonitorManagerKms *manager_kms,
MetaOutput *output)
{
if (!output->crtc)
return;
MetaCRTC *crtc = output->crtc;
MetaCRTCKms *crtc_kms = crtc->driver_private;
if (!crtc_kms->underscan_prop_id)
return;
if (output->is_underscanning)
{
drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id,
DRM_MODE_OBJECT_CRTC,
crtc_kms->underscan_prop_id, (uint64_t) 1);
if (crtc_kms->underscan_hborder_prop_id)
{
uint64_t value = crtc->current_mode->width * 0.05;
drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id,
DRM_MODE_OBJECT_CRTC,
crtc_kms->underscan_hborder_prop_id, value);
}
if (crtc_kms->underscan_vborder_prop_id)
{
uint64_t value = crtc->current_mode->height * 0.05;
drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id,
DRM_MODE_OBJECT_CRTC,
crtc_kms->underscan_vborder_prop_id, value);
}
}
else
{
drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id,
DRM_MODE_OBJECT_CRTC,
crtc_kms->underscan_prop_id, (uint64_t) 0);
}
}
static void
meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
MetaCRTCInfo **crtcs,
@@ -912,7 +755,6 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
MetaOutputInfo **outputs,
unsigned int n_outputs)
{
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
ClutterBackend *backend;
CoglContext *cogl_context;
CoglDisplay *cogl_display;
@@ -1058,9 +900,6 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
output->is_primary = output_info->is_primary;
output->is_presentation = output_info->is_presentation;
output->is_underscanning = output_info->is_underscanning;
set_underscan (manager_kms, output);
}
/* Disable outputs not mentioned in the list */

View File

@@ -40,24 +40,12 @@
#include "meta-idle-monitor-xsync.h"
#include "meta-monitor-manager-xrandr.h"
#include "backends/meta-monitor-manager-dummy.h"
#include "backends/x11/nested/meta-cursor-renderer-x11-nested.h"
#include "meta-cursor-renderer-x11.h"
#ifdef HAVE_WAYLAND
#include "wayland/meta-wayland.h"
#endif
#include <meta/util.h>
#include "display-private.h"
#include "compositor/compositor-private.h"
typedef enum {
/* We're a traditional CM running under the host. */
META_BACKEND_X11_MODE_COMPOSITOR,
/* We're a nested X11 client */
META_BACKEND_X11_MODE_NESTED,
} MetaBackendX11Mode;
struct _MetaBackendX11Private
{
/* The host X11 display */
@@ -65,8 +53,6 @@ struct _MetaBackendX11Private
xcb_connection_t *xcb;
GSource *source;
MetaBackendX11Mode mode;
int xsync_event_base;
int xsync_error_base;
@@ -116,7 +102,7 @@ translate_device_event (MetaBackendX11 *x11,
/* This codepath should only ever trigger as an X11 compositor,
* and never under nested, as under nested all backend events
* should be reported with respect to the stage window. */
g_assert (priv->mode == META_BACKEND_X11_MODE_COMPOSITOR);
g_assert (!meta_is_wayland_compositor ());
device_event->event = stage_window;
@@ -147,8 +133,6 @@ static void
translate_crossing_event (MetaBackendX11 *x11,
XIEnterEvent *enter_event)
{
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
/* Throw out weird events generated by grabs. */
if (enter_event->mode == XINotifyGrab ||
enter_event->mode == XINotifyUngrab)
@@ -157,14 +141,7 @@ translate_crossing_event (MetaBackendX11 *x11,
return;
}
Window stage_window = meta_backend_x11_get_xwindow (x11);
if (enter_event->event != stage_window &&
priv->mode == META_BACKEND_X11_MODE_COMPOSITOR)
{
enter_event->event = meta_backend_x11_get_xwindow (x11);
enter_event->event_x = enter_event->root_x;
enter_event->event_y = enter_event->root_y;
}
enter_event->event = meta_backend_x11_get_xwindow (x11);
}
static void
@@ -273,25 +250,6 @@ handle_host_xevent (MetaBackend *backend,
}
}
if (priv->mode == META_BACKEND_X11_MODE_NESTED && event->type == FocusIn)
{
#ifdef HAVE_WAYLAND
Window xwin = meta_backend_x11_get_xwindow(x11);
XEvent xev;
if (event->xfocus.window == xwin)
{
/* Since we've selected for KeymapStateMask, every FocusIn is followed immediately
* by a KeymapNotify event */
XMaskEvent(priv->xdisplay, KeymapStateMask, &xev);
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
meta_wayland_compositor_update_key_state (compositor, xev.xkeymap.key_vector, 32, 8);
}
#else
g_assert_not_reached ();
#endif
}
if (event->type == (priv->xsync_event_base + XSyncAlarmNotify))
handle_alarm_notify (backend, event);
@@ -441,7 +399,6 @@ meta_backend_x11_post_init (MetaBackend *backend)
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
int major, minor;
gboolean has_xi = FALSE;
priv->xdisplay = clutter_x11_get_default_display ();
@@ -451,27 +408,29 @@ meta_backend_x11_post_init (MetaBackend *backend)
!XSyncInitialize (priv->xdisplay, &major, &minor))
meta_fatal ("Could not initialize XSync");
if (XQueryExtension (priv->xdisplay,
"XInputExtension",
&priv->xinput_opcode,
&priv->xinput_error_base,
&priv->xinput_event_base))
{
major = 2; minor = 3;
if (XIQueryVersion (priv->xdisplay, &major, &minor) == Success)
{
int version = (major * 10) + minor;
if (version >= 22)
has_xi = TRUE;
}
}
{
int major = 2, minor = 3;
gboolean has_xi = FALSE;
if (!has_xi)
meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n");
if (XQueryExtension (priv->xdisplay,
"XInputExtension",
&priv->xinput_opcode,
&priv->xinput_error_base,
&priv->xinput_event_base))
{
if (XIQueryVersion (priv->xdisplay, &major, &minor) == Success)
{
int version = (major * 10) + minor;
if (version >= 22)
has_xi = TRUE;
}
}
/* We only take the passive touch grab if we are a X11 compositor */
if (priv->mode == META_BACKEND_X11_MODE_COMPOSITOR)
take_touch_grab (backend);
if (!has_xi)
meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n");
}
take_touch_grab (backend);
priv->xcb = XGetXCBConnection (priv->xdisplay);
if (!xkb_x11_setup_xkb_extension (priv->xcb,
@@ -502,37 +461,19 @@ meta_backend_x11_create_idle_monitor (MetaBackend *backend,
static MetaMonitorManager *
meta_backend_x11_create_monitor_manager (MetaBackend *backend)
{
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
/* If we're a Wayland compositor using the X11 backend,
* we're a nested configuration, so return the dummy
* monitor setup. */
if (meta_is_wayland_compositor ())
return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL);
switch (priv->mode)
{
case META_BACKEND_X11_MODE_COMPOSITOR:
return g_object_new (META_TYPE_MONITOR_MANAGER_XRANDR, NULL);
case META_BACKEND_X11_MODE_NESTED:
return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL);
default:
g_assert_not_reached ();
}
return g_object_new (META_TYPE_MONITOR_MANAGER_XRANDR, NULL);
}
static MetaCursorRenderer *
meta_backend_x11_create_cursor_renderer (MetaBackend *backend)
{
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
switch (priv->mode)
{
case META_BACKEND_X11_MODE_COMPOSITOR:
return g_object_new (META_TYPE_CURSOR_RENDERER_X11, NULL);
break;
case META_BACKEND_X11_MODE_NESTED:
return g_object_new (META_TYPE_CURSOR_RENDERER_X11_NESTED, NULL);
break;
default:
g_assert_not_reached ();
}
return g_object_new (META_TYPE_CURSOR_RENDERER_X11, NULL);
}
static gboolean
@@ -760,9 +701,6 @@ meta_backend_x11_get_keymap (MetaBackend *backend)
priv->xcb,
xkb_x11_get_core_keyboard_device_id (priv->xcb),
XKB_KEYMAP_COMPILE_NO_FLAGS);
if (priv->keymap == NULL)
priv->keymap = xkb_keymap_new_from_names (context, NULL, XKB_KEYMAP_COMPILE_NO_FLAGS);
xkb_context_unref (context);
}
@@ -783,10 +721,7 @@ static void
meta_backend_x11_update_screen_size (MetaBackend *backend,
int width, int height)
{
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
if (priv->mode == META_BACKEND_X11_MODE_NESTED)
if (meta_is_wayland_compositor ())
{
/* For a nested wayland session, we want to go through Clutter to update the
* toplevel window size, rather than doing it directly.
@@ -795,6 +730,8 @@ meta_backend_x11_update_screen_size (MetaBackend *backend,
}
else
{
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
Window xwin = meta_backend_x11_get_xwindow (x11);
XResizeWindow (priv->xdisplay, xwin, width, height);
}
@@ -818,36 +755,10 @@ meta_backend_x11_select_stage_events (MetaBackend *backend)
XISetMask (mask.mask, XI_FocusIn);
XISetMask (mask.mask, XI_FocusOut);
XISetMask (mask.mask, XI_Motion);
if (priv->mode == META_BACKEND_X11_MODE_NESTED)
{
/* When we're an X11 compositor, we can't take these events or else
* replaying events from our passive root window grab will cause
* them to come back to us.
*
* When we're a nested application, we want to behave like any other
* application, so select these events like normal apps do.
*/
XISetMask (mask.mask, XI_TouchBegin);
XISetMask (mask.mask, XI_TouchEnd);
XISetMask (mask.mask, XI_TouchUpdate);
}
XIClearMask (mask.mask, XI_TouchBegin);
XIClearMask (mask.mask, XI_TouchEnd);
XIClearMask (mask.mask, XI_TouchUpdate);
XISelectEvents (priv->xdisplay, xwin, &mask, 1);
if (priv->mode == META_BACKEND_X11_MODE_NESTED)
{
/* We have no way of tracking key changes when the stage doesn't have
* focus, so we select for KeymapStateMask so that we get a complete
* dump of the keyboard state in a KeymapNotify event that immediately
* follows each FocusIn (and EnterNotify, but we ignore that.)
*/
XWindowAttributes xwa;
XGetWindowAttributes(priv->xdisplay, xwin, &xwa);
XSelectInput(priv->xdisplay, xwin,
xwa.your_event_mask | FocusChangeMask | KeymapStateMask);
}
}
static void
@@ -872,15 +783,8 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
static void
meta_backend_x11_init (MetaBackendX11 *x11)
{
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
/* We do X11 event retrieval ourselves */
clutter_x11_disable_event_retrieval ();
if (meta_is_wayland_compositor ())
priv->mode = META_BACKEND_X11_MODE_NESTED;
else
priv->mode = META_BACKEND_X11_MODE_COMPOSITOR;
}
Display *

View File

@@ -40,29 +40,25 @@ typedef struct _MetaCursorRendererX11Private MetaCursorRendererX11Private;
G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererX11, meta_cursor_renderer_x11, META_TYPE_CURSOR_RENDERER);
static gboolean
meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer)
{
MetaCursorRendererX11 *x11 = META_CURSOR_RENDERER_X11 (renderer);
MetaCursorRendererX11Private *priv = meta_cursor_renderer_x11_get_instance_private (x11);
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
Window xwindow = meta_backend_x11_get_xwindow (backend);
Display *xdisplay = meta_backend_x11_get_xdisplay (backend);
if (xwindow == None)
{
if (cursor_sprite)
meta_cursor_sprite_realize_texture (cursor_sprite);
return FALSE;
}
return FALSE;
Display *xdisplay = meta_backend_x11_get_xdisplay (backend);
MetaCursorReference *cursor_ref = meta_cursor_renderer_get_cursor (renderer);
gboolean has_server_cursor = FALSE;
if (cursor_sprite)
if (cursor_ref)
{
MetaCursor cursor = meta_cursor_sprite_get_meta_cursor (cursor_sprite);
MetaCursor cursor = meta_cursor_reference_get_meta_cursor (cursor_ref);
if (cursor != META_CURSOR_NONE)
{
Cursor xcursor = meta_cursor_create_x_cursor (xdisplay, cursor);
@@ -84,9 +80,6 @@ meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer,
priv->server_cursor_visible = has_server_cursor;
}
if (!priv->server_cursor_visible && cursor_sprite)
meta_cursor_sprite_realize_texture (cursor_sprite);
return priv->server_cursor_visible;
}

View File

@@ -26,7 +26,6 @@
#include "meta-backend-x11.h"
#include "meta-input-settings-x11.h"
#include <string.h>
#include <gdk/gdkx.h>
#include <X11/Xatom.h>
#include <X11/extensions/XInput2.h>
@@ -36,41 +35,6 @@
G_DEFINE_TYPE (MetaInputSettingsX11, meta_input_settings_x11, META_TYPE_INPUT_SETTINGS)
static void *
get_property (ClutterInputDevice *device,
const gchar *property,
Atom type,
int format,
gulong nitems)
{
MetaBackend *backend = meta_get_backend ();
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
gulong nitems_ret, bytes_after_ret;
int rc, device_id, format_ret;
Atom property_atom, type_ret;
guchar *data_ret = NULL;
property_atom = XInternAtom (xdisplay, property, True);
if (!property_atom)
return NULL;
device_id = clutter_input_device_get_device_id (device);
rc = XIGetProperty (xdisplay, device_id, property_atom,
0, 10, False, type, &type_ret, &format_ret,
&nitems_ret, &bytes_after_ret, &data_ret);
if (rc == Success && type_ret == type && format_ret == format && nitems_ret >= nitems)
{
if (nitems_ret > nitems)
g_warning ("Property '%s' for device '%s' returned %lu items, expected %lu",
property, clutter_input_device_get_device_name (device), nitems_ret, nitems);
return data_ret;
}
meta_XFree (data_ret);
return NULL;
}
static void
change_property (ClutterInputDevice *device,
const gchar *property,
@@ -81,23 +45,23 @@ change_property (ClutterInputDevice *device,
{
MetaBackend *backend = meta_get_backend ();
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
int device_id;
Atom property_atom;
gulong nitems_ret, bytes_after_ret;
int rc, device_id, format_ret;
Atom property_atom, type_ret;
guchar *data_ret;
property_atom = XInternAtom (xdisplay, property, True);
if (!property_atom)
return;
property_atom = XInternAtom (xdisplay, property, False);
device_id = clutter_input_device_get_device_id (device);
data_ret = get_property (device, property, type, format, nitems);
if (!data_ret)
return;
rc = XIGetProperty (xdisplay, device_id, property_atom,
0, 0, False, type, &type_ret, &format_ret,
&nitems_ret, &bytes_after_ret, &data_ret);
XIChangeProperty (xdisplay, device_id, property_atom, type,
format, XIPropModeReplace, data, nitems);
meta_XFree (data_ret);
if (rc == Success && type_ret == type && format_ret == format)
XIChangeProperty (xdisplay, device_id, property_atom, type,
format, XIPropModeReplace, data, nitems);
}
static void
@@ -106,12 +70,6 @@ meta_input_settings_x11_set_send_events (MetaInputSettings *settings,
GDesktopDeviceSendEvents mode)
{
guchar values[2] = { 0 }; /* disabled, disabled-on-external-mouse */
guchar *available;
available = get_property (device, "libinput Send Events Modes Available",
XA_INTEGER, 8, 2);
if (!available)
return;
switch (mode)
{
@@ -125,14 +83,8 @@ meta_input_settings_x11_set_send_events (MetaInputSettings *settings,
break;
}
if ((values[0] && !available[0]) || (values[1] && !available[1]))
g_warning ("Device '%s' does not support sendevents mode %d\n",
clutter_input_device_get_device_name (device), mode);
else
change_property (device, "libinput Send Events Mode Enabled",
XA_INTEGER, 8, &values, 2);
meta_XFree (available);
change_property (device, "libinput Send Events Mode Enabled",
XA_INTEGER, 8, &values, 2);
}
static void
@@ -204,12 +156,6 @@ meta_input_settings_x11_set_scroll_method (MetaInputSettings *setting
GDesktopTouchpadScrollMethod mode)
{
guchar values[3] = { 0 }; /* 2fg, edge, button. The last value is unused */
guchar *available;
available = get_property (device, "libinput Scroll Methods Available",
XA_INTEGER, 8, 3);
if (!available)
return;
switch (mode)
{
@@ -225,14 +171,8 @@ meta_input_settings_x11_set_scroll_method (MetaInputSettings *setting
g_assert_not_reached ();
}
if ((values[0] && !available[0]) || (values[1] && !available[1]))
g_warning ("Device '%s' does not support scroll mode %d\n",
clutter_input_device_get_device_name (device), mode);
else
change_property (device, "libinput Scroll Method Enabled",
XA_INTEGER, 8, &values, 3);
meta_XFree (available);
change_property (device, "libinput Scroll Method Enabled",
XA_INTEGER, 8, &values, 3);
}
static void
@@ -240,7 +180,7 @@ meta_input_settings_x11_set_scroll_button (MetaInputSettings *settings,
ClutterInputDevice *device,
guint button)
{
change_property (device, "libinput Button Scrolling Button",
change_property (device, "libinput Scroll Method Enabled",
XA_INTEGER, 32, &button, 1);
}
@@ -250,28 +190,16 @@ meta_input_settings_x11_set_click_method (MetaInputSettings *settings,
GDesktopTouchpadClickMethod mode)
{
guchar values[2] = { 0 }; /* buttonareas, clickfinger */
guchar *defaults, *available;
available = get_property (device, "libinput Click Methods Available",
XA_INTEGER, 8, 2);
if (!available)
return;
switch (mode)
{
case G_DESKTOP_TOUCHPAD_CLICK_METHOD_DEFAULT:
defaults = get_property (device, "libinput Click Method Enabled Default",
XA_INTEGER, 8, 2);
if (!defaults)
break;
memcpy (values, defaults, 2);
meta_XFree (defaults);
break;
case G_DESKTOP_TOUCHPAD_CLICK_METHOD_NONE:
break;
case G_DESKTOP_TOUCHPAD_CLICK_METHOD_AREAS:
values[0] = 1;
break;
case G_DESKTOP_TOUCHPAD_CLICK_METHOD_DEFAULT:
/* XXX: We can't be much smarter yet, x11 doesn't expose default settings */
case G_DESKTOP_TOUCHPAD_CLICK_METHOD_FINGERS:
values[1] = 1;
break;
@@ -280,14 +208,8 @@ meta_input_settings_x11_set_click_method (MetaInputSettings *settings,
return;
}
if ((values[0] && !available[0]) || (values[1] && !available[1]))
g_warning ("Device '%s' does not support click method %d\n",
clutter_input_device_get_device_name (device), mode);
else
change_property (device, "libinput Click Method Enabled",
XA_INTEGER, 8, &values, 2);
meta_XFree(available);
change_property (device, "libinput Click Method Enabled",
XA_INTEGER, 8, &values, 2);
}
static void

View File

@@ -58,7 +58,6 @@ struct _MetaMonitorManagerXrandr
XRRScreenResources *resources;
int rr_event_base;
int rr_error_base;
gboolean has_randr15;
};
struct _MetaMonitorManagerXrandrClass
@@ -195,10 +194,11 @@ static gboolean
output_get_boolean_property (MetaMonitorManagerXrandr *manager_xrandr,
MetaOutput *output, const char *propname)
{
gboolean value = FALSE;
Atom atom, actual_type;
int actual_format;
unsigned long nitems, bytes_after;
g_autofree unsigned char *buffer = NULL;
unsigned char *buffer;
atom = XInternAtom (manager_xrandr->xdisplay, propname, False);
XRRGetOutputProperty (manager_xrandr->xdisplay,
@@ -209,9 +209,13 @@ output_get_boolean_property (MetaMonitorManagerXrandr *manager_xrandr,
&nitems, &bytes_after, &buffer);
if (actual_type != XA_CARDINAL || actual_format != 32 || nitems < 1)
return FALSE;
goto out;
return ((int*)buffer)[0];
value = ((int*)buffer)[0];
out:
XFree (buffer);
return value;
}
static gboolean
@@ -221,76 +225,6 @@ output_get_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
return output_get_boolean_property (manager_xrandr, output, "_MUTTER_PRESENTATION_OUTPUT");
}
static gboolean
output_get_underscanning_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
MetaOutput *output)
{
Atom atom, actual_type;
int actual_format;
unsigned long nitems, bytes_after;
g_autofree unsigned char *buffer = NULL;
g_autofree char *str = NULL;
atom = XInternAtom (manager_xrandr->xdisplay, "underscan", False);
XRRGetOutputProperty (manager_xrandr->xdisplay,
(XID)output->winsys_id,
atom,
0, G_MAXLONG, False, False, XA_ATOM,
&actual_type, &actual_format,
&nitems, &bytes_after, &buffer);
if (actual_type != XA_ATOM || actual_format != 32 || nitems < 1)
return FALSE;
str = XGetAtomName (manager_xrandr->xdisplay, *(Atom *)buffer);
return (strcmp (str, "on") == 0);
}
static gboolean
output_get_supports_underscanning_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
MetaOutput *output)
{
Atom atom, actual_type;
int actual_format, i;
unsigned long nitems, bytes_after;
g_autofree unsigned char *buffer = NULL;
XRRPropertyInfo *property_info;
Atom *values;
gboolean supports_underscanning = FALSE;
atom = XInternAtom (manager_xrandr->xdisplay, "underscan", False);
XRRGetOutputProperty (manager_xrandr->xdisplay,
(XID)output->winsys_id,
atom,
0, G_MAXLONG, False, False, XA_ATOM,
&actual_type, &actual_format,
&nitems, &bytes_after, &buffer);
if (actual_type != XA_ATOM || actual_format != 32 || nitems < 1)
return FALSE;
property_info = XRRQueryOutputProperty (manager_xrandr->xdisplay,
(XID) output->winsys_id,
atom);
values = (Atom *) property_info->values;
for (i = 0; i < property_info->num_values; i++)
{
/* The output supports underscanning if "on" is a valid value
* for the underscan property.
*/
char *name = XGetAtomName (manager_xrandr->xdisplay, values[i]);
if (strcmp (name, "on") == 0)
supports_underscanning = TRUE;
XFree (name);
}
XFree (property_info);
return supports_underscanning;
}
static int
normalize_backlight (MetaOutput *output,
int hw_value)
@@ -307,7 +241,7 @@ output_get_backlight_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
Atom atom, actual_type;
int actual_format;
unsigned long nitems, bytes_after;
g_autofree unsigned char *buffer = NULL;
unsigned char *buffer;
atom = XInternAtom (manager_xrandr->xdisplay, "Backlight", False);
XRRGetOutputProperty (manager_xrandr->xdisplay,
@@ -318,9 +252,12 @@ output_get_backlight_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
&nitems, &bytes_after, &buffer);
if (actual_type != XA_INTEGER || actual_format != 32 || nitems < 1)
return FALSE;
goto out;
value = ((int*)buffer)[0];
out:
XFree (buffer);
if (value > 0)
return normalize_backlight (output, value);
else
@@ -333,7 +270,7 @@ output_get_backlight_limits_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
{
Atom atom;
xcb_connection_t *xcb_conn;
g_autofree xcb_randr_query_output_property_reply_t *reply;
xcb_randr_query_output_property_reply_t *reply;
atom = XInternAtom (manager_xrandr->xdisplay, "Backlight", False);
@@ -351,12 +288,15 @@ output_get_backlight_limits_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
if (!reply->range || reply->length != 2)
{
meta_verbose ("backlight %s was not range\n", output->name);
return;
goto out;
}
int32_t *values = xcb_randr_query_output_property_valid_values (reply);
output->backlight_min = values[0];
output->backlight_max = values[1];
out:
free (reply);
}
static int
@@ -436,42 +376,6 @@ read_output_edid (MetaMonitorManagerXrandr *manager_xrandr,
return NULL;
}
static void
output_get_tile_info (MetaMonitorManagerXrandr *manager_xrandr,
MetaOutput *output)
{
Atom tile_atom;
unsigned char *prop;
unsigned long nitems, bytes_after;
int actual_format;
Atom actual_type;
if (manager_xrandr->has_randr15 == FALSE)
return;
tile_atom = XInternAtom (manager_xrandr->xdisplay, "TILE", FALSE);
XRRGetOutputProperty (manager_xrandr->xdisplay,
output->winsys_id,
tile_atom, 0, 100, False,
False, AnyPropertyType,
&actual_type, &actual_format,
&nitems, &bytes_after, &prop);
if (actual_type == XA_INTEGER && actual_format == 32 && nitems == 8)
{
long *values = (long *)prop;
output->tile_info.group_id = values[0];
output->tile_info.flags = values[1];
output->tile_info.max_h_tiles = values[2];
output->tile_info.max_v_tiles = values[3];
output->tile_info.loc_h_tile = values[4];
output->tile_info.loc_v_tile = values[5];
output->tile_info.tile_w = values[6];
output->tile_info.tile_h = values[7];
}
XFree (prop);
}
static gboolean
output_get_hotplug_mode_update (MetaMonitorManagerXrandr *manager_xrandr,
MetaOutput *output)
@@ -543,10 +447,11 @@ static MetaConnectorType
output_get_connector_type_from_prop (MetaMonitorManagerXrandr *manager_xrandr,
MetaOutput *output)
{
MetaConnectorType ret = META_CONNECTOR_TYPE_Unknown;
Atom atom, actual_type, connector_type_atom;
int actual_format;
unsigned long nitems, bytes_after;
g_autofree unsigned char *buffer = NULL;
unsigned char *buffer;
atom = XInternAtom (manager_xrandr->xdisplay, "ConnectorType", False);
XRRGetOutputProperty (manager_xrandr->xdisplay,
@@ -557,10 +462,14 @@ output_get_connector_type_from_prop (MetaMonitorManagerXrandr *manager_xrandr,
&nitems, &bytes_after, &buffer);
if (actual_type != XA_ATOM || actual_format != 32 || nitems < 1)
return META_CONNECTOR_TYPE_Unknown;
goto out;
connector_type_atom = ((Atom *) buffer)[0];
return connector_type_from_atom (manager_xrandr, connector_type_atom);
ret = connector_type_from_atom (manager_xrandr, connector_type_atom);
out:
meta_XFree (buffer);
return ret;
}
static MetaConnectorType
@@ -597,7 +506,7 @@ output_get_connector_type_from_name (MetaMonitorManagerXrandr *manager_xrandr,
if (g_str_has_prefix (name, "Virtual"))
return META_CONNECTOR_TYPE_VIRTUAL;
if (g_str_has_prefix (name, "Composite"))
return META_CONNECTOR_TYPE_Composite;
return META_CONNECTOR_TYPE_VGA;
if (g_str_has_prefix (name, "S-video"))
return META_CONNECTOR_TYPE_SVIDEO;
if (g_str_has_prefix (name, "TV"))
@@ -637,32 +546,6 @@ output_get_connector_type (MetaMonitorManagerXrandr *manager_xrandr,
return META_CONNECTOR_TYPE_Unknown;
}
static void
output_get_modes (MetaMonitorManager *manager,
MetaOutput *meta_output,
XRROutputInfo *output)
{
guint j, k;
guint n_actual_modes;
meta_output->modes = g_new0 (MetaMonitorMode *, output->nmode);
n_actual_modes = 0;
for (j = 0; j < (guint)output->nmode; j++)
{
for (k = 0; k < manager->n_modes; k++)
{
if (output->modes[j] == (XID)manager->modes[k].mode_id)
{
meta_output->modes[n_actual_modes] = &manager->modes[k];
n_actual_modes += 1;
break;
}
}
}
meta_output->n_modes = n_actual_modes;
}
static char *
get_xmode_name (XRRModeInfo *xmode)
{
@@ -799,8 +682,6 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
MetaOutput *meta_output;
output = XRRGetOutputInfo (manager_xrandr->xdisplay, resources, resources->outputs[i]);
if (!output)
continue;
meta_output = &manager->outputs[n_actual_outputs];
@@ -823,8 +704,19 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
meta_output->suggested_y = output_get_suggested_y (manager_xrandr, meta_output);
meta_output->connector_type = output_get_connector_type (manager_xrandr, meta_output);
output_get_tile_info (manager_xrandr, meta_output);
output_get_modes (manager, meta_output, output);
meta_output->n_modes = output->nmode;
meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
for (j = 0; j < meta_output->n_modes; j++)
{
for (k = 0; k < manager->n_modes; k++)
{
if (output->modes[j] == (XID)manager->modes[k].mode_id)
{
meta_output->modes[j] = &manager->modes[k];
break;
}
}
}
meta_output->preferred_mode = meta_output->modes[0];
meta_output->n_possible_crtcs = output->ncrtc;
@@ -864,8 +756,6 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
meta_output->is_primary = ((XID)meta_output->winsys_id == primary_output);
meta_output->is_presentation = output_get_presentation_xrandr (manager_xrandr, meta_output);
meta_output->is_underscanning = output_get_underscanning_xrandr (manager_xrandr, meta_output);
meta_output->supports_underscanning = output_get_supports_underscanning_xrandr (manager_xrandr, meta_output);
output_get_backlight_limits_xrandr (manager_xrandr, meta_output);
if (!(meta_output->backlight_min == 0 && meta_output->backlight_max == 0))
@@ -979,58 +869,11 @@ output_set_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
int value = presentation;
atom = XInternAtom (manager_xrandr->xdisplay, "_MUTTER_PRESENTATION_OUTPUT", False);
xcb_randr_change_output_property (XGetXCBConnection (manager_xrandr->xdisplay),
(XID)output->winsys_id,
atom, XCB_ATOM_CARDINAL, 32,
XCB_PROP_MODE_REPLACE,
1, &value);
}
static void
output_set_underscanning_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
MetaOutput *output,
gboolean underscanning)
{
Atom prop, valueatom;
const char *value;
prop = XInternAtom (manager_xrandr->xdisplay, "underscan", False);
value = underscanning ? "on" : "off";
valueatom = XInternAtom (manager_xrandr->xdisplay, value, False);
xcb_randr_change_output_property (XGetXCBConnection (manager_xrandr->xdisplay),
(XID)output->winsys_id,
prop, XCB_ATOM_ATOM, 32,
XCB_PROP_MODE_REPLACE,
1, &valueatom);
/* Configure the border at the same time. Currently, we use a
* 5% of the width/height of the mode. In the future, we should
* make the border configurable. */
if (underscanning)
{
uint32_t border_value;
prop = XInternAtom (manager_xrandr->xdisplay, "underscan hborder", False);
border_value = output->crtc->current_mode->width * 0.05;
xcb_randr_change_output_property (XGetXCBConnection (manager_xrandr->xdisplay),
(XID)output->winsys_id,
prop, XCB_ATOM_INTEGER, 32,
XCB_PROP_MODE_REPLACE,
1, &border_value);
prop = XInternAtom (manager_xrandr->xdisplay, "underscan vborder", False);
border_value = output->crtc->current_mode->height * 0.05;
xcb_randr_change_output_property (XGetXCBConnection (manager_xrandr->xdisplay),
(XID)output->winsys_id,
prop, XCB_ATOM_INTEGER, 32,
XCB_PROP_MODE_REPLACE,
1, &border_value);
}
XRRChangeOutputProperty (manager_xrandr->xdisplay,
(XID)output->winsys_id,
atom,
XA_CARDINAL, 32, PropModeReplace,
(unsigned char*) &value, 1);
}
static void
@@ -1149,16 +992,17 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
if (crtc_info->mode != NULL)
{
MetaMonitorMode *mode;
g_autofree XID *output_ids = NULL;
unsigned int j, n_output_ids;
XID *outputs;
unsigned int j, n_outputs;
int width, height;
Status ok;
mode = crtc_info->mode;
n_output_ids = crtc_info->outputs->len;
output_ids = g_new (XID, n_output_ids);
n_outputs = crtc_info->outputs->len;
outputs = g_new (XID, n_outputs);
for (j = 0; j < n_output_ids; j++)
for (j = 0; j < n_outputs; j++)
{
MetaOutput *output;
@@ -1167,7 +1011,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
output->is_dirty = TRUE;
output->crtc = crtc;
output_ids[j] = output->winsys_id;
outputs[j] = output->winsys_id;
}
ok = XRRSetCrtcConfig (manager_xrandr->xdisplay,
@@ -1177,7 +1021,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
crtc_info->x, crtc_info->y,
(XID)mode->mode_id,
meta_monitor_transform_to_xrandr (crtc_info->transform),
output_ids, n_output_ids);
outputs, n_outputs);
if (ok != Success)
{
@@ -1185,7 +1029,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
(unsigned)(crtc->crtc_id), (unsigned)(mode->mode_id),
mode->width, mode->height, (float)mode->refresh_rate,
crtc_info->x, crtc_info->y, crtc_info->transform);
continue;
goto next;
}
if (meta_monitor_transform_is_rotated (crtc_info->transform))
@@ -1205,6 +1049,9 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
crtc->rect.height = height;
crtc->current_mode = mode;
crtc->transform = crtc_info->transform;
next:
g_free (outputs);
}
}
@@ -1224,14 +1071,8 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
output_info->output,
output_info->is_presentation);
if (output_get_supports_underscanning_xrandr (manager_xrandr, output_info->output))
output_set_underscanning_xrandr (manager_xrandr,
output_info->output,
output_info->is_underscanning);
output->is_primary = output_info->is_primary;
output->is_presentation = output_info->is_presentation;
output->is_underscanning = output_info->is_underscanning;
}
/* Disable outputs not mentioned in the list */
@@ -1265,12 +1106,11 @@ meta_monitor_manager_xrandr_change_backlight (MetaMonitorManager *manager,
hw_value = round ((double)value / 100.0 * output->backlight_max + output->backlight_min);
atom = XInternAtom (manager_xrandr->xdisplay, "Backlight", False);
xcb_randr_change_output_property (XGetXCBConnection (manager_xrandr->xdisplay),
(XID)output->winsys_id,
atom, XCB_ATOM_INTEGER, 32,
XCB_PROP_MODE_REPLACE,
1, &hw_value);
XRRChangeOutputProperty (manager_xrandr->xdisplay,
(XID)output->winsys_id,
atom,
XA_INTEGER, 32, PropModeReplace,
(unsigned char *) &hw_value, 1);
/* We're not selecting for property notifies, so update the value immediately */
output->backlight = normalize_backlight (output, hw_value);
@@ -1318,88 +1158,6 @@ meta_monitor_manager_xrandr_set_crtc_gamma (MetaMonitorManager *manager,
XRRFreeGamma (gamma);
}
#ifdef HAVE_XRANDR15
static void
meta_monitor_manager_xrandr_add_monitor(MetaMonitorManager *manager,
MetaMonitorInfo *monitor)
{
MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
XRRMonitorInfo *m;
int o;
Atom name;
char name_buf[40];
if (manager_xrandr->has_randr15 == FALSE)
return;
if (monitor->n_outputs <= 1)
return;
if (monitor->outputs[0]->product)
snprintf (name_buf, 40, "%s-%d", monitor->outputs[0]->product, monitor->outputs[0]->tile_info.group_id);
else
snprintf (name_buf, 40, "Tiled-%d", monitor->outputs[0]->tile_info.group_id);
name = XInternAtom (manager_xrandr->xdisplay, name_buf, False);
monitor->monitor_winsys_xid = name;
m = XRRAllocateMonitor (manager_xrandr->xdisplay, monitor->n_outputs);
if (!m)
return;
m->name = name;
m->primary = monitor->is_primary;
m->automatic = True;
for (o = 0; o < monitor->n_outputs; o++) {
MetaOutput *output = monitor->outputs[o];
m->outputs[o] = output->winsys_id;
}
XRRSetMonitor (manager_xrandr->xdisplay,
DefaultRootWindow (manager_xrandr->xdisplay),
m);
XRRFreeMonitors (m);
}
static void
meta_monitor_manager_xrandr_delete_monitor(MetaMonitorManager *manager,
int monitor_winsys_xid)
{
MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
if (manager_xrandr->has_randr15 == FALSE)
return;
XRRDeleteMonitor (manager_xrandr->xdisplay,
DefaultRootWindow (manager_xrandr->xdisplay),
monitor_winsys_xid);
}
static void
meta_monitor_manager_xrandr_init_monitors(MetaMonitorManagerXrandr *manager_xrandr)
{
XRRMonitorInfo *m;
int n, i;
if (manager_xrandr->has_randr15 == FALSE)
return;
/* delete any tiled monitors setup, as mutter will want to recreate
things in its image */
m = XRRGetMonitors (manager_xrandr->xdisplay,
DefaultRootWindow (manager_xrandr->xdisplay),
FALSE, &n);
if (n == -1)
return;
for (i = 0; i < n; i++)
{
if (m[i].noutput > 1)
XRRDeleteMonitor (manager_xrandr->xdisplay,
DefaultRootWindow (manager_xrandr->xdisplay),
m[i].name);
}
XRRFreeMonitors (m);
}
#endif
static void
meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
{
@@ -1415,7 +1173,6 @@ meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
}
else
{
int major_version, minor_version;
/* We only use ScreenChangeNotify, but GDK uses the others,
and we don't want to step on its toes */
XRRSelectInput (manager_xrandr->xdisplay,
@@ -1423,17 +1180,6 @@ meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
RRScreenChangeNotifyMask
| RRCrtcChangeNotifyMask
| RROutputPropertyNotifyMask);
manager_xrandr->has_randr15 = FALSE;
XRRQueryVersion (manager_xrandr->xdisplay, &major_version,
&minor_version);
#ifdef HAVE_XRANDR15
if (major_version > 1 ||
(major_version == 1 &&
minor_version >= 5))
manager_xrandr->has_randr15 = TRUE;
meta_monitor_manager_xrandr_init_monitors (manager_xrandr);
#endif
}
}
@@ -1464,10 +1210,6 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
manager_class->change_backlight = meta_monitor_manager_xrandr_change_backlight;
manager_class->get_crtc_gamma = meta_monitor_manager_xrandr_get_crtc_gamma;
manager_class->set_crtc_gamma = meta_monitor_manager_xrandr_set_crtc_gamma;
#ifdef HAVE_XRANDR15
manager_class->add_monitor = meta_monitor_manager_xrandr_add_monitor;
manager_class->delete_monitor = meta_monitor_manager_xrandr_delete_monitor;
#endif
}
gboolean

View File

@@ -1,89 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2015 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.
*
* Written by:
* Jonas Ådahl <jadahl@gmail.com>
*/
#include "config.h"
#include "backends/x11/nested/meta-cursor-renderer-x11-nested.h"
#include "backends/x11/meta-backend-x11.h"
struct _MetaCursorRendererX11Nested
{
MetaCursorRenderer parent;
};
G_DEFINE_TYPE (MetaCursorRendererX11Nested, meta_cursor_renderer_x11_nested,
META_TYPE_CURSOR_RENDERER);
static gboolean
meta_cursor_renderer_x11_nested_update_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
{
if (cursor_sprite)
meta_cursor_sprite_realize_texture (cursor_sprite);
return FALSE;
}
static Cursor
create_empty_cursor (Display *xdisplay)
{
XcursorImage *image;
XcursorPixel *pixels;
Cursor xcursor;
image = XcursorImageCreate (1, 1);
if (image == NULL)
return None;
image->xhot = 0;
image->yhot = 0;
pixels = image->pixels;
pixels[0] = 0;
xcursor = XcursorImageLoadCursor (xdisplay, image);
XcursorImageDestroy (image);
return xcursor;
}
static void
meta_cursor_renderer_x11_nested_init (MetaCursorRendererX11Nested *x11_nested)
{
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
Window xwindow = meta_backend_x11_get_xwindow (backend);
Display *xdisplay = meta_backend_x11_get_xdisplay (backend);
Cursor empty_xcursor = create_empty_cursor (xdisplay);
XDefineCursor (xdisplay, xwindow, empty_xcursor);
XFreeCursor (xdisplay, empty_xcursor);
}
static void
meta_cursor_renderer_x11_nested_class_init (MetaCursorRendererX11NestedClass *klass)
{
MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_CLASS (klass);
renderer_class->update_cursor = meta_cursor_renderer_x11_nested_update_cursor;
}

View File

@@ -1,38 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2015 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.
*
* Written by:
* Jonas Ådahl <jadahl@gmail.com>
*/
#ifndef META_CURSOR_RENDERER_X11_NESTED_NESTED_H
#define META_CURSOR_RENDERER_X11_NESTED_NESTED_H
#include <glib-object.h>
#include "backends/meta-cursor-renderer.h"
#define META_TYPE_CURSOR_RENDERER_X11_NESTED (meta_cursor_renderer_x11_nested_get_type ())
G_DECLARE_FINAL_TYPE (MetaCursorRendererX11Nested,
meta_cursor_renderer_x11_nested,
META, CURSOR_RENDERER_X11_NESTED,
MetaCursorRenderer);
#endif /* META_CURSOR_RENDERER_X11_NESTED_NESTED_H */

View File

@@ -15,8 +15,7 @@ struct _MetaCompositor
{
MetaDisplay *display;
guint pre_paint_func_id;
guint post_paint_func_id;
guint repaint_func_id;
gint64 server_time_query_time;
gint64 server_time_offset;
@@ -41,7 +40,6 @@ struct _MetaCompositor
MetaPluginManager *plugin_mgr;
gboolean frame_has_updated_xsurfaces;
gboolean have_x11_sync_object;
};
/* Wait 2ms after vblank before starting to draw next frame */

View File

@@ -37,6 +37,11 @@
* compositor needs to delay hiding the windows until the switch
* workspace animation completes.
*
* meta_compositor_maximize_window() and meta_compositor_unmaximize_window()
* are transitions within the visible state. The window is resized __before__
* the call, so it may be necessary to readjust the display based on the
* old_rect to start the animation.
*
* # Containers #
*
* There's two containers in the stage that are used to place window actors, here
@@ -74,7 +79,6 @@
#include "frame.h"
#include <X11/extensions/shape.h>
#include <X11/extensions/Xcomposite.h>
#include "meta-sync-ring.h"
#include "backends/x11/meta-backend-x11.h"
@@ -121,11 +125,7 @@ meta_switch_workspace_completed (MetaCompositor *compositor)
void
meta_compositor_destroy (MetaCompositor *compositor)
{
clutter_threads_remove_repaint_func (compositor->pre_paint_func_id);
clutter_threads_remove_repaint_func (compositor->post_paint_func_id);
if (compositor->have_x11_sync_object)
meta_sync_ring_destroy ();
clutter_threads_remove_repaint_func (compositor->repaint_func_id);
}
static void
@@ -468,11 +468,13 @@ meta_compositor_manage (MetaCompositor *compositor)
MetaDisplay *display = compositor->display;
Display *xdisplay = display->xdisplay;
MetaScreen *screen = display->screen;
MetaBackend *backend = meta_get_backend ();
meta_screen_set_cm_selection (display->screen);
compositor->stage = meta_backend_get_stage (backend);
{
MetaBackend *backend = meta_get_backend ();
compositor->stage = meta_backend_get_stage (backend);
}
/* We use connect_after() here to accomodate code in GNOME Shell that,
* when benchmarking drawing performance, connects to ::after-paint
@@ -508,7 +510,7 @@ meta_compositor_manage (MetaCompositor *compositor)
compositor->output = screen->composite_overlay_window;
xwin = meta_backend_x11_get_xwindow (META_BACKEND_X11 (backend));
xwin = meta_backend_x11_get_xwindow (META_BACKEND_X11 (meta_get_backend ()));
XReparentWindow (xdisplay, xwin, compositor->output, 0, 0);
@@ -528,8 +530,6 @@ meta_compositor_manage (MetaCompositor *compositor)
* contents until we show the stage.
*/
XMapWindow (xdisplay, compositor->output);
compositor->have_x11_sync_object = meta_sync_ring_init (xdisplay);
}
redirect_windows (display->screen);
@@ -731,9 +731,6 @@ meta_compositor_process_event (MetaCompositor *compositor,
process_damage (compositor, (XDamageNotifyEvent *) event, window);
}
if (compositor->have_x11_sync_object)
meta_sync_ring_handle_event (event);
/* Clutter needs to know about MapNotify events otherwise it will
think the stage is invisible */
if (!meta_is_wayland_compositor () && event->type == MapNotify)
@@ -772,14 +769,23 @@ meta_compositor_hide_window (MetaCompositor *compositor,
}
void
meta_compositor_size_change_window (MetaCompositor *compositor,
MetaWindow *window,
MetaSizeChange which_change,
MetaRectangle *old_frame_rect,
MetaRectangle *old_buffer_rect)
meta_compositor_maximize_window (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *old_rect,
MetaRectangle *new_rect)
{
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
meta_window_actor_size_change (window_actor, which_change, old_frame_rect, old_buffer_rect);
meta_window_actor_maximize (window_actor, old_rect, new_rect);
}
void
meta_compositor_unmaximize_window (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *old_rect,
MetaRectangle *new_rect)
{
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
meta_window_actor_unmaximize (window_actor, old_rect, new_rect);
}
void
@@ -1038,12 +1044,11 @@ frame_callback (CoglOnscreen *onscreen,
}
}
static gboolean
meta_pre_paint_func (gpointer data)
static void
pre_paint_windows (MetaCompositor *compositor)
{
GList *l;
MetaWindowActor *top_window;
MetaCompositor *compositor = data;
if (compositor->onscreen == NULL)
{
@@ -1055,7 +1060,7 @@ meta_pre_paint_func (gpointer data)
}
if (compositor->windows == NULL)
return TRUE;
return;
top_window = g_list_last (compositor->windows)->data;
@@ -1072,12 +1077,10 @@ meta_pre_paint_func (gpointer data)
{
/* We need to make sure that any X drawing that happens before
* the XDamageSubtract() for each window above is visible to
* subsequent GL rendering; the standardized way to do this is
* GL_EXT_X11_sync_object. Since this isn't implemented yet in
* mesa, we also have a path that relies on the implementation
* of the open source drivers.
*
* Anything else, we just hope for the best.
* subsequent GL rendering; the only standardized way to do this
* is EXT_x11_sync_object, which isn't yet widely available. For
* now, we count on details of Xorg and the open source drivers,
* and hope for the best otherwise.
*
* Xorg and open source driver specifics:
*
@@ -1092,28 +1095,17 @@ meta_pre_paint_func (gpointer data)
* round trip request at this point is sufficient to flush the
* GLX buffers.
*/
if (compositor->have_x11_sync_object)
compositor->have_x11_sync_object = meta_sync_ring_insert_wait ();
else
XSync (compositor->display->xdisplay, False);
}
return TRUE;
}
static gboolean
meta_post_paint_func (gpointer data)
{
MetaCompositor *compositor = data;
if (compositor->frame_has_updated_xsurfaces)
{
if (compositor->have_x11_sync_object)
compositor->have_x11_sync_object = meta_sync_ring_after_frame ();
XSync (compositor->display->xdisplay, False);
compositor->frame_has_updated_xsurfaces = FALSE;
}
}
static gboolean
meta_repaint_func (gpointer data)
{
MetaCompositor *compositor = data;
pre_paint_windows (compositor);
return TRUE;
}
@@ -1148,16 +1140,10 @@ meta_compositor_new (MetaDisplay *display)
G_CALLBACK (on_shadow_factory_changed),
compositor);
compositor->pre_paint_func_id =
clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_PRE_PAINT,
meta_pre_paint_func,
compositor,
NULL);
compositor->post_paint_func_id =
clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT,
meta_post_paint_func,
compositor,
NULL);
compositor->repaint_func_id = clutter_threads_add_repaint_func (meta_repaint_func,
compositor,
NULL);
return compositor;
}

View File

@@ -22,8 +22,6 @@
#include "meta-background-private.h"
#include "cogl-utils.h"
#include <string.h>
enum
{
CHANGED,
@@ -73,8 +71,6 @@ enum
G_DEFINE_TYPE (MetaBackground, meta_background, G_TYPE_OBJECT)
static gboolean texture_has_alpha (CoglTexture *texture);
static GSList *all_backgrounds = NULL;
static void
@@ -478,7 +474,7 @@ get_texture_area (MetaBackground *self,
}
}
static gboolean
static void
draw_texture (MetaBackground *self,
CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
@@ -487,7 +483,6 @@ draw_texture (MetaBackground *self,
{
MetaBackgroundPrivate *priv = self->priv;
cairo_rectangle_int_t texture_area;
gboolean bare_region_visible;
get_texture_area (self, monitor_area, texture, &texture_area);
@@ -508,9 +503,6 @@ draw_texture (MetaBackground *self,
- texture_area.y / (float)texture_area.height,
(monitor_area->width - texture_area.x) / (float)texture_area.width,
(monitor_area->height - texture_area.y) / (float)texture_area.height);
bare_region_visible = texture_has_alpha (texture);
/* Draw just the texture */
break;
case G_DESKTOP_BACKGROUND_STYLE_CENTERED:
@@ -521,16 +513,11 @@ draw_texture (MetaBackground *self,
texture_area.x + texture_area.width,
texture_area.y + texture_area.height,
0, 0, 1.0, 1.0);
bare_region_visible = texture_has_alpha (texture) || memcmp (&texture_area, monitor_area, sizeof (cairo_rectangle_int_t)) != 0;
break;
case G_DESKTOP_BACKGROUND_STYLE_NONE:
bare_region_visible = TRUE;
break;
default:
g_return_val_if_reached(FALSE);
g_return_if_reached();
}
return bare_region_visible;
}
static void
@@ -761,7 +748,6 @@ meta_background_get_texture (MetaBackground *self,
if (monitor->dirty)
{
CoglError *catch_error = NULL;
gboolean bare_region_visible = FALSE;
if (monitor->texture == NULL)
{
@@ -797,9 +783,9 @@ meta_background_get_texture (MetaBackground *self,
cogl_pipeline_set_layer_texture (pipeline, 0, texture2);
cogl_pipeline_set_layer_wrap_mode (pipeline, 0, get_wrap_mode (priv->style));
bare_region_visible = draw_texture (self,
monitor->fbo, pipeline,
texture2, &monitor_area);
draw_texture (self,
monitor->fbo, pipeline,
texture2, &monitor_area);
cogl_object_unref (pipeline);
}
@@ -810,7 +796,8 @@ meta_background_get_texture (MetaBackground *self,
0.0, 0.0, 0.0, 0.0);
}
if (texture1 != NULL && priv->blend_factor != 1.0)
if (texture1 != NULL &&
!(texture2 != NULL && priv->blend_factor == 1.0 && !texture_has_alpha (texture2)))
{
CoglPipeline *pipeline = create_pipeline (PIPELINE_ADD);
cogl_pipeline_set_color4f (pipeline,
@@ -821,14 +808,15 @@ meta_background_get_texture (MetaBackground *self,
cogl_pipeline_set_layer_texture (pipeline, 0, texture1);
cogl_pipeline_set_layer_wrap_mode (pipeline, 0, get_wrap_mode (priv->style));
bare_region_visible = bare_region_visible || draw_texture (self,
monitor->fbo, pipeline,
texture1, &monitor_area);
draw_texture (self,
monitor->fbo, pipeline,
texture1, &monitor_area);
cogl_object_unref (pipeline);
}
if (bare_region_visible)
if (!((texture2 != NULL && priv->blend_factor == 1.0 && !texture_has_alpha (texture2)) ||
(texture1 != NULL && !texture_has_alpha (texture1))))
{
CoglPipeline *pipeline = create_pipeline (PIPELINE_OVER_REVERSE);

View File

@@ -187,7 +187,7 @@ meta_feedback_actor_set_anchor (MetaFeedbackActor *self,
if (priv->anchor_x == anchor_x && priv->anchor_y == anchor_y)
return;
if (priv->anchor_x != anchor_x)
if (priv->anchor_x != anchor_y)
{
priv->anchor_x = anchor_x;
g_object_notify (G_OBJECT (self), "anchor-x");

View File

@@ -149,7 +149,7 @@ meta_plugin_manager_kill_switch_workspace (MetaPluginManager *plugin_mgr)
gboolean
meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr,
MetaWindowActor *actor,
MetaPluginEffect event)
unsigned long event)
{
MetaPlugin *plugin = plugin_mgr->plugin;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
@@ -196,32 +196,67 @@ meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr,
}
break;
default:
g_warning ("Incorrect handler called for event %d", event);
g_warning ("Incorrect handler called for event %lu", event);
}
return retval;
}
/*
* The public method that the compositor hooks into for maximize and unmaximize
* events.
*
* Returns TRUE if the plugin handled the event type (i.e.,
* if the return value is FALSE, there will be no subsequent call to the
* manager completed() callback, and the compositor must ensure that any
* appropriate post-effect cleanup is carried out.
*/
gboolean
meta_plugin_manager_event_size_change (MetaPluginManager *plugin_mgr,
MetaWindowActor *actor,
MetaSizeChange which_change,
MetaRectangle *old_frame_rect,
MetaRectangle *old_buffer_rect)
meta_plugin_manager_event_maximize (MetaPluginManager *plugin_mgr,
MetaWindowActor *actor,
unsigned long event,
gint target_x,
gint target_y,
gint target_width,
gint target_height)
{
MetaPlugin *plugin = plugin_mgr->plugin;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
MetaDisplay *display = plugin_mgr->compositor->display;
gboolean retval = FALSE;
if (display->display_opening)
return FALSE;
if (!klass->size_change)
return FALSE;
switch (event)
{
case META_PLUGIN_MAXIMIZE:
if (klass->maximize)
{
retval = TRUE;
meta_plugin_manager_kill_window_effects (plugin_mgr,
actor);
klass->maximize (plugin, actor,
target_x, target_y,
target_width, target_height);
}
break;
case META_PLUGIN_UNMAXIMIZE:
if (klass->unmaximize)
{
retval = TRUE;
meta_plugin_manager_kill_window_effects (plugin_mgr,
actor);
klass->unmaximize (plugin, actor,
target_x, target_y,
target_width, target_height);
}
break;
default:
g_warning ("Incorrect handler called for event %lu", event);
}
meta_plugin_manager_kill_window_effects (plugin_mgr, actor);
klass->size_change (plugin, actor, which_change, old_frame_rect, old_buffer_rect);
return TRUE;
return retval;
}
/*

View File

@@ -24,17 +24,20 @@
#include <meta/types.h>
#include <meta/screen.h>
#include <meta/meta-plugin.h>
typedef enum {
META_PLUGIN_NONE,
META_PLUGIN_MINIMIZE,
META_PLUGIN_MAP,
META_PLUGIN_DESTROY,
META_PLUGIN_SWITCH_WORKSPACE,
META_PLUGIN_UNMINIMIZE,
META_PLUGIN_SIZE_CHANGE,
} MetaPluginEffect;
#define META_PLUGIN_FROM_MANAGER_
#include <meta/meta-plugin.h>
#undef META_PLUGIN_FROM_MANAGER_
#define META_PLUGIN_MINIMIZE (1<<0)
#define META_PLUGIN_MAXIMIZE (1<<1)
#define META_PLUGIN_UNMAXIMIZE (1<<2)
#define META_PLUGIN_MAP (1<<3)
#define META_PLUGIN_DESTROY (1<<4)
#define META_PLUGIN_SWITCH_WORKSPACE (1<<5)
#define META_PLUGIN_UNMINIMIZE (1<<6)
#define META_PLUGIN_ALL_EFFECTS (~0)
/**
* MetaPluginManager: (skip)
@@ -48,13 +51,15 @@ void meta_plugin_manager_load (const gchar *plugin_name);
gboolean meta_plugin_manager_event_simple (MetaPluginManager *mgr,
MetaWindowActor *actor,
MetaPluginEffect event);
unsigned long event);
gboolean meta_plugin_manager_event_size_change (MetaPluginManager *mgr,
MetaWindowActor *actor,
MetaSizeChange which_change,
MetaRectangle *old_frame_rect,
MetaRectangle *old_buffer_rect);
gboolean meta_plugin_manager_event_maximize (MetaPluginManager *mgr,
MetaWindowActor *actor,
unsigned long event,
gint target_x,
gint target_y,
gint target_width,
gint target_height);
gboolean meta_plugin_manager_switch_workspace (MetaPluginManager *mgr,
gint from,

View File

@@ -118,10 +118,17 @@ meta_plugin_unminimize_completed (MetaPlugin *plugin,
}
void
meta_plugin_size_change_completed (MetaPlugin *plugin,
MetaWindowActor *actor)
meta_plugin_maximize_completed (MetaPlugin *plugin,
MetaWindowActor *actor)
{
meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_SIZE_CHANGE);
meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_MAXIMIZE);
}
void
meta_plugin_unmaximize_completed (MetaPlugin *plugin,
MetaWindowActor *actor)
{
meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_UNMAXIMIZE);
}
void

View File

@@ -0,0 +1,66 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* MetaShadowFactory:
*
* Create and cache shadow textures for arbitrary window shapes
*
* Copyright (C) 2010 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 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/>.
*/
#ifndef __META_SHADOW_FACTORY_PRIVATE_H__
#define __META_SHADOW_FACTORY_PRIVATE_H__
#include <cairo.h>
#include <clutter/clutter.h>
#include "meta-window-shape.h"
#include <meta/meta-shadow-factory.h>
/**
* MetaShadow:
* #MetaShadow holds a shadow texture along with information about how to
* apply that texture to draw a window texture. (E.g., it knows how big the
* unscaled borders are on each side of the shadow texture.)
*/
typedef struct _MetaShadow MetaShadow;
MetaShadow *meta_shadow_ref (MetaShadow *shadow);
void meta_shadow_unref (MetaShadow *shadow);
CoglTexture*meta_shadow_get_texture (MetaShadow *shadow);
void meta_shadow_paint (MetaShadow *shadow,
int window_x,
int window_y,
int window_width,
int window_height,
guint8 opacity,
cairo_region_t *clip,
gboolean clip_strictly);
void meta_shadow_get_bounds (MetaShadow *shadow,
int window_x,
int window_y,
int window_width,
int window_height,
cairo_rectangle_int_t *bounds);
MetaShadowFactory *meta_shadow_factory_new (void);
MetaShadow *meta_shadow_factory_get_shadow (MetaShadowFactory *factory,
MetaWindowShape *shape,
int width,
int height,
const char *class_name,
gboolean focused);
#endif /* __META_SHADOW_FACTORY_PRIVATE_H__ */

View File

@@ -26,9 +26,8 @@
#include <math.h>
#include <string.h>
#include <meta/meta-shadow-factory.h>
#include "cogl-utils.h"
#include "meta-shadow-factory-private.h"
#include "region-utils.h"
/* This file implements blurring the shape of a window to produce a
@@ -1049,6 +1048,3 @@ meta_shadow_factory_get_params (MetaShadowFactory *factory,
if (params)
*params = *stored_params;
}
G_DEFINE_BOXED_TYPE (MetaShadow, meta_shadow,
meta_shadow_ref, meta_shadow_unref)

View File

@@ -32,9 +32,6 @@
ClutterActor *meta_shaped_texture_new (void);
void meta_shaped_texture_set_texture (MetaShapedTexture *stex,
CoglTexture *texture);
void meta_shaped_texture_set_fallback_size (MetaShapedTexture *stex,
guint fallback_width,
guint fallback_height);
gboolean meta_shaped_texture_is_obscured (MetaShapedTexture *self);
#endif

View File

@@ -86,7 +86,6 @@ struct _MetaShapedTexturePrivate
cairo_region_t *unobscured_region;
guint tex_width, tex_height;
guint fallback_width, fallback_height;
guint create_mipmaps : 1;
};
@@ -137,20 +136,7 @@ set_unobscured_region (MetaShapedTexture *self,
g_clear_pointer (&priv->unobscured_region, (GDestroyNotify) cairo_region_destroy);
if (unobscured_region)
{
guint width, height;
if (priv->texture)
{
width = priv->tex_width;
height = priv->tex_height;
}
else
{
width = priv->fallback_width;
height = priv->fallback_height;
}
cairo_rectangle_int_t bounds = { 0, 0, width, height };
cairo_rectangle_int_t bounds = { 0, 0, priv->tex_width, priv->tex_height };
priv->unobscured_region = cairo_region_copy (unobscured_region);
cairo_region_intersect_rectangle (priv->unobscured_region, &bounds);
}
@@ -187,25 +173,10 @@ meta_shaped_texture_dispose (GObject *object)
G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object);
}
static CoglPipeline *
get_base_pipeline (CoglContext *ctx)
{
static CoglPipeline *template = NULL;
if (G_UNLIKELY (template == NULL))
{
template = cogl_pipeline_new (ctx);
cogl_pipeline_set_layer_wrap_mode_s (template, 0, COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
cogl_pipeline_set_layer_wrap_mode_t (template, 0, COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
cogl_pipeline_set_layer_wrap_mode_s (template, 1, COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
cogl_pipeline_set_layer_wrap_mode_t (template, 1, COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
}
return template;
}
static CoglPipeline *
get_unmasked_pipeline (CoglContext *ctx)
{
return get_base_pipeline (ctx);
return cogl_pipeline_new (ctx);
}
static CoglPipeline *
@@ -214,13 +185,13 @@ get_masked_pipeline (CoglContext *ctx)
static CoglPipeline *template = NULL;
if (G_UNLIKELY (template == NULL))
{
template = cogl_pipeline_copy (get_base_pipeline (ctx));
template = cogl_pipeline_new (ctx);
cogl_pipeline_set_layer_combine (template, 1,
"RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
NULL);
}
return template;
return cogl_pipeline_copy (template);
}
static CoglPipeline *
@@ -230,7 +201,7 @@ get_unblended_pipeline (CoglContext *ctx)
if (G_UNLIKELY (template == NULL))
{
CoglColor color;
template = cogl_pipeline_copy (get_base_pipeline (ctx));
template = cogl_pipeline_new (ctx);
cogl_color_init_from_4ub (&color, 255, 255, 255, 255);
cogl_pipeline_set_blend (template,
"RGBA = ADD (SRC_COLOR, 0)",
@@ -238,7 +209,7 @@ get_unblended_pipeline (CoglContext *ctx)
cogl_pipeline_set_color (template, &color);
}
return template;
return cogl_pipeline_copy (template);
}
static void
@@ -449,6 +420,8 @@ meta_shaped_texture_paint (ClutterActor *actor)
cairo_region_get_rectangle (region, i, &rect);
paint_clipped_rectangle (fb, opaque_pipeline, &rect, &alloc);
}
cogl_object_unref (opaque_pipeline);
}
cairo_region_destroy (region);
@@ -511,6 +484,8 @@ meta_shaped_texture_paint (ClutterActor *actor)
alloc.x2 - alloc.x1,
alloc.y2 - alloc.y1);
}
cogl_object_unref (blended_pipeline);
}
if (blended_region != NULL)
@@ -523,18 +498,17 @@ meta_shaped_texture_get_preferred_width (ClutterActor *self,
gfloat *min_width_p,
gfloat *natural_width_p)
{
MetaShapedTexturePrivate *priv = META_SHAPED_TEXTURE (self)->priv;
guint width;
MetaShapedTexturePrivate *priv;
if (priv->texture)
width = priv->tex_width;
else
width = priv->fallback_width;
g_return_if_fail (META_IS_SHAPED_TEXTURE (self));
priv = META_SHAPED_TEXTURE (self)->priv;
if (min_width_p)
*min_width_p = width;
*min_width_p = priv->tex_width;
if (natural_width_p)
*natural_width_p = width;
*natural_width_p = priv->tex_width;
}
static void
@@ -543,18 +517,17 @@ meta_shaped_texture_get_preferred_height (ClutterActor *self,
gfloat *min_height_p,
gfloat *natural_height_p)
{
MetaShapedTexturePrivate *priv = META_SHAPED_TEXTURE (self)->priv;
guint height;
MetaShapedTexturePrivate *priv;
if (priv->texture)
height = priv->tex_height;
else
height = priv->fallback_height;
g_return_if_fail (META_IS_SHAPED_TEXTURE (self));
priv = META_SHAPED_TEXTURE (self)->priv;
if (min_height_p)
*min_height_p = height;
*min_height_p = priv->tex_height;
if (natural_height_p)
*natural_height_p = height;
*natural_height_p = priv->tex_height;
}
static cairo_region_t *
@@ -887,17 +860,6 @@ meta_shaped_texture_get_image (MetaShapedTexture *stex,
return surface;
}
void
meta_shaped_texture_set_fallback_size (MetaShapedTexture *self,
guint fallback_width,
guint fallback_height)
{
MetaShapedTexturePrivate *priv = self->priv;
priv->fallback_width = fallback_width;
priv->fallback_height = fallback_height;
}
static void
meta_shaped_texture_cull_out (MetaCullable *cullable,
cairo_region_t *unobscured_region,

View File

@@ -26,20 +26,16 @@
#include "meta-surface-actor-wayland.h"
#include <math.h>
#include <cogl/cogl-wayland-server.h>
#include "meta-shaped-texture-private.h"
#include "wayland/meta-wayland-buffer.h"
#include "wayland/meta-wayland-private.h"
#include "wayland/meta-window-wayland.h"
#include "compositor/region-utils.h"
struct _MetaSurfaceActorWaylandPrivate
{
MetaWaylandSurface *surface;
struct wl_list frame_callback_list;
};
typedef struct _MetaSurfaceActorWaylandPrivate MetaSurfaceActorWaylandPrivate;
@@ -84,89 +80,53 @@ meta_surface_actor_wayland_is_unredirected (MetaSurfaceActor *actor)
return FALSE;
}
static int
get_output_scale (int winsys_id)
{
MetaMonitorManager *monitor_manager = meta_monitor_manager_get ();
MetaOutput *outputs;
guint n_outputs, i;
int output_scale = 1;
outputs = meta_monitor_manager_get_outputs (monitor_manager, &n_outputs);
for (i = 0; i < n_outputs; i++)
{
if (outputs[i].winsys_id == winsys_id)
{
output_scale = outputs[i].scale;
break;
}
}
return output_scale;
}
double
meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor)
{
MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (actor);
MetaWaylandSurface *surface = priv->surface;
MetaWindow *window;
MetaWindow *window = surface->window;
int output_scale = 1;
if (!surface)
return 1;
window = meta_wayland_surface_get_toplevel_window (surface);
while (surface)
{
if (surface->window)
{
window = surface->window;
break;
}
surface = surface->sub.parent;
}
/* 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);
output_scale = get_output_scale (window->monitor->winsys_id);
return (double)output_scale / (double)priv->surface->scale;
}
static void
logical_to_actor_position (MetaSurfaceActorWayland *self,
int *x,
int *y)
{
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
MetaWindow *toplevel_window;
int monitor_scale = 1;
toplevel_window = meta_wayland_surface_get_toplevel_window (surface);
if (toplevel_window)
monitor_scale = meta_window_wayland_get_main_monitor_scale (toplevel_window);
*x = *x * monitor_scale;
*y = *y * monitor_scale;
}
/* Convert the current actor state to the corresponding subsurface rectangle
* in logical pixel coordinate space. */
void
meta_surface_actor_wayland_get_subsurface_rect (MetaSurfaceActorWayland *self,
MetaRectangle *rect)
{
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
CoglTexture *texture = surface->buffer->texture;
MetaWindow *toplevel_window;
int monitor_scale;
float x, y;
toplevel_window = meta_wayland_surface_get_toplevel_window (surface);
monitor_scale = meta_window_wayland_get_main_monitor_scale (toplevel_window);
clutter_actor_get_position (CLUTTER_ACTOR (self), &x, &y);
*rect = (MetaRectangle) {
.x = x / monitor_scale,
.y = y / monitor_scale,
.width = cogl_texture_get_width (texture) / surface->scale,
.height = cogl_texture_get_height (texture) / surface->scale,
};
}
void
meta_surface_actor_wayland_sync_subsurface_state (MetaSurfaceActorWayland *self)
{
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
MetaWindow *window;
int x = surface->offset_x + surface->sub.x;
int y = surface->offset_y + surface->sub.y;
window = meta_wayland_surface_get_toplevel_window (surface);
if (window && window->client_type == META_WINDOW_CLIENT_TYPE_X11)
{
/* Bail directly if this is part of a Xwayland window and warn
* if there happen to be offsets anyway since that is not supposed
* to happen. */
g_warn_if_fail (x == 0 && y == 0);
return;
}
logical_to_actor_position (self, &x, &y);
clutter_actor_set_position (CLUTTER_ACTOR (self), x, y);
}
void
meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self)
{
@@ -198,10 +158,6 @@ meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self)
scaled_input_region);
cairo_region_destroy (scaled_input_region);
}
else
{
meta_surface_actor_set_input_region (META_SURFACE_ACTOR (self), NULL);
}
/* Opaque region */
if (surface->opaque_region)
@@ -217,88 +173,31 @@ meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self)
scaled_opaque_region);
cairo_region_destroy (scaled_opaque_region);
}
else
{
meta_surface_actor_set_opaque_region (META_SURFACE_ACTOR (self), NULL);
}
meta_surface_actor_wayland_sync_subsurface_state (self);
}
void
meta_surface_actor_wayland_sync_state_recursive (MetaSurfaceActorWayland *self)
{
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
MetaWindow *window = meta_wayland_surface_get_toplevel_window (surface);
GList *iter;
meta_surface_actor_wayland_sync_state (self);
if (window && window->client_type != META_WINDOW_CLIENT_TYPE_X11)
for (iter = surface->subsurfaces; iter != NULL; iter = iter->next)
{
for (iter = surface->subsurfaces; iter != NULL; iter = iter->next)
{
MetaWaylandSurface *subsurf = iter->data;
MetaWaylandSurface *subsurf = iter->data;
meta_surface_actor_wayland_sync_state_recursive (
META_SURFACE_ACTOR_WAYLAND (subsurf->surface_actor));
}
meta_surface_actor_wayland_sync_state_recursive (
META_SURFACE_ACTOR_WAYLAND (subsurf->surface_actor));
}
}
gboolean
meta_surface_actor_wayland_is_on_monitor (MetaSurfaceActorWayland *self,
MetaMonitorInfo *monitor)
{
float x, y, width, height;
cairo_rectangle_int_t actor_rect;
cairo_region_t *region;
gboolean is_on_monitor;
clutter_actor_get_transformed_position (CLUTTER_ACTOR (self), &x, &y);
clutter_actor_get_transformed_size (CLUTTER_ACTOR (self), &width, &height);
actor_rect.x = (int)roundf (x);
actor_rect.y = (int)roundf (y);
actor_rect.width = (int)roundf (x + width) - actor_rect.x;
actor_rect.height = (int)roundf (y + height) - actor_rect.y;
/* Calculate the scaled surface actor region. */
region = cairo_region_create_rectangle (&actor_rect);
cairo_region_intersect_rectangle (region,
&((cairo_rectangle_int_t) {
.x = monitor->rect.x,
.y = monitor->rect.y,
.width = monitor->rect.width,
.height = monitor->rect.height,
}));
is_on_monitor = !cairo_region_is_empty (region);
cairo_region_destroy (region);
return is_on_monitor;
}
void
meta_surface_actor_wayland_add_frame_callbacks (MetaSurfaceActorWayland *self,
struct wl_list *frame_callbacks)
{
MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self);
wl_list_insert_list (&priv->frame_callback_list, frame_callbacks);
}
static MetaWindow *
meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor)
{
MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (META_SURFACE_ACTOR_WAYLAND (actor));
MetaWaylandSurface *surface = priv->surface;
if (!surface)
return NULL;
return surface->window;
return priv->surface->window;
}
static void
@@ -337,25 +236,6 @@ meta_surface_actor_wayland_get_preferred_height (ClutterActor *self,
*natural_height_p *= scale;
}
static void
meta_surface_actor_wayland_paint (ClutterActor *actor)
{
MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor);
MetaSurfaceActorWaylandPrivate *priv =
meta_surface_actor_wayland_get_instance_private (self);
if (priv->surface)
{
MetaWaylandCompositor *compositor = priv->surface->compositor;
meta_wayland_surface_update_outputs (priv->surface);
wl_list_insert_list (&compositor->frame_callbacks, &priv->frame_callback_list);
wl_list_init (&priv->frame_callback_list);
}
CLUTTER_ACTOR_CLASS (meta_surface_actor_wayland_parent_class)->paint (actor);
}
static void
meta_surface_actor_wayland_dispose (GObject *object)
{
@@ -375,7 +255,6 @@ meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
actor_class->get_preferred_width = meta_surface_actor_wayland_get_preferred_width;
actor_class->get_preferred_height = meta_surface_actor_wayland_get_preferred_height;
actor_class->paint = meta_surface_actor_wayland_paint;
surface_actor_class->process_damage = meta_surface_actor_wayland_process_damage;
surface_actor_class->pre_paint = meta_surface_actor_wayland_pre_paint;
@@ -403,7 +282,6 @@ meta_surface_actor_wayland_new (MetaWaylandSurface *surface)
g_assert (meta_is_wayland_compositor ());
wl_list_init (&priv->frame_callback_list);
priv->surface = surface;
return META_SURFACE_ACTOR (self);
@@ -423,18 +301,3 @@ meta_surface_actor_wayland_get_surface (MetaSurfaceActorWayland *self)
MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self);
return priv->surface;
}
void
meta_surface_actor_wayland_surface_destroyed (MetaSurfaceActorWayland *self)
{
MetaWaylandFrameCallback *callback, *next;
MetaSurfaceActorWaylandPrivate *priv =
meta_surface_actor_wayland_get_instance_private (self);
wl_list_for_each_safe (callback, next, &priv->frame_callback_list, link)
{
wl_resource_destroy (callback->resource);
}
priv->surface = NULL;
}

View File

@@ -30,9 +30,6 @@
#include "meta-surface-actor.h"
#include "wayland/meta-wayland.h"
#include "wayland/meta-wayland-private.h"
#include "backends/meta-monitor-manager-private.h"
G_BEGIN_DECLS
@@ -60,28 +57,16 @@ GType meta_surface_actor_wayland_get_type (void);
MetaSurfaceActor * meta_surface_actor_wayland_new (MetaWaylandSurface *surface);
MetaWaylandSurface * meta_surface_actor_wayland_get_surface (MetaSurfaceActorWayland *self);
void meta_surface_actor_wayland_surface_destroyed (MetaSurfaceActorWayland *self);
void meta_surface_actor_wayland_set_texture (MetaSurfaceActorWayland *self,
CoglTexture *texture);
double meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor);
void meta_surface_actor_wayland_get_subsurface_rect (MetaSurfaceActorWayland *self,
MetaRectangle *rect);
void meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self);
void meta_surface_actor_wayland_sync_state_recursive (MetaSurfaceActorWayland *self);
void meta_surface_actor_wayland_sync_subsurface_state (MetaSurfaceActorWayland *self);
gboolean meta_surface_actor_wayland_is_on_monitor (MetaSurfaceActorWayland *self,
MetaMonitorInfo *monitor);
void meta_surface_actor_wayland_add_frame_callbacks (MetaSurfaceActorWayland *self,
struct wl_list *frame_callbacks);
G_END_DECLS
#endif /* __META_SURFACE_ACTOR_WAYLAND_H__ */

View File

@@ -416,7 +416,6 @@ meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self,
int width, int height)
{
MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
if (priv->last_width == width &&
priv->last_height == height)
@@ -425,5 +424,4 @@ meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self,
priv->size_changed = TRUE;
priv->last_width = width;
priv->last_height = height;
meta_shaped_texture_set_fallback_size (stex, width, height);
}

View File

@@ -1,592 +0,0 @@
/*
* This is based on an original C++ implementation for compiz that
* carries the following copyright notice:
*
*
* Copyright © 2011 NVIDIA Corporation
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of NVIDIA
* Corporation not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior
* permission. NVIDIA Corporation makes no representations about the
* suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* NVIDIA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*
* Authors: James Jones <jajones@nvidia.com>
*/
#include <string.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <X11/extensions/sync.h>
#include <cogl/cogl.h>
#include <clutter/clutter.h>
#include <meta/util.h>
#include "meta-sync-ring.h"
/* Theory of operation:
*
* We use a ring of NUM_SYNCS fence objects. On each frame we advance
* to the next fence in the ring. For each fence we do:
*
* 1. fence is XSyncTriggerFence()'d and glWaitSync()'d
* 2. NUM_SYNCS / 2 frames later, fence should be triggered
* 3. fence is XSyncResetFence()'d
* 4. NUM_SYNCS / 2 frames later, fence should be reset
* 5. go back to 1 and re-use fence
*
* glClientWaitSync() and XAlarms are used in steps 2 and 4,
* respectively, to double-check the expectections.
*/
#define NUM_SYNCS 10
#define MAX_SYNC_WAIT_TIME (1 * 1000 * 1000 * 1000) /* one sec */
#define MAX_REBOOT_ATTEMPTS 2
typedef enum
{
META_SYNC_STATE_READY,
META_SYNC_STATE_WAITING,
META_SYNC_STATE_DONE,
META_SYNC_STATE_RESET_PENDING,
} MetaSyncState;
typedef struct
{
Display *xdisplay;
XSyncFence xfence;
GLsync gl_x11_sync;
GLsync gpu_fence;
XSyncCounter xcounter;
XSyncAlarm xalarm;
XSyncValue next_counter_value;
MetaSyncState state;
} MetaSync;
typedef struct
{
Display *xdisplay;
int xsync_event_base;
int xsync_error_base;
GHashTable *alarm_to_sync;
MetaSync *syncs_array[NUM_SYNCS];
guint current_sync_idx;
MetaSync *current_sync;
guint warmup_syncs;
guint reboots;
} MetaSyncRing;
static MetaSyncRing meta_sync_ring = { 0 };
static XSyncValue SYNC_VALUE_ZERO;
static XSyncValue SYNC_VALUE_ONE;
static const char* (*meta_gl_get_string) (GLenum name);
static void (*meta_gl_get_integerv) (GLenum pname,
GLint *params);
static const char* (*meta_gl_get_stringi) (GLenum name,
GLuint index);
static void (*meta_gl_delete_sync) (GLsync sync);
static GLenum (*meta_gl_client_wait_sync) (GLsync sync,
GLbitfield flags,
GLuint64 timeout);
static void (*meta_gl_wait_sync) (GLsync sync,
GLbitfield flags,
GLuint64 timeout);
static GLsync (*meta_gl_import_sync) (GLenum external_sync_type,
GLintptr external_sync,
GLbitfield flags);
static GLsync (*meta_gl_fence_sync) (GLenum condition,
GLbitfield flags);
static MetaSyncRing *
meta_sync_ring_get (void)
{
if (meta_sync_ring.reboots > MAX_REBOOT_ATTEMPTS)
return NULL;
return &meta_sync_ring;
}
static gboolean
load_gl_symbol (const char *name,
void **func)
{
*func = cogl_get_proc_address (name);
if (!*func)
{
meta_verbose ("MetaSyncRing: failed to resolve required GL symbol \"%s\"\n", name);
return FALSE;
}
return TRUE;
}
static gboolean
check_gl_extensions (void)
{
ClutterBackend *backend;
CoglContext *cogl_context;
CoglDisplay *cogl_display;
CoglRenderer *cogl_renderer;
backend = clutter_get_default_backend ();
cogl_context = clutter_backend_get_cogl_context (backend);
cogl_display = cogl_context_get_display (cogl_context);
cogl_renderer = cogl_display_get_renderer (cogl_display);
switch (cogl_renderer_get_driver (cogl_renderer))
{
case COGL_DRIVER_GL3:
{
int num_extensions, i;
gboolean arb_sync = FALSE;
gboolean x11_sync_object = FALSE;
meta_gl_get_integerv (GL_NUM_EXTENSIONS, &num_extensions);
for (i = 0; i < num_extensions; ++i)
{
const char *ext = meta_gl_get_stringi (GL_EXTENSIONS, i);
if (g_strcmp0 ("GL_ARB_sync", ext) == 0)
arb_sync = TRUE;
else if (g_strcmp0 ("GL_EXT_x11_sync_object", ext) == 0)
x11_sync_object = TRUE;
}
return arb_sync && x11_sync_object;
}
case COGL_DRIVER_GL:
{
const char *extensions = meta_gl_get_string (GL_EXTENSIONS);
return (extensions != NULL &&
strstr (extensions, "GL_ARB_sync") != NULL &&
strstr (extensions, "GL_EXT_x11_sync_object") != NULL);
}
default:
break;
}
return FALSE;
}
static gboolean
load_required_symbols (void)
{
static gboolean success = FALSE;
if (success)
return TRUE;
/* We don't link against libGL directly because cogl may want to
* use something else. This assumes that cogl has been initialized
* and dynamically loaded libGL at this point.
*/
if (!load_gl_symbol ("glGetString", (void **) &meta_gl_get_string))
goto out;
if (!load_gl_symbol ("glGetIntegerv", (void **) &meta_gl_get_integerv))
goto out;
if (!load_gl_symbol ("glGetStringi", (void **) &meta_gl_get_stringi))
goto out;
if (!check_gl_extensions ())
{
meta_verbose ("MetaSyncRing: couldn't find required GL extensions\n");
goto out;
}
if (!load_gl_symbol ("glDeleteSync", (void **) &meta_gl_delete_sync))
goto out;
if (!load_gl_symbol ("glClientWaitSync", (void **) &meta_gl_client_wait_sync))
goto out;
if (!load_gl_symbol ("glWaitSync", (void **) &meta_gl_wait_sync))
goto out;
if (!load_gl_symbol ("glImportSyncEXT", (void **) &meta_gl_import_sync))
goto out;
if (!load_gl_symbol ("glFenceSync", (void **) &meta_gl_fence_sync))
goto out;
success = TRUE;
out:
return success;
}
static void
meta_sync_insert (MetaSync *self)
{
g_return_if_fail (self->state == META_SYNC_STATE_READY);
XSyncTriggerFence (self->xdisplay, self->xfence);
XFlush (self->xdisplay);
meta_gl_wait_sync (self->gl_x11_sync, 0, GL_TIMEOUT_IGNORED);
self->gpu_fence = meta_gl_fence_sync (GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
self->state = META_SYNC_STATE_WAITING;
}
static GLenum
meta_sync_check_update_finished (MetaSync *self,
GLuint64 timeout)
{
GLenum status = GL_WAIT_FAILED;
switch (self->state)
{
case META_SYNC_STATE_DONE:
status = GL_ALREADY_SIGNALED;
break;
case META_SYNC_STATE_WAITING:
status = meta_gl_client_wait_sync (self->gpu_fence, 0, timeout);
if (status == GL_ALREADY_SIGNALED || status == GL_CONDITION_SATISFIED)
{
self->state = META_SYNC_STATE_DONE;
meta_gl_delete_sync (self->gpu_fence);
self->gpu_fence = 0;
}
break;
default:
break;
}
g_warn_if_fail (status != GL_WAIT_FAILED);
return status;
}
static void
meta_sync_reset (MetaSync *self)
{
XSyncAlarmAttributes attrs;
int overflow;
g_return_if_fail (self->state == META_SYNC_STATE_DONE);
XSyncResetFence (self->xdisplay, self->xfence);
attrs.trigger.wait_value = self->next_counter_value;
XSyncChangeAlarm (self->xdisplay, self->xalarm, XSyncCAValue, &attrs);
XSyncSetCounter (self->xdisplay, self->xcounter, self->next_counter_value);
XSyncValueAdd (&self->next_counter_value,
self->next_counter_value,
SYNC_VALUE_ONE,
&overflow);
self->state = META_SYNC_STATE_RESET_PENDING;
}
static void
meta_sync_handle_event (MetaSync *self,
XSyncAlarmNotifyEvent *event)
{
g_return_if_fail (event->alarm == self->xalarm);
g_return_if_fail (self->state == META_SYNC_STATE_RESET_PENDING);
self->state = META_SYNC_STATE_READY;
}
static MetaSync *
meta_sync_new (Display *xdisplay)
{
MetaSync *self;
XSyncAlarmAttributes attrs;
self = g_malloc0 (sizeof (MetaSync));
self->xdisplay = xdisplay;
self->xfence = XSyncCreateFence (xdisplay, DefaultRootWindow (xdisplay), FALSE);
self->gl_x11_sync = 0;
self->gpu_fence = 0;
self->xcounter = XSyncCreateCounter (xdisplay, SYNC_VALUE_ZERO);
attrs.trigger.counter = self->xcounter;
attrs.trigger.value_type = XSyncAbsolute;
attrs.trigger.wait_value = SYNC_VALUE_ONE;
attrs.trigger.test_type = XSyncPositiveTransition;
attrs.events = TRUE;
self->xalarm = XSyncCreateAlarm (xdisplay,
XSyncCACounter |
XSyncCAValueType |
XSyncCAValue |
XSyncCATestType |
XSyncCAEvents,
&attrs);
XSyncIntToValue (&self->next_counter_value, 1);
self->state = META_SYNC_STATE_READY;
return self;
}
static void
meta_sync_import (MetaSync *self)
{
g_return_if_fail (self->gl_x11_sync == 0);
self->gl_x11_sync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0);
}
static Bool
alarm_event_predicate (Display *dpy,
XEvent *event,
XPointer data)
{
MetaSyncRing *ring = meta_sync_ring_get ();
if (!ring)
return False;
if (event->type == ring->xsync_event_base + XSyncAlarmNotify)
{
if (((MetaSync *) data)->xalarm == ((XSyncAlarmNotifyEvent *) event)->alarm)
return True;
}
return False;
}
static void
meta_sync_free (MetaSync *self)
{
/* When our assumptions don't hold, something has gone wrong but we
* don't know what, so we reboot the ring. While doing that, we
* trigger fences before deleting them to try to get ourselves out
* of a potentially stuck GPU state.
*/
switch (self->state)
{
case META_SYNC_STATE_WAITING:
meta_gl_delete_sync (self->gpu_fence);
break;
case META_SYNC_STATE_DONE:
/* nothing to do */
break;
case META_SYNC_STATE_RESET_PENDING:
{
XEvent event;
XIfEvent (self->xdisplay, &event, alarm_event_predicate, (XPointer) self);
meta_sync_handle_event (self, (XSyncAlarmNotifyEvent *) &event);
}
/* fall through */
case META_SYNC_STATE_READY:
XSyncTriggerFence (self->xdisplay, self->xfence);
XFlush (self->xdisplay);
break;
default:
break;
}
meta_gl_delete_sync (self->gl_x11_sync);
XSyncDestroyFence (self->xdisplay, self->xfence);
XSyncDestroyCounter (self->xdisplay, self->xcounter);
XSyncDestroyAlarm (self->xdisplay, self->xalarm);
g_free (self);
}
gboolean
meta_sync_ring_init (Display *xdisplay)
{
gint major, minor;
guint i;
MetaSyncRing *ring = meta_sync_ring_get ();
if (!ring)
return FALSE;
g_return_val_if_fail (xdisplay != NULL, FALSE);
g_return_val_if_fail (ring->xdisplay == NULL, FALSE);
if (!load_required_symbols ())
return FALSE;
if (!XSyncQueryExtension (xdisplay, &ring->xsync_event_base, &ring->xsync_error_base) ||
!XSyncInitialize (xdisplay, &major, &minor))
return FALSE;
XSyncIntToValue (&SYNC_VALUE_ZERO, 0);
XSyncIntToValue (&SYNC_VALUE_ONE, 1);
ring->xdisplay = xdisplay;
ring->alarm_to_sync = g_hash_table_new (NULL, NULL);
for (i = 0; i < NUM_SYNCS; ++i)
{
MetaSync *sync = meta_sync_new (ring->xdisplay);
ring->syncs_array[i] = sync;
g_hash_table_replace (ring->alarm_to_sync, (gpointer) sync->xalarm, sync);
}
/* Since the connection we create the X fences on isn't the same as
* the one used for the GLX context, we need to XSync() here to
* ensure glImportSync() succeeds. */
XSync (xdisplay, False);
for (i = 0; i < NUM_SYNCS; ++i)
meta_sync_import (ring->syncs_array[i]);
ring->current_sync_idx = 0;
ring->current_sync = ring->syncs_array[0];
ring->warmup_syncs = 0;
return TRUE;
}
void
meta_sync_ring_destroy (void)
{
guint i;
MetaSyncRing *ring = meta_sync_ring_get ();
if (!ring)
return;
g_return_if_fail (ring->xdisplay != NULL);
ring->current_sync_idx = 0;
ring->current_sync = NULL;
ring->warmup_syncs = 0;
for (i = 0; i < NUM_SYNCS; ++i)
meta_sync_free (ring->syncs_array[i]);
g_hash_table_destroy (ring->alarm_to_sync);
ring->xsync_event_base = 0;
ring->xsync_error_base = 0;
ring->xdisplay = NULL;
}
static gboolean
meta_sync_ring_reboot (Display *xdisplay)
{
MetaSyncRing *ring = meta_sync_ring_get ();
if (!ring)
return FALSE;
meta_sync_ring_destroy ();
ring->reboots += 1;
if (!meta_sync_ring_get ())
{
meta_warning ("MetaSyncRing: Too many reboots -- disabling\n");
return FALSE;
}
return meta_sync_ring_init (xdisplay);
}
gboolean
meta_sync_ring_after_frame (void)
{
MetaSyncRing *ring = meta_sync_ring_get ();
if (!ring)
return FALSE;
g_return_val_if_fail (ring->xdisplay != NULL, FALSE);
if (ring->warmup_syncs >= NUM_SYNCS / 2)
{
guint reset_sync_idx = (ring->current_sync_idx + NUM_SYNCS - (NUM_SYNCS / 2)) % NUM_SYNCS;
MetaSync *sync_to_reset = ring->syncs_array[reset_sync_idx];
GLenum status = meta_sync_check_update_finished (sync_to_reset, 0);
if (status == GL_TIMEOUT_EXPIRED)
{
meta_warning ("MetaSyncRing: We should never wait for a sync -- add more syncs?\n");
status = meta_sync_check_update_finished (sync_to_reset, MAX_SYNC_WAIT_TIME);
}
if (status != GL_ALREADY_SIGNALED && status != GL_CONDITION_SATISFIED)
{
meta_warning ("MetaSyncRing: Timed out waiting for sync object.\n");
return meta_sync_ring_reboot (ring->xdisplay);
}
meta_sync_reset (sync_to_reset);
}
else
{
ring->warmup_syncs += 1;
}
ring->current_sync_idx += 1;
ring->current_sync_idx %= NUM_SYNCS;
ring->current_sync = ring->syncs_array[ring->current_sync_idx];
return TRUE;
}
gboolean
meta_sync_ring_insert_wait (void)
{
MetaSyncRing *ring = meta_sync_ring_get ();
if (!ring)
return FALSE;
g_return_val_if_fail (ring->xdisplay != NULL, FALSE);
if (ring->current_sync->state != META_SYNC_STATE_READY)
{
meta_warning ("MetaSyncRing: Sync object is not ready -- were events handled properly?\n");
if (!meta_sync_ring_reboot (ring->xdisplay))
return FALSE;
}
meta_sync_insert (ring->current_sync);
return TRUE;
}
void
meta_sync_ring_handle_event (XEvent *xevent)
{
XSyncAlarmNotifyEvent *event;
MetaSync *sync;
MetaSyncRing *ring = meta_sync_ring_get ();
if (!ring)
return;
g_return_if_fail (ring->xdisplay != NULL);
if (xevent->type != (ring->xsync_event_base + XSyncAlarmNotify))
return;
event = (XSyncAlarmNotifyEvent *) xevent;
sync = g_hash_table_lookup (ring->alarm_to_sync, (gpointer) event->alarm);
if (sync)
meta_sync_handle_event (sync, event);
}

View File

@@ -1,14 +0,0 @@
#ifndef _META_SYNC_RING_H_
#define _META_SYNC_RING_H_
#include <glib.h>
#include <X11/Xlib.h>
gboolean meta_sync_ring_init (Display *dpy);
void meta_sync_ring_destroy (void);
gboolean meta_sync_ring_after_frame (void);
gboolean meta_sync_ring_insert_wait (void);
void meta_sync_ring_handle_event (XEvent *event);
#endif /* _META_SYNC_RING_H_ */

View File

@@ -8,7 +8,6 @@
#include <X11/extensions/Xdamage.h>
#include <meta/compositor-mutter.h>
#include "meta-surface-actor.h"
#include "meta-plugin-manager.h"
MetaWindowActor *meta_window_actor_new (MetaWindow *window);
@@ -19,10 +18,12 @@ void meta_window_actor_show (MetaWindowActor *self,
void meta_window_actor_hide (MetaWindowActor *self,
MetaCompEffect effect);
void meta_window_actor_size_change (MetaWindowActor *self,
MetaSizeChange which_change,
MetaRectangle *old_frame_rect,
MetaRectangle *old_buffer_rect);
void meta_window_actor_maximize (MetaWindowActor *self,
MetaRectangle *old_rect,
MetaRectangle *new_rect);
void meta_window_actor_unmaximize (MetaWindowActor *self,
MetaRectangle *old_rect,
MetaRectangle *new_rect);
void meta_window_actor_process_x11_damage (MetaWindowActor *self,
XDamageNotifyEvent *event);
@@ -54,8 +55,8 @@ void meta_window_actor_sync_updates_frozen (MetaWindowActor *self);
void meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
gboolean no_delay_frame);
void meta_window_actor_effect_completed (MetaWindowActor *actor,
MetaPluginEffect event);
void meta_window_actor_effect_completed (MetaWindowActor *actor,
gulong event);
MetaSurfaceActor *meta_window_actor_get_surface (MetaWindowActor *self);
void meta_window_actor_update_surface (MetaWindowActor *self);

View File

@@ -20,11 +20,10 @@
#include "frame.h"
#include <meta/window.h>
#include <meta/meta-shaped-texture.h>
#include <meta/meta-enum-types.h>
#include <meta/meta-shadow-factory.h>
#include "compositor-private.h"
#include "meta-shaped-texture-private.h"
#include "meta-shadow-factory-private.h"
#include "meta-window-actor-private.h"
#include "meta-texture-rectangle.h"
#include "region-utils.h"
@@ -75,8 +74,6 @@ struct _MetaWindowActorPrivate
MetaWindowShape *shadow_shape;
char * shadow_class;
MetaShadowMode shadow_mode;
guint send_frame_messages_timer;
gint64 frame_drawn_time;
@@ -90,7 +87,8 @@ struct _MetaWindowActorPrivate
*/
gint minimize_in_progress;
gint unminimize_in_progress;
gint size_change_in_progress;
gint maximize_in_progress;
gint unmaximize_in_progress;
gint map_in_progress;
gint destroy_in_progress;
@@ -112,6 +110,8 @@ struct _MetaWindowActorPrivate
guint needs_destroy : 1;
guint no_shadow : 1;
guint updates_frozen : 1;
guint first_frame_state : 2; /* FirstFrameState */
};
@@ -147,7 +147,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
enum
{
PROP_META_WINDOW = 1,
PROP_SHADOW_MODE,
PROP_NO_SHADOW,
PROP_SHADOW_CLASS
};
@@ -245,15 +245,14 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
PROP_META_WINDOW,
pspec);
pspec = g_param_spec_enum ("shadow-mode",
"Shadow mode",
"Decides when to paint shadows",
META_TYPE_SHADOW_MODE,
META_SHADOW_MODE_AUTO,
G_PARAM_READWRITE);
pspec = g_param_spec_boolean ("no-shadow",
"No shadow",
"Do not add shaddow to this window",
FALSE,
G_PARAM_READWRITE);
g_object_class_install_property (object_class,
PROP_SHADOW_MODE,
PROP_NO_SHADOW,
pspec);
pspec = g_param_spec_string ("shadow-class",
@@ -511,14 +510,14 @@ meta_window_actor_set_property (GObject *object,
g_signal_connect_object (priv->window, "notify::appears-focused",
G_CALLBACK (window_appears_focused_notify), self, 0);
break;
case PROP_SHADOW_MODE:
case PROP_NO_SHADOW:
{
MetaShadowMode newv = g_value_get_enum (value);
gboolean newv = g_value_get_boolean (value);
if (newv == priv->shadow_mode)
if (newv == priv->no_shadow)
return;
priv->shadow_mode = newv;
priv->no_shadow = newv;
meta_window_actor_invalidate_shadow (self);
}
@@ -555,8 +554,8 @@ meta_window_actor_get_property (GObject *object,
case PROP_META_WINDOW:
g_value_set_object (value, priv->window);
break;
case PROP_SHADOW_MODE:
g_value_set_enum (value, priv->shadow_mode);
case PROP_NO_SHADOW:
g_value_set_boolean (value, priv->no_shadow);
break;
case PROP_SHADOW_CLASS:
g_value_set_string (value, priv->shadow_class);
@@ -616,10 +615,8 @@ meta_window_actor_get_shape_bounds (MetaWindowActor *self,
#ifdef HAVE_WAYLAND
if (META_IS_SURFACE_ACTOR_WAYLAND (priv->surface))
{
MetaSurfaceActorWayland *surface_actor =
META_SURFACE_ACTOR_WAYLAND (priv->surface);
double scale = meta_surface_actor_wayland_get_scale (surface_actor);
double scale = priv->surface ?
meta_surface_actor_wayland_get_scale (META_SURFACE_ACTOR_WAYLAND (priv->surface)) : 1.;
bounds->x *= scale;
bounds->y *= scale;
bounds->width *= scale;
@@ -805,10 +802,8 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
{
MetaWindowActorPrivate *priv = self->priv;
if (priv->shadow_mode == META_SHADOW_MODE_FORCED_OFF)
if (priv->no_shadow)
return FALSE;
if (priv->shadow_mode == META_SHADOW_MODE_FORCED_ON)
return TRUE;
/* Leaving out shadows for maximized and fullscreen windows is an effeciency
* win and also prevents the unsightly effect of the shadow of maximized
@@ -832,23 +827,21 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
return TRUE;
/*
* Do not add shadows to non-opaque (ARGB32) windows, as we can't easily
* generate shadows for them.
* Do not add shadows to non-opaque windows; eventually we should generate
* a shadow from the input shape for such windows.
*/
if (is_non_opaque (self))
return FALSE;
/*
* If a window specifies that it has custom frame extents, that likely
* means that it is drawing a shadow itself. Don't draw our own.
* Add shadows to override redirect windows on X11 unless the toolkit
* indicates that it is handling shadows itself (e.g., Gtk menus).
*/
if (priv->window->has_custom_frame_extents)
return FALSE;
if (priv->window->override_redirect &&
!priv->window->has_custom_frame_extents)
return TRUE;
/*
* Generate shadows for all other windows.
*/
return TRUE;
return FALSE;
}
/**
@@ -1043,18 +1036,20 @@ gboolean
meta_window_actor_effect_in_progress (MetaWindowActor *self)
{
return (self->priv->minimize_in_progress ||
self->priv->size_change_in_progress ||
self->priv->maximize_in_progress ||
self->priv->unmaximize_in_progress ||
self->priv->map_in_progress ||
self->priv->destroy_in_progress);
}
static gboolean
is_freeze_thaw_effect (MetaPluginEffect event)
is_freeze_thaw_effect (gulong event)
{
switch (event)
{
case META_PLUGIN_DESTROY:
case META_PLUGIN_SIZE_CHANGE:
case META_PLUGIN_MAXIMIZE:
case META_PLUGIN_UNMAXIMIZE:
return TRUE;
break;
default:
@@ -1063,8 +1058,8 @@ is_freeze_thaw_effect (MetaPluginEffect event)
}
static gboolean
start_simple_effect (MetaWindowActor *self,
MetaPluginEffect event)
start_simple_effect (MetaWindowActor *self,
gulong event)
{
MetaWindowActorPrivate *priv = self->priv;
MetaCompositor *compositor = priv->compositor;
@@ -1073,8 +1068,6 @@ start_simple_effect (MetaWindowActor *self,
switch (event)
{
case META_PLUGIN_NONE:
return FALSE;
case META_PLUGIN_MINIMIZE:
counter = &priv->minimize_in_progress;
break;
@@ -1087,7 +1080,8 @@ start_simple_effect (MetaWindowActor *self,
case META_PLUGIN_DESTROY:
counter = &priv->destroy_in_progress;
break;
case META_PLUGIN_SIZE_CHANGE:
case META_PLUGIN_UNMAXIMIZE:
case META_PLUGIN_MAXIMIZE:
case META_PLUGIN_SWITCH_WORKSPACE:
g_assert_not_reached ();
break;
@@ -1129,8 +1123,8 @@ meta_window_actor_after_effects (MetaWindowActor *self)
}
void
meta_window_actor_effect_completed (MetaWindowActor *self,
MetaPluginEffect event)
meta_window_actor_effect_completed (MetaWindowActor *self,
gulong event)
{
MetaWindowActorPrivate *priv = self->priv;
@@ -1140,8 +1134,6 @@ meta_window_actor_effect_completed (MetaWindowActor *self,
switch (event)
{
case META_PLUGIN_NONE:
break;
case META_PLUGIN_MINIMIZE:
{
priv->minimize_in_progress--;
@@ -1184,12 +1176,20 @@ meta_window_actor_effect_completed (MetaWindowActor *self,
priv->destroy_in_progress = 0;
}
break;
case META_PLUGIN_SIZE_CHANGE:
priv->size_change_in_progress--;
if (priv->size_change_in_progress < 0)
case META_PLUGIN_UNMAXIMIZE:
priv->unmaximize_in_progress--;
if (priv->unmaximize_in_progress < 0)
{
g_warning ("Error in size change accounting.");
priv->size_change_in_progress = 0;
g_warning ("Error in unmaximize accounting.");
priv->unmaximize_in_progress = 0;
}
break;
case META_PLUGIN_MAXIMIZE:
priv->maximize_in_progress--;
if (priv->maximize_in_progress < 0)
{
g_warning ("Error in maximize accounting.");
priv->maximize_in_progress = 0;
}
break;
case META_PLUGIN_SWITCH_WORKSPACE:
@@ -1300,7 +1300,7 @@ meta_window_actor_show (MetaWindowActor *self,
{
MetaWindowActorPrivate *priv = self->priv;
MetaCompositor *compositor = priv->compositor;
MetaPluginEffect event;
gulong event = 0;
g_return_if_fail (!priv->visible);
@@ -1315,13 +1315,14 @@ meta_window_actor_show (MetaWindowActor *self,
event = META_PLUGIN_UNMINIMIZE;
break;
case META_COMP_EFFECT_NONE:
event = META_PLUGIN_NONE;
break;
default:
case META_COMP_EFFECT_DESTROY:
case META_COMP_EFFECT_MINIMIZE:
g_assert_not_reached();
}
if (compositor->switch_workspace_in_progress ||
event == 0 ||
!start_simple_effect (self, event))
{
clutter_actor_show (CLUTTER_ACTOR (self));
@@ -1334,7 +1335,7 @@ meta_window_actor_hide (MetaWindowActor *self,
{
MetaWindowActorPrivate *priv = self->priv;
MetaCompositor *compositor = priv->compositor;
MetaPluginEffect event;
gulong event = 0;
g_return_if_fail (priv->visible);
@@ -1356,32 +1357,70 @@ meta_window_actor_hide (MetaWindowActor *self,
event = META_PLUGIN_MINIMIZE;
break;
case META_COMP_EFFECT_NONE:
event = META_PLUGIN_NONE;
break;
default:
case META_COMP_EFFECT_UNMINIMIZE:
case META_COMP_EFFECT_CREATE:
g_assert_not_reached();
}
if (!start_simple_effect (self, event))
if (event == 0 ||
!start_simple_effect (self, event))
clutter_actor_hide (CLUTTER_ACTOR (self));
}
void
meta_window_actor_size_change (MetaWindowActor *self,
MetaSizeChange which_change,
MetaRectangle *old_frame_rect,
MetaRectangle *old_buffer_rect)
meta_window_actor_maximize (MetaWindowActor *self,
MetaRectangle *old_rect,
MetaRectangle *new_rect)
{
MetaWindowActorPrivate *priv = self->priv;
MetaCompositor *compositor = priv->compositor;
self->priv->size_change_in_progress++;
/* The window has already been resized (in order to compute new_rect),
* which by side effect caused the actor to be resized. Restore it to the
* old size and position */
clutter_actor_set_position (CLUTTER_ACTOR (self), old_rect->x, old_rect->y);
clutter_actor_set_size (CLUTTER_ACTOR (self), old_rect->width, old_rect->height);
self->priv->maximize_in_progress++;
meta_window_actor_freeze (self);
if (!meta_plugin_manager_event_size_change (compositor->plugin_mgr, self,
which_change, old_frame_rect, old_buffer_rect))
if (!meta_plugin_manager_event_maximize (compositor->plugin_mgr,
self,
META_PLUGIN_MAXIMIZE,
new_rect->x, new_rect->y,
new_rect->width, new_rect->height))
{
self->priv->size_change_in_progress--;
self->priv->maximize_in_progress--;
meta_window_actor_thaw (self);
}
}
void
meta_window_actor_unmaximize (MetaWindowActor *self,
MetaRectangle *old_rect,
MetaRectangle *new_rect)
{
MetaWindowActorPrivate *priv = self->priv;
MetaCompositor *compositor = priv->compositor;
/* The window has already been resized (in order to compute new_rect),
* which by side effect caused the actor to be resized. Restore it to the
* old size and position */
clutter_actor_set_position (CLUTTER_ACTOR (self), old_rect->x, old_rect->y);
clutter_actor_set_size (CLUTTER_ACTOR (self), old_rect->width, old_rect->height);
self->priv->unmaximize_in_progress++;
meta_window_actor_freeze (self);
if (!meta_plugin_manager_event_maximize (compositor->plugin_mgr,
self,
META_PLUGIN_UNMAXIMIZE,
new_rect->x, new_rect->y,
new_rect->width, new_rect->height))
{
self->priv->unmaximize_in_progress--;
meta_window_actor_thaw (self);
}
}

View File

@@ -58,7 +58,9 @@ meta_window_group_paint (ClutterActor *actor)
cairo_region_t *clip_region;
cairo_region_t *unobscured_region;
cairo_rectangle_int_t visible_rect, clip_rect;
int paint_x_offset, paint_y_offset;
int paint_x_origin, paint_y_origin;
int actor_x_origin, actor_y_origin;
int screen_width, screen_height;
MetaWindowGroup *window_group = META_WINDOW_GROUP (actor);
@@ -80,7 +82,7 @@ meta_window_group_paint (ClutterActor *actor)
* on the stage.
*/
if (!meta_actor_painting_untransformed (screen_width, screen_height, &paint_x_origin, &paint_y_origin) ||
!meta_actor_is_untransformed (actor, NULL, NULL))
!meta_actor_is_untransformed (actor, &actor_x_origin, &actor_y_origin))
{
CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor);
return;
@@ -103,7 +105,9 @@ meta_window_group_paint (ClutterActor *actor)
clip_region = cairo_region_create_rectangle (&clip_rect);
cairo_region_translate (clip_region, -paint_x_origin, -paint_y_origin);
paint_x_offset = paint_x_origin - actor_x_origin;
paint_y_offset = paint_y_origin - actor_y_origin;
cairo_region_translate (clip_region, -paint_x_offset, -paint_y_offset);
meta_cullable_cull_out (META_CULLABLE (window_group), unobscured_region, clip_region);
@@ -141,36 +145,6 @@ meta_window_group_get_paint_volume (ClutterActor *self,
return TRUE;
}
/* This is a workaround for Clutter's awful allocation tracking.
* Without this, any time the window group changed size, which is
* any time windows are dragged around, we'll do a full repaint
* of the window group, which includes the background actor, meaning
* a full-stage repaint.
*
* Since actors are allowed to paint outside their allocation, and
* since child actors are allowed to be outside their parents, this
* doesn't affect anything, but it means that we'll get much more
* sane and consistent clipped repaints from Clutter. */
static void
meta_window_group_get_preferred_width (ClutterActor *actor,
gfloat for_height,
gfloat *min_width,
gfloat *nat_width)
{
*min_width = 0;
*nat_width = 0;
}
static void
meta_window_group_get_preferred_height (ClutterActor *actor,
gfloat for_width,
gfloat *min_height,
gfloat *nat_height)
{
*min_height = 0;
*nat_height = 0;
}
static void
meta_window_group_class_init (MetaWindowGroupClass *klass)
{
@@ -178,8 +152,6 @@ meta_window_group_class_init (MetaWindowGroupClass *klass)
actor_class->paint = meta_window_group_paint;
actor_class->get_paint_volume = meta_window_group_get_paint_volume;
actor_class->get_preferred_width = meta_window_group_get_preferred_width;
actor_class->get_preferred_height = meta_window_group_get_preferred_height;
}
static void

View File

@@ -1,5 +1,4 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* MetaWindowShape
*
@@ -20,12 +19,9 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <meta/meta-window-shape.h>
#include <string.h>
#include "meta-window-shape.h"
#include "region-utils.h"
struct _MetaWindowShape
@@ -254,5 +250,3 @@ meta_window_shape_to_region (MetaWindowShape *shape,
return region;
}
G_DEFINE_BOXED_TYPE (MetaWindowShape, meta_window_shape,
meta_window_shape_ref, meta_window_shape_unref)

View File

@@ -24,9 +24,7 @@
#define __META_WINDOW_SHAPE_H__
#include <cairo.h>
#include <glib-object.h>
GType meta_window_shape_get_type (void) G_GNUC_CONST;
#include <glib.h>
/**
* MetaWindowShape:

View File

@@ -689,7 +689,7 @@ show_tile_preview (MetaPlugin *plugin,
ScreenTilePreview *preview = get_screen_tile_preview (screen);
ClutterActor *window_actor;
if (clutter_actor_is_visible (preview->actor)
if (CLUTTER_ACTOR_IS_VISIBLE (preview->actor)
&& preview->tile_rect.x == tile_rect->x
&& preview->tile_rect.y == tile_rect->y
&& preview->tile_rect.width == tile_rect->width

View File

@@ -493,10 +493,11 @@ place_window_if_needed(MetaWindow *window,
if (window->placed || did_placement)
{
if (window->maximize_horizontally_after_placement ||
window->maximize_vertically_after_placement)
window->maximize_vertically_after_placement ||
window->fullscreen_after_placement)
{
/* define a sane saved_rect so that the user can unmaximize to
* something reasonable.
/* define a sane saved_rect so that the user can unmaximize or
* make unfullscreen to something reasonable.
*/
if (info->current.width >= info->work_area_monitor.width)
{
@@ -524,6 +525,15 @@ place_window_if_needed(MetaWindow *window,
(window->maximize_vertically_after_placement ?
META_MAXIMIZE_VERTICAL : 0), &info->current);
if (window->fullscreen_after_placement)
{
window->saved_rect = info->current;
window->fullscreen = TRUE;
window->fullscreen_after_placement = FALSE;
g_object_notify (G_OBJECT (window), "fullscreen");
}
window->maximize_horizontally_after_placement = FALSE;
window->maximize_vertically_after_placement = FALSE;
}

View File

@@ -172,6 +172,18 @@ meta_core_toggle_maximize (Display *xdisplay,
meta_window_maximize (window, META_MAXIMIZE_BOTH);
}
void
meta_core_change_workspace (Display *xdisplay,
Window frame_xwindow,
int new_workspace)
{
MetaWindow *window = get_window (xdisplay, frame_xwindow);
meta_window_change_workspace (window,
meta_screen_get_workspace_by_index (window->screen,
new_workspace));
}
void
meta_core_show_window_menu (Display *xdisplay,
Window frame_xwindow,
@@ -205,6 +217,19 @@ meta_core_show_window_menu_for_rect (Display *xdisplay,
meta_window_show_menu_for_rect (window, menu, rect);
}
const char*
meta_core_get_workspace_name_with_index (Display *xdisplay,
Window xroot,
int index)
{
MetaDisplay *display;
MetaWorkspace *workspace;
display = meta_display_for_x_display (xdisplay);
workspace = meta_screen_get_workspace_by_index (display->screen, index);
return workspace ? meta_workspace_get_name (workspace) : NULL;
}
gboolean
meta_core_begin_grab_op (Display *xdisplay,
Window frame_xwindow,

View File

@@ -41,6 +41,15 @@ void meta_core_toggle_maximize_horizontally (Display *xdisplay,
Window frame_xwindow);
void meta_core_toggle_maximize_vertically (Display *xdisplay,
Window frame_xwindow);
void meta_core_change_workspace (Display *xdisplay,
Window frame_xwindow,
int new_workspace);
int meta_core_get_frame_workspace (Display *xdisplay,
Window frame_xwindow);
const char* meta_core_get_workspace_name_with_index (Display *xdisplay,
Window xroot,
int index);
void meta_core_show_window_menu (Display *xdisplay,
Window frame_xwindow,

View File

@@ -160,7 +160,12 @@ void
meta_window_set_alive (MetaWindow *window,
gboolean is_alive)
{
if (is_alive)
if (window->is_alive == is_alive)
return;
window->is_alive = is_alive;
if (window->is_alive)
kill_delete_dialog (window);
else
show_delete_dialog (window, CurrentTime);
@@ -180,6 +185,34 @@ meta_window_delete (MetaWindow *window,
META_WINDOW_GET_CLASS (window)->delete (window, timestamp);
meta_window_check_alive (window, timestamp);
if (window->has_focus)
{
/* FIXME Clean this up someday
* http://bugzilla.gnome.org/show_bug.cgi?id=108706
*/
#if 0
/* This is unfortunately going to result in weirdness
* if the window doesn't respond to the delete event.
* I don't know how to avoid that though.
*/
meta_topic (META_DEBUG_FOCUS,
"Focusing default window because focus window %s was deleted/killed\n",
window->desc);
meta_workspace_focus_default_window (window->screen->active_workspace,
window);
#else
meta_topic (META_DEBUG_FOCUS,
"Not unfocusing %s on delete/kill\n",
window->desc);
#endif
}
else
{
meta_topic (META_DEBUG_FOCUS,
"Window %s was deleted/killed but didn't have focus\n",
window->desc);
}
}
void

View File

@@ -121,7 +121,7 @@ struct _MetaDisplay
* class is constructed.
*/
#define item(x) Atom atom_##x;
#include <x11/atomnames.h>
#include <meta/atomnames.h>
#undef item
/* The window and serial of the most recent FocusIn event. */
@@ -217,6 +217,9 @@ struct _MetaDisplay
guint grab_have_pointer : 1;
guint grab_have_keyboard : 1;
guint grab_frame_action : 1;
/* During a resize operation, the directions in which we've broken
* out of the initial maximization state */
guint grab_resize_unmaximize : 2; /* MetaMaximizeFlags */
MetaRectangle grab_initial_window_pos;
int grab_initial_x, grab_initial_y; /* These are only relevant for */
gboolean grab_threshold_movement_reached; /* raise_on_click == FALSE. */

View File

@@ -46,7 +46,7 @@
#include <meta/compositor.h>
#include <meta/compositor-mutter.h>
#include <X11/Xatom.h>
#include <meta/meta-enum-types.h>
#include "mutter-enum-types.h"
#include "meta-idle-monitor-dbus.h"
#include "meta-cursor-tracker-private.h"
#include <meta/meta-backend.h>
@@ -547,9 +547,9 @@ meta_display_open (void)
guint32 timestamp;
/* A list of all atom names, so that we can intern them in one go. */
const char *atom_names[] = {
char *atom_names[] = {
#define item(x) #x,
#include <x11/atomnames.h>
#include <meta/atomnames.h>
#undef item
};
Atom atoms[G_N_ELEMENTS(atom_names)];
@@ -605,13 +605,14 @@ meta_display_open (void)
meta_prefs_add_listener (prefs_changed_callback, display);
meta_verbose ("Creating %d atoms\n", (int) G_N_ELEMENTS (atom_names));
XInternAtoms (display->xdisplay, (char **)atom_names, G_N_ELEMENTS (atom_names),
XInternAtoms (display->xdisplay, atom_names, G_N_ELEMENTS (atom_names),
False, atoms);
i = 0;
{
int i = 0;
#define item(x) display->atom_##x = atoms[i++];
#include <x11/atomnames.h>
#include <meta/atomnames.h>
#undef item
}
display->prop_hooks = NULL;
meta_display_init_window_prop_hooks (display);
@@ -1921,6 +1922,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
display->grab_last_moveresize_time.tv_usec = 0;
display->grab_last_user_action_was_snap = FALSE;
display->grab_frame_action = frame_action;
display->grab_resize_unmaximize = 0;
meta_display_update_cursor (display);
@@ -1963,12 +1965,9 @@ meta_display_end_grab_op (MetaDisplay *display,
meta_topic (META_DEBUG_WINDOW_OPS,
"Ending grab op %u at time %u\n", grab_op, timestamp);
if (display->event_route == META_EVENT_ROUTE_NORMAL ||
display->event_route == META_EVENT_ROUTE_COMPOSITOR_GRAB)
if (display->event_route == META_EVENT_ROUTE_NORMAL)
return;
g_assert (grab_window != NULL);
g_signal_emit (display, display_signals[GRAB_OP_END], 0,
display->screen, grab_window, grab_op);

View File

@@ -40,13 +40,6 @@
#endif
#include "meta-surface-actor.h"
#define IS_GESTURE_EVENT(e) ((e)->type == CLUTTER_TOUCHPAD_SWIPE || \
(e)->type == CLUTTER_TOUCHPAD_PINCH || \
(e)->type == CLUTTER_TOUCH_BEGIN || \
(e)->type == CLUTTER_TOUCH_UPDATE || \
(e)->type == CLUTTER_TOUCH_END || \
(e)->type == CLUTTER_TOUCH_CANCEL)
static MetaWindow *
get_window_for_event (MetaDisplay *display,
const ClutterEvent *event)
@@ -100,15 +93,6 @@ handle_idletime_for_event (const ClutterEvent *event)
if (device == NULL)
return;
if (event->any.flags & CLUTTER_EVENT_FLAG_SYNTHETIC ||
event->type == CLUTTER_ENTER ||
event->type == CLUTTER_LEAVE ||
event->type == CLUTTER_STAGE_STATE ||
event->type == CLUTTER_DESTROY_NOTIFY ||
event->type == CLUTTER_CLIENT_MESSAGE ||
event->type == CLUTTER_DELETE)
return;
device_id = clutter_input_device_get_device_id (device);
core_monitor = meta_idle_monitor_get_core ();
@@ -206,9 +190,8 @@ meta_display_handle_event (MetaDisplay *display,
if (meta_is_wayland_compositor () && event->type == CLUTTER_MOTION)
{
meta_cursor_tracker_update_position (meta_cursor_tracker_get_for_screen (NULL),
event->motion.x, event->motion.y);
display->monitor_cache_invalidated = TRUE;
MetaCursorTracker *tracker = meta_cursor_tracker_get_for_screen (NULL);
meta_cursor_tracker_update_position (tracker, event->motion.x, event->motion.y);
}
handle_idletime_for_event (event);
@@ -272,18 +255,15 @@ meta_display_handle_event (MetaDisplay *display,
if (window)
{
/* Events that are likely to trigger compositor gestures should
* be known to clutter so they can propagate along the hierarchy.
* Gesture-wise, there's two groups of events we should be getting
* here:
* - CLUTTER_TOUCH_* with a touch sequence that's not yet accepted
* by the gesture tracker, these might trigger gesture actions
* into recognition. Already accepted touch sequences are handled
* directly by meta_gesture_tracker_handle_event().
* - CLUTTER_TOUCHPAD_* events over windows. These can likewise
* trigger ::captured-event handlers along the way.
*/
bypass_clutter = !IS_GESTURE_EVENT (event);
if (!clutter_event_get_event_sequence (event))
{
/* Swallow all non-touch events on windows that come our way.
* Touch events that reach here aren't yet in an accepted state,
* so Clutter must see them to maybe trigger gestures into
* recognition.
*/
bypass_clutter = TRUE;
}
meta_window_handle_ungrabbed_event (window, event);

View File

@@ -30,7 +30,6 @@
#include <gio/gio.h>
#include <meta/keybindings.h>
#include <xkbcommon/xkbcommon.h>
#include "meta-accel-parse.h"
typedef struct _MetaKeyHandler MetaKeyHandler;
struct _MetaKeyHandler
@@ -54,6 +53,7 @@ typedef struct _MetaResolvedKeyCombo {
* @keycode: keycode
* @modifiers: modifiers
*/
typedef struct _MetaKeyCombo MetaKeyCombo;
struct _MetaKeyCombo
{
unsigned int keysym;

View File

@@ -188,7 +188,7 @@ reload_modmap (MetaKeyBindingManager *keys)
/* Modifiers to find. */
struct {
const char *name;
char *name;
xkb_mod_mask_t *mask_p;
} mods[] = {
{ "ScrollLock", &scroll_lock_mask },
@@ -3186,7 +3186,7 @@ handle_move_to_monitor (MetaDisplay *display,
gint which = binding->handler->data;
const MetaMonitorInfo *current, *new;
current = window->monitor;
current = meta_screen_get_monitor_for_window (screen, window);
new = meta_screen_get_monitor_neighbor (screen, current->number, which);
if (new == NULL)

View File

@@ -176,6 +176,7 @@ static gboolean
accelerator_parse (const gchar *accelerator,
MetaKeyCombo *combo)
{
gboolean error = FALSE;
guint keyval, keycode;
MetaVirtualModifier mods;
gint len;
@@ -185,7 +186,10 @@ accelerator_parse (const gchar *accelerator,
combo->modifiers = 0;
if (accelerator == NULL)
return FALSE;
{
error = TRUE;
goto out;
}
keyval = 0;
keycode = 0;
@@ -306,7 +310,10 @@ accelerator_parse (const gchar *accelerator,
g_free (with_xf86);
if (keyval == XKB_KEY_NoSymbol)
return FALSE;
{
error = TRUE;
goto out;
}
}
}
@@ -315,10 +322,14 @@ accelerator_parse (const gchar *accelerator,
}
}
out:
out:
if (error)
return FALSE;
combo->keysym = keyval;
combo->keycode = keycode;
combo->modifiers = mods;
return TRUE;
}

View File

@@ -44,7 +44,7 @@ print_version (const gchar *option_name,
exit (0);
}
static const char *plugin = "default";
static gchar *plugin = "default";
GOptionEntry mutter_options[] = {
{

View File

@@ -96,10 +96,6 @@ static gboolean bell_is_audible = TRUE;
static gboolean gnome_accessibility = FALSE;
static gboolean gnome_animations = TRUE;
static char *cursor_theme = NULL;
/* cursor_size will, when running as an X11 compositing window manager, be the
* actual cursor size, multiplied with the global window scaling factor. On
* Wayland, it will be the actual cursor size retrieved from gsettings.
*/
static int cursor_size = 24;
static int draggable_border_width = 10;
static int drag_threshold;
@@ -127,9 +123,6 @@ static gboolean update_binding (MetaKeyPref *binding,
static gboolean update_key_binding (const char *key,
gchar **strokes);
static void wayland_settings_changed (GSettings *settings,
gchar *key,
gpointer data);
static void settings_changed (GSettings *settings,
gchar *key,
gpointer data);
@@ -141,10 +134,9 @@ static void shell_shows_app_menu_changed (GtkSettings *settings,
GParamSpec *pspec,
gpointer data);
static void update_cursor_size_from_gtk (GtkSettings *settings,
GParamSpec *pspec,
gpointer data);
static void update_cursor_size (void);
static void update_cursor_size (GtkSettings *settings,
GParamSpec *pspec,
gpointer data);
static void queue_changed (MetaPreference pref);
@@ -169,8 +161,8 @@ typedef struct
typedef struct
{
const char *key;
const char *schema;
char *key;
char *schema;
MetaPreference pref;
} MetaBasePreference;
@@ -971,18 +963,14 @@ meta_prefs_init (void)
G_CALLBACK (settings_changed), NULL);
g_signal_connect (settings, "changed::" KEY_GNOME_CURSOR_THEME,
G_CALLBACK (settings_changed), NULL);
if (meta_is_wayland_compositor ())
g_signal_connect (settings, "changed::cursor-size",
G_CALLBACK (wayland_settings_changed), NULL);
g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_INTERFACE), settings);
g_signal_connect (gtk_settings_get_default (),
"notify::gtk-shell-shows-app-menu",
G_CALLBACK (shell_shows_app_menu_changed), NULL);
if (!meta_is_wayland_compositor ())
g_signal_connect (gtk_settings_get_default (), "notify::gtk-cursor-theme-size",
G_CALLBACK (update_cursor_size_from_gtk), NULL);
g_signal_connect (gtk_settings_get_default (), "notify::gtk-cursor-theme-size",
G_CALLBACK (update_cursor_size), NULL);
settings = g_settings_new (SCHEMA_INPUT_SOURCES);
g_signal_connect (settings, "changed::" KEY_XKB_OPTIONS,
@@ -1004,7 +992,7 @@ meta_prefs_init (void)
handle_preference_init_string_array ();
handle_preference_init_int ();
update_cursor_size ();
update_cursor_size (gtk_settings_get_default (), NULL, NULL);
shell_shows_app_menu_changed (gtk_settings_get_default (), NULL, NULL);
init_bindings ();
@@ -1145,20 +1133,6 @@ meta_prefs_override_preference_schema (const char *key, const char *schema)
/****************************************************************************/
static void
wayland_settings_changed (GSettings *settings,
gchar *key,
gpointer data)
{
GVariant *value = g_settings_get_value (settings, key);
const GVariantType *type = g_variant_get_type (value);
g_return_if_fail (g_variant_type_equal (type, G_VARIANT_TYPE_INT32));
g_return_if_fail (g_str_equal (key, "cursor-size"));
update_cursor_size ();
}
static void
settings_changed (GSettings *settings,
gchar *key,
@@ -1242,29 +1216,9 @@ shell_shows_app_menu_changed (GtkSettings *settings,
}
static void
update_cursor_size (void)
{
if (meta_is_wayland_compositor ())
{
/* When running as a Wayland compositor, since we size of the cursor
* depends on what output it is on, we cannot use the GTK+
* "gtk-cursor-theme-size" setting because it has already been multiplied
* by the primary monitor scale. So, instead get the non-premultiplied
* cursor size value directly from gsettings instead.
*/
cursor_size =
g_settings_get_int (SETTINGS (SCHEMA_INTERFACE), "cursor-size");
}
else
{
update_cursor_size_from_gtk (gtk_settings_get_default (), NULL, NULL);
}
}
static void
update_cursor_size_from_gtk (GtkSettings *settings,
GParamSpec *pspec,
gpointer data)
update_cursor_size (GtkSettings *settings,
GParamSpec *pspec,
gpointer data)
{
GdkScreen *screen = gdk_screen_get_default ();
GValue value = G_VALUE_INIT;
@@ -1477,11 +1431,42 @@ button_function_from_string (const char *str)
return META_BUTTON_FUNCTION_MAXIMIZE;
else if (strcmp (str, "close") == 0)
return META_BUTTON_FUNCTION_CLOSE;
else if (strcmp (str, "shade") == 0)
return META_BUTTON_FUNCTION_SHADE;
else if (strcmp (str, "above") == 0)
return META_BUTTON_FUNCTION_ABOVE;
else if (strcmp (str, "stick") == 0)
return META_BUTTON_FUNCTION_STICK;
else
/* don't know; give up */
return META_BUTTON_FUNCTION_LAST;
}
static MetaButtonFunction
button_opposite_function (MetaButtonFunction ofwhat)
{
switch (ofwhat)
{
case META_BUTTON_FUNCTION_SHADE:
return META_BUTTON_FUNCTION_UNSHADE;
case META_BUTTON_FUNCTION_UNSHADE:
return META_BUTTON_FUNCTION_SHADE;
case META_BUTTON_FUNCTION_ABOVE:
return META_BUTTON_FUNCTION_UNABOVE;
case META_BUTTON_FUNCTION_UNABOVE:
return META_BUTTON_FUNCTION_ABOVE;
case META_BUTTON_FUNCTION_STICK:
return META_BUTTON_FUNCTION_UNSTICK;
case META_BUTTON_FUNCTION_UNSTICK:
return META_BUTTON_FUNCTION_STICK;
default:
return META_BUTTON_FUNCTION_LAST;
}
}
static gboolean
button_layout_handler (GVariant *value,
gpointer *result,
@@ -1525,6 +1510,12 @@ button_layout_handler (GVariant *value,
if (i > 0 && strcmp("spacer", buttons[b]) == 0)
{
new_layout.left_buttons_has_spacer[i-1] = TRUE;
f = button_opposite_function (f);
if (f != META_BUTTON_FUNCTION_LAST)
{
new_layout.left_buttons_has_spacer[i-2] = TRUE;
}
}
else
{
@@ -1533,6 +1524,11 @@ button_layout_handler (GVariant *value,
new_layout.left_buttons[i] = f;
used[f] = TRUE;
++i;
f = button_opposite_function (f);
if (f != META_BUTTON_FUNCTION_LAST)
new_layout.left_buttons[i++] = f;
}
else
{
@@ -1576,6 +1572,11 @@ button_layout_handler (GVariant *value,
if (i > 0 && strcmp("spacer", buttons[b]) == 0)
{
new_layout.right_buttons_has_spacer[i-1] = TRUE;
f = button_opposite_function (f);
if (f != META_BUTTON_FUNCTION_LAST)
{
new_layout.right_buttons_has_spacer[i-2] = TRUE;
}
}
else
{
@@ -1584,6 +1585,12 @@ button_layout_handler (GVariant *value,
new_layout.right_buttons[i] = f;
used[f] = TRUE;
++i;
f = button_opposite_function (f);
if (f != META_BUTTON_FUNCTION_LAST)
new_layout.right_buttons[i++] = f;
}
else
{

View File

@@ -41,6 +41,14 @@
typedef void (* MetaScreenWindowFunc) (MetaWindow *window,
gpointer user_data);
typedef enum
{
META_SCREEN_UP,
META_SCREEN_DOWN,
META_SCREEN_LEFT,
META_SCREEN_RIGHT
} MetaScreenDirection;
#define META_WIREFRAME_XOR_LINE_WIDTH 2
struct _MetaScreen
@@ -149,12 +157,8 @@ const MetaMonitorInfo* meta_screen_get_current_monitor_info_for_pos (MetaScree
int y);
const MetaMonitorInfo* meta_screen_get_monitor_for_rect (MetaScreen *screen,
MetaRectangle *rect);
const MetaMonitorInfo* meta_screen_calculate_monitor_for_window (MetaScreen *screen,
MetaWindow *window);
const MetaMonitorInfo* meta_screen_get_monitor_for_point (MetaScreen *screen,
int x,
int y);
const MetaMonitorInfo* meta_screen_get_monitor_for_window (MetaScreen *screen,
MetaWindow *window);
const MetaMonitorInfo* meta_screen_get_monitor_neighbor (MetaScreen *screen,

View File

@@ -40,10 +40,9 @@
#include "keybindings-private.h"
#include "stack.h"
#include <meta/compositor.h>
#include <meta/meta-enum-types.h>
#include "mutter-enum-types.h"
#include "core.h"
#include "meta-cursor-tracker-private.h"
#include "boxes-private.h"
#include <X11/extensions/Xinerama.h>
#include <X11/extensions/Xcomposite.h>
@@ -295,7 +294,7 @@ set_supported_hint (MetaScreen *screen)
Atom atoms[] = {
#define EWMH_ATOMS_ONLY
#define item(x) screen->display->atom_##x,
#include <x11/atomnames.h>
#include <meta/atomnames.h>
#undef item
#undef EWMH_ATOMS_ONLY
@@ -751,7 +750,7 @@ void
meta_screen_init_workspaces (MetaScreen *screen)
{
MetaWorkspace *current_workspace;
uint32_t current_workspace_index = 0;
gulong current_workspace_index = 0;
guint32 timestamp;
g_return_if_fail (META_IS_SCREEN (screen));
@@ -1167,7 +1166,7 @@ update_num_workspaces (MetaScreen *screen,
if (meta_prefs_get_dynamic_workspaces ())
{
int n_items;
uint32_t *list;
gulong *list;
n_items = 0;
list = NULL;
@@ -1256,47 +1255,21 @@ update_num_workspaces (MetaScreen *screen,
g_object_notify (G_OBJECT (screen), "n-workspaces");
}
static void
root_cursor_prepare_at (MetaCursorSprite *cursor_sprite,
int x,
int y,
MetaScreen *screen)
{
const MetaMonitorInfo *monitor;
monitor = meta_screen_get_monitor_for_point (screen, x, y);
/* Reload the cursor texture if the scale has changed. */
meta_cursor_sprite_set_theme_scale (cursor_sprite, monitor->scale);
}
static void
manage_root_cursor_sprite_scale (MetaScreen *screen,
MetaCursorSprite *cursor_sprite)
{
g_signal_connect_object (cursor_sprite,
"prepare-at",
G_CALLBACK (root_cursor_prepare_at),
screen,
0);
}
void
meta_screen_update_cursor (MetaScreen *screen)
{
MetaDisplay *display = screen->display;
MetaCursor cursor = screen->current_cursor;
Cursor xcursor;
MetaCursorSprite *cursor_sprite;
MetaCursorReference *cursor_ref;
MetaCursorTracker *tracker = meta_cursor_tracker_get_for_screen (screen);
cursor_sprite = meta_cursor_sprite_from_theme (cursor);
cursor_ref = meta_cursor_reference_from_theme (cursor);
if (cursor_ref == NULL)
meta_fatal ("Could not find cursor. Perhaps set XCURSOR_PATH?");
if (meta_is_wayland_compositor ())
manage_root_cursor_sprite_scale (screen, cursor_sprite);
meta_cursor_tracker_set_root_cursor (tracker, cursor_sprite);
g_object_unref (cursor_sprite);
meta_cursor_tracker_set_root_cursor (tracker, cursor_ref);
meta_cursor_reference_unref (cursor_ref);
/* Set a cursor for X11 applications that don't specify their own */
xcursor = meta_display_create_x_cursor (display, cursor);
@@ -1466,8 +1439,8 @@ meta_screen_get_monitor_for_rect (MetaScreen *screen,
}
const MetaMonitorInfo*
meta_screen_calculate_monitor_for_window (MetaScreen *screen,
MetaWindow *window)
meta_screen_get_monitor_for_window (MetaScreen *screen,
MetaWindow *window)
{
MetaRectangle window_rect;
@@ -1484,25 +1457,6 @@ meta_screen_get_monitor_index_for_rect (MetaScreen *screen,
return monitor->number;
}
const MetaMonitorInfo *
meta_screen_get_monitor_for_point (MetaScreen *screen,
int x,
int y)
{
int i;
if (screen->n_monitor_infos == 1)
return &screen->monitor_infos[0];
for (i = 0; i < screen->n_monitor_infos; i++)
{
if (POINT_IN_RECT (x, y, screen->monitor_infos[i].rect))
return &screen->monitor_infos[i];
}
return NULL;
}
const MetaMonitorInfo*
meta_screen_get_monitor_neighbor (MetaScreen *screen,
int which_monitor,
@@ -1536,16 +1490,6 @@ meta_screen_get_monitor_neighbor (MetaScreen *screen,
return NULL;
}
int
meta_screen_get_monitor_neighbor_index (MetaScreen *screen,
int which_monitor,
MetaScreenDirection direction)
{
const MetaMonitorInfo *monitor;
monitor = meta_screen_get_monitor_neighbor (screen, which_monitor, direction);
return monitor ? monitor->number : -1;
}
void
meta_screen_get_natural_monitor_list (MetaScreen *screen,
int** monitors_list,
@@ -1801,7 +1745,7 @@ meta_screen_get_monitor_geometry (MetaScreen *screen,
void
meta_screen_update_workspace_layout (MetaScreen *screen)
{
uint32_t *list;
gulong *list;
int n_items;
if (screen->workspace_layout_overridden)
@@ -2100,7 +2044,7 @@ meta_screen_queue_workarea_recalc (MetaScreen *screen)
#ifdef WITH_VERBOSE_MODE
static const char *
static char *
meta_screen_corner_to_string (MetaScreenCorner corner)
{
switch (corner)
@@ -2434,12 +2378,12 @@ on_monitors_changed (MetaMonitorManager *manager,
&changes);
}
/* Fix up monitor for all windows on this screen */
meta_screen_foreach_window (screen, META_LIST_INCLUDE_OVERRIDE_REDIRECT, (MetaScreenWindowFunc) meta_window_update_for_monitors_changed, 0);
/* Queue a resize on all the windows */
meta_screen_foreach_window (screen, META_LIST_DEFAULT, meta_screen_resize_func, 0);
/* Fix up monitor for all windows on this screen */
meta_screen_foreach_window (screen, META_LIST_INCLUDE_OVERRIDE_REDIRECT, (MetaScreenWindowFunc) meta_window_update_for_monitors_changed, 0);
meta_screen_queue_check_fullscreen (screen);
g_signal_emit (screen, screen_signals[MONITORS_CHANGED], 0);

View File

@@ -288,7 +288,8 @@ windows_on_different_monitor (MetaWindow *a,
if (a->screen != b->screen)
return TRUE;
return a->monitor != b->monitor;
return meta_screen_get_monitor_for_window (a->screen, a) !=
meta_screen_get_monitor_for_window (b->screen, b);
}
/* Get layer ignoring any transient or group relationships */
@@ -1055,7 +1056,7 @@ stack_sync_to_xserver (MetaStack *stack)
all_root_children_stacked = g_array_new (FALSE, FALSE, sizeof (guint64));
x11_hidden_stack_ids = g_array_new (FALSE, FALSE, sizeof (guint64));
meta_topic (META_DEBUG_STACK, "Bottom to top: ");
meta_topic (META_DEBUG_STACK, "Top to bottom: ");
meta_push_no_msg_prefix ();
for (tmp = g_list_last(stack->sorted); tmp != NULL; tmp = tmp->prev)
@@ -1088,7 +1089,11 @@ stack_sync_to_xserver (MetaStack *stack)
if (w->hidden)
{
if (w->client_type == META_WINDOW_CLIENT_TYPE_X11)
g_array_append_val (x11_hidden_stack_ids, top_level_window);
{
guint64 stack_id = top_level_window;
g_array_append_val (x11_hidden_stack_ids, stack_id);
}
continue;
}
@@ -1234,10 +1239,24 @@ get_default_focus_window (MetaStack *stack,
{
/* Find the topmost, focusable, mapped, window.
* not_this_one is being unfocused or going away, so exclude it.
* Also, prefer to focus transient parent of not_this_one,
* or top window in same group as not_this_one.
*/
MetaWindow *transient_parent;
MetaWindow *topmost_in_group;
MetaWindow *topmost_overall;
MetaGroup *not_this_one_group;
GList *l;
transient_parent = NULL;
topmost_in_group = NULL;
topmost_overall = NULL;
if (not_this_one)
not_this_one_group = meta_window_get_group (not_this_one);
else
not_this_one_group = NULL;
stack_ensure_sorted (stack);
/* top of this layer is at the front of the list */
@@ -1254,25 +1273,49 @@ get_default_focus_window (MetaStack *stack,
if (window->unmaps_pending > 0)
continue;
if (window->minimized)
continue;
if (window->unmanaging)
continue;
if (!(window->input || window->take_focus))
continue;
if (!meta_window_should_be_showing (window))
if (workspace != NULL && !meta_window_located_on_workspace (window, workspace))
continue;
if (must_be_at_point && !window_contains_point (window, root_x, root_y))
continue;
if (window->type == META_WINDOW_DOCK)
continue;
if (not_this_one != NULL)
{
if (transient_parent == NULL &&
meta_window_get_transient_for (not_this_one) == window)
transient_parent = window;
return window;
if (topmost_in_group == NULL &&
not_this_one_group != NULL &&
not_this_one_group == meta_window_get_group (window))
topmost_in_group = window;
}
if (topmost_overall == NULL && window->type != META_WINDOW_DOCK)
topmost_overall = window;
/* We could try to bail out early here for efficiency in
* some cases, but it's just not worth the code.
*/
}
return NULL;
if (transient_parent)
return transient_parent;
else if (topmost_in_group)
return topmost_in_group;
else if (topmost_overall)
return topmost_overall;
else
return NULL;
}
MetaWindow*

View File

@@ -30,7 +30,7 @@
#define NUM_RANDOM_RUNS 10000
static void
init_random_ness (void)
init_random_ness ()
{
srand(time(NULL));
}
@@ -99,7 +99,7 @@ new_monitor_edge (int x, int y, int width, int height, int side_type)
}
static void
test_area (void)
test_area ()
{
MetaRectangle temp;
int i;
@@ -116,7 +116,7 @@ test_area (void)
}
static void
test_intersect (void)
test_intersect ()
{
MetaRectangle a = {100, 200, 50, 40};
MetaRectangle b = { 0, 50, 110, 152};
@@ -144,7 +144,7 @@ test_intersect (void)
}
static void
test_equal (void)
test_equal ()
{
MetaRectangle a = {10, 12, 4, 18};
MetaRectangle b = a;
@@ -163,7 +163,7 @@ test_equal (void)
}
static void
test_overlap_funcs (void)
test_overlap_funcs ()
{
MetaRectangle temp1, temp2;
int i;
@@ -186,7 +186,7 @@ test_overlap_funcs (void)
}
static void
test_basic_fitting (void)
test_basic_fitting ()
{
MetaRectangle temp1, temp2, temp3;
int i;
@@ -357,7 +357,7 @@ get_monitor_edges (int which_monitor_set, int which_strut_set)
#if 0
static void
test_merge_regions (void)
test_merge_regions ()
{
/* logarithmically distributed random number of struts (range?)
* logarithmically distributed random size of struts (up to screen size???)
@@ -579,7 +579,7 @@ verify_lists_are_equal (GList *code, GList *answer)
}
static void
test_regions_okay (void)
test_regions_okay ()
{
GList* region;
GList* tmp;
@@ -665,7 +665,7 @@ test_regions_okay (void)
}
static void
test_region_fitting (void)
test_region_fitting ()
{
GList* region;
MetaRectangle rect;
@@ -709,7 +709,7 @@ test_region_fitting (void)
}
static void
test_clamping_to_region (void)
test_clamping_to_region ()
{
GList* region;
MetaRectangle rect;
@@ -826,7 +826,7 @@ rect_overlaps_region (const GList *spanning_rects,
gboolean time_to_print = FALSE;
static void
test_clipping_to_region (void)
test_clipping_to_region ()
{
GList* region;
MetaRectangle rect, temp;
@@ -888,7 +888,7 @@ test_clipping_to_region (void)
}
static void
test_shoving_into_region (void)
test_shoving_into_region ()
{
GList* region;
MetaRectangle rect, temp;
@@ -1005,7 +1005,7 @@ verify_edge_lists_are_equal (GList *code, GList *answer)
}
static void
test_find_onscreen_edges (void)
test_find_onscreen_edges ()
{
GList* edges;
GList* tmp;
@@ -1138,7 +1138,7 @@ test_find_onscreen_edges (void)
}
static void
test_find_nonintersected_monitor_edges (void)
test_find_nonintersected_monitor_edges ()
{
GList* edges;
GList* tmp;
@@ -1227,7 +1227,7 @@ test_find_nonintersected_monitor_edges (void)
}
static void
test_gravity_resize (void)
test_gravity_resize ()
{
MetaRectangle oldrect, rect, temp;
@@ -1329,7 +1329,7 @@ test_gravity_resize (void)
#define EPSILON 0.000000001
static void
test_find_closest_point_to_line (void)
test_find_closest_point_to_line ()
{
double x1, y1, x2, y2, px, py, rx, ry;
double answer_x, answer_y;
@@ -1381,7 +1381,7 @@ test_find_closest_point_to_line (void)
}
int
main(void)
main()
{
init_random_ness ();
test_area ();

View File

@@ -46,7 +46,7 @@
static void
meta_topic_real_valist (MetaDebugTopic topic,
const char *format,
va_list args) G_GNUC_PRINTF(2, 0);
va_list args);
#endif
static gint verbose_topics = 0;

View File

@@ -78,7 +78,6 @@ typedef enum
META_MOVE_RESIZE_RESIZE_ACTION = 1 << 3,
META_MOVE_RESIZE_WAYLAND_RESIZE = 1 << 4,
META_MOVE_RESIZE_STATE_CHANGED = 1 << 5,
META_MOVE_RESIZE_DONT_SYNC_COMPOSITOR = 1 << 6,
} MetaMoveResizeFlags;
typedef enum
@@ -176,6 +175,9 @@ struct _MetaWindow
/* Whether the window is marked as urgent */
guint urgent : 1;
/* Whether we have to fullscreen after placement */
guint fullscreen_after_placement : 1;
/* Area to cover when in fullscreen mode. If _NET_WM_FULLSCREEN_MONITORS has
* been overridden (via a client message), the window will cover the union of
* these monitors. If not, this is the single monitor which the window's
@@ -432,6 +434,7 @@ struct _MetaWindow
/* Managed by delete.c */
int dialog_pid;
guint is_alive : 1;
/* maintained by group.c */
MetaGroup *group;
@@ -479,7 +482,6 @@ struct _MetaWindowClass
gboolean (*update_icon) (MetaWindow *window,
cairo_surface_t **icon,
cairo_surface_t **mini_icon);
void (*update_main_monitor) (MetaWindow *window);
void (*main_monitor_changed) (MetaWindow *window,
const MetaMonitorInfo *old);
};
@@ -693,6 +695,4 @@ void meta_window_set_alive (MetaWindow *window, gboolean is_alive);
gboolean meta_window_has_pointer (MetaWindow *window);
void meta_window_emit_size_changed (MetaWindow *window);
#endif

View File

@@ -41,7 +41,7 @@
#include <meta/prefs.h>
#include <meta/group.h>
#include "constraints.h"
#include <meta/meta-enum-types.h>
#include "mutter-enum-types.h"
#include "core.h"
#include <X11/Xatom.h>
@@ -57,8 +57,7 @@
#include "x11/xprops.h"
#ifdef HAVE_WAYLAND
#include "wayland/meta-window-wayland.h"
#include "wayland/meta-wayland-surface.h"
#include "wayland/window-wayland.h"
#include "wayland/meta-wayland-private.h"
#endif
@@ -724,12 +723,6 @@ meta_window_should_attach_to_parent (MetaWindow *window)
static gboolean
client_window_should_be_mapped (MetaWindow *window)
{
#ifdef HAVE_WAYLAND
if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND &&
!window->surface->buffer)
return FALSE;
#endif
return !window->shaded;
}
@@ -763,22 +756,10 @@ meta_window_update_desc (MetaWindow *window)
{
g_clear_pointer (&window->desc, g_free);
if (window->client_type == META_WINDOW_CLIENT_TYPE_X11)
{
if (window->title)
window->desc = g_strdup_printf ("0x%lx (%.10s)", window->xwindow, window->title);
else
window->desc = g_strdup_printf ("0x%lx", window->xwindow);
}
if (window->title)
window->desc = g_strdup_printf ("0x%lx (%.10s)", window->xwindow, window->title);
else
{
guint64 small_stamp = window->stamp - G_GUINT64_CONSTANT(0x100000000);
if (window->title)
window->desc = g_strdup_printf ("W%" G_GUINT64_FORMAT " (%.10s)", small_stamp, window->title);
else
window->desc = g_strdup_printf ("W%" G_GUINT64_FORMAT , small_stamp);
}
window->desc = g_strdup_printf ("0x%lx", window->xwindow);
}
static void
@@ -892,6 +873,7 @@ _meta_window_shared_new (MetaDisplay *display,
window->maximize_vertically_after_placement = FALSE;
window->minimize_after_placement = FALSE;
window->fullscreen = FALSE;
window->fullscreen_after_placement = FALSE;
window->fullscreen_monitors[0] = -1;
window->require_fully_onscreen = TRUE;
window->require_on_single_monitor = TRUE;
@@ -992,8 +974,7 @@ _meta_window_shared_new (MetaDisplay *display,
window->compositor_private = NULL;
window->monitor = meta_screen_calculate_monitor_for_window (window->screen,
window);
window->monitor = meta_screen_get_monitor_for_window (window->screen, window);
window->preferred_output_winsys_id = window->monitor->winsys_id;
window->tile_match = NULL;
@@ -1552,12 +1533,6 @@ meta_window_showing_on_its_workspace (MetaWindow *window)
gboolean
meta_window_should_be_showing (MetaWindow *window)
{
#ifdef HAVE_WAYLAND
if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND &&
!window->surface->buffer)
return FALSE;
#endif
/* Windows should be showing if they're located on the
* active workspace and they're showing on their own workspace. */
return (meta_window_located_on_workspace (window, window->screen->active_workspace) &&
@@ -2676,6 +2651,8 @@ meta_window_maximize (MetaWindow *window,
{
MetaRectangle *saved_rect = NULL;
gboolean maximize_horizontally, maximize_vertically;
MetaRectangle old_rect;
MetaRectangle new_rect;
g_return_if_fail (!window->override_redirect);
@@ -2725,23 +2702,18 @@ meta_window_maximize (MetaWindow *window,
directions,
saved_rect);
MetaRectangle old_frame_rect, old_buffer_rect, new_rect;
meta_window_get_frame_rect (window, &old_frame_rect);
meta_window_get_buffer_rect (window, &old_buffer_rect);
meta_window_get_frame_rect (window, &old_rect);
meta_window_move_resize_internal (window,
(META_MOVE_RESIZE_MOVE_ACTION |
META_MOVE_RESIZE_RESIZE_ACTION |
META_MOVE_RESIZE_STATE_CHANGED |
META_MOVE_RESIZE_DONT_SYNC_COMPOSITOR),
META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION | META_MOVE_RESIZE_STATE_CHANGED,
NorthWestGravity,
window->unconstrained_rect);
meta_window_get_frame_rect (window, &new_rect);
meta_compositor_size_change_window (window->display->compositor, window,
META_SIZE_CHANGE_MAXIMIZE,
&old_frame_rect, &old_buffer_rect);
meta_window_get_frame_rect (window, &new_rect);
meta_compositor_maximize_window (window->display->compositor,
window,
&old_rect,
&new_rect);
}
}
@@ -2901,6 +2873,8 @@ void
meta_window_tile (MetaWindow *window)
{
MetaMaximizeFlags directions;
MetaRectangle old_rect;
MetaRectangle new_rect;
/* Don't do anything if no tiling is requested */
if (window->tile_mode == META_TILE_NONE)
@@ -2914,8 +2888,16 @@ meta_window_tile (MetaWindow *window)
meta_window_maximize_internal (window, directions, NULL);
meta_screen_update_tile_preview (window->screen, FALSE);
meta_window_get_frame_rect (window, &old_rect);
meta_window_move_resize_now (window);
meta_window_get_frame_rect (window, &new_rect);
meta_compositor_maximize_window (window->display->compositor,
window,
&old_rect,
&new_rect);
if (window->frame)
meta_frame_queue_draw (window->frame);
}
@@ -2983,9 +2965,11 @@ unmaximize_window_before_freeing (MetaWindow *window)
}
}
void
meta_window_unmaximize (MetaWindow *window,
MetaMaximizeFlags directions)
static void
meta_window_unmaximize_internal (MetaWindow *window,
MetaMaximizeFlags directions,
MetaRectangle *desired_rect,
int gravity)
{
gboolean unmaximize_horizontally, unmaximize_vertically;
MetaRectangle new_rect;
@@ -3006,14 +2990,12 @@ meta_window_unmaximize (MetaWindow *window,
if ((unmaximize_horizontally && window->maximized_horizontally) ||
(unmaximize_vertically && window->maximized_vertically))
{
MetaRectangle *desired_rect;
MetaRectangle target_rect;
MetaRectangle work_area;
MetaRectangle old_frame_rect, old_buffer_rect;
MetaRectangle old_rect;
meta_window_get_work_area_for_monitor (window, window->monitor->number, &work_area);
meta_window_get_frame_rect (window, &old_frame_rect);
meta_window_get_buffer_rect (window, &old_buffer_rect);
meta_window_get_frame_rect (window, &old_rect);
meta_topic (META_DEBUG_WINDOW_OPS,
"Unmaximizing %s%s\n",
@@ -3033,12 +3015,10 @@ meta_window_unmaximize (MetaWindow *window,
*/
meta_window_frame_size_changed (window);
desired_rect = &window->saved_rect;
/* Unmaximize to the saved_rect position in the direction(s)
* being unmaximized.
*/
target_rect = old_frame_rect;
target_rect = old_rect;
/* Avoid unmaximizing to "almost maximized" size when the previous size
* is greater then 80% of the work area use MAX_UNMAXIMIZED_WINDOW_AREA of the work area as upper limit
@@ -3080,17 +3060,15 @@ meta_window_unmaximize (MetaWindow *window,
meta_window_client_rect_to_frame_rect (window, &target_rect, &target_rect);
meta_window_move_resize_internal (window,
(META_MOVE_RESIZE_MOVE_ACTION |
META_MOVE_RESIZE_RESIZE_ACTION |
META_MOVE_RESIZE_STATE_CHANGED |
META_MOVE_RESIZE_DONT_SYNC_COMPOSITOR),
NorthWestGravity,
META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION | META_MOVE_RESIZE_STATE_CHANGED,
gravity,
target_rect);
meta_window_get_frame_rect (window, &new_rect);
meta_compositor_size_change_window (window->display->compositor, window,
META_SIZE_CHANGE_UNMAXIMIZE,
&old_frame_rect, &old_buffer_rect);
meta_compositor_unmaximize_window (window->display->compositor,
window,
&old_rect,
&new_rect);
/* When we unmaximize, if we're doing a mouse move also we could
* get the window suddenly jumping to the upper left corner of
@@ -3117,6 +3095,37 @@ meta_window_unmaximize (MetaWindow *window,
g_object_thaw_notify (G_OBJECT (window));
}
void
meta_window_unmaximize (MetaWindow *window,
MetaMaximizeFlags directions)
{
meta_window_unmaximize_internal (window, directions, &window->saved_rect,
NorthWestGravity);
}
/* Like meta_window_unmaximize(), but instead of unmaximizing to the
* saved position, we give the new desired size, and the gravity that
* determines the positioning relationship between the area occupied
* maximized and the new are. The arguments are similar to
* meta_window_resize_with_gravity().
* Unlike meta_window_unmaximize(), tiling is not restored for windows
* with a tile mode other than META_TILE_NONE.
*/
static void
meta_window_unmaximize_with_gravity (MetaWindow *window,
MetaMaximizeFlags directions,
int new_width,
int new_height,
int gravity)
{
MetaRectangle desired_rect;
desired_rect.width = new_width;
desired_rect.height = new_height;
meta_window_unmaximize_internal (window, directions, &desired_rect, gravity);
}
void
meta_window_make_above (MetaWindow *window)
{
@@ -3195,23 +3204,12 @@ meta_window_make_fullscreen (MetaWindow *window)
if (!window->fullscreen)
{
MetaRectangle old_frame_rect, old_buffer_rect;
meta_window_get_frame_rect (window, &old_frame_rect);
meta_window_get_buffer_rect (window, &old_buffer_rect);
meta_window_make_fullscreen_internal (window);
meta_window_move_resize_internal (window,
(META_MOVE_RESIZE_MOVE_ACTION |
META_MOVE_RESIZE_RESIZE_ACTION |
META_MOVE_RESIZE_STATE_CHANGED |
META_MOVE_RESIZE_DONT_SYNC_COMPOSITOR),
META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION | META_MOVE_RESIZE_STATE_CHANGED,
NorthWestGravity,
window->unconstrained_rect);
meta_compositor_size_change_window (window->display->compositor,
window, META_SIZE_CHANGE_FULLSCREEN,
&old_frame_rect, &old_buffer_rect);
}
}
@@ -3222,7 +3220,7 @@ meta_window_unmake_fullscreen (MetaWindow *window)
if (window->fullscreen)
{
MetaRectangle old_frame_rect, old_buffer_rect, target_rect;
MetaRectangle target_rect;
meta_topic (META_DEBUG_WINDOW_OPS,
"Unfullscreening %s\n", window->desc);
@@ -3230,10 +3228,6 @@ meta_window_unmake_fullscreen (MetaWindow *window)
window->fullscreen = FALSE;
target_rect = window->saved_rect;
meta_window_frame_size_changed (window);
meta_window_get_frame_rect (window, &old_frame_rect);
meta_window_get_buffer_rect (window, &old_buffer_rect);
/* Window's size hints may have changed while maximized, making
* saved_rect invalid. #329152
*/
@@ -3247,17 +3241,10 @@ meta_window_unmake_fullscreen (MetaWindow *window)
set_net_wm_state (window);
meta_window_move_resize_internal (window,
(META_MOVE_RESIZE_MOVE_ACTION |
META_MOVE_RESIZE_RESIZE_ACTION |
META_MOVE_RESIZE_STATE_CHANGED |
META_MOVE_RESIZE_DONT_SYNC_COMPOSITOR),
META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION | META_MOVE_RESIZE_STATE_CHANGED,
NorthWestGravity,
target_rect);
meta_compositor_size_change_window (window->display->compositor,
window, META_SIZE_CHANGE_UNFULLSCREEN,
&old_frame_rect, &old_buffer_rect);
meta_window_update_layer (window);
g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_FULLSCREEN]);
@@ -3578,7 +3565,7 @@ meta_window_update_monitor (MetaWindow *window,
const MetaMonitorInfo *old;
old = window->monitor;
META_WINDOW_GET_CLASS (window)->update_main_monitor (window);
window->monitor = meta_screen_get_monitor_for_window (window->screen, window);
if (old != window->monitor)
{
meta_window_on_all_workspaces_changed (window);
@@ -3719,7 +3706,7 @@ meta_window_move_resize_internal (MetaWindow *window,
{
window->unconstrained_rect = unconstrained_rect;
if (window->known_to_compositor && !(flags & META_MOVE_RESIZE_DONT_SYNC_COMPOSITOR))
if (window->known_to_compositor)
meta_compositor_sync_window_geometry (window->display->compositor,
window,
did_placement);
@@ -4051,8 +4038,9 @@ meta_window_get_buffer_rect (const MetaWindow *window,
* @client_rect: client rectangle in root coordinates
* @frame_rect: (out): location to store the computed corresponding frame bounds.
*
* Converts a desired bounds of the client window into the corresponding bounds
* of the window frame (excluding invisible borders and client side shadows.)
* Converts a desired bounds of the client window - what is passed to meta_window_move_resize() -
* into the corresponding bounds of the window frame (excluding invisible borders
* and client side shadows.)
*/
void
meta_window_client_rect_to_frame_rect (MetaWindow *window,
@@ -4099,7 +4087,7 @@ meta_window_client_rect_to_frame_rect (MetaWindow *window,
* @client_rect: (out): location to store the computed corresponding client rectangle.
*
* Converts a desired frame bounds for a window into the bounds of the client
* window.
* window - what is passed to meta_window_move_resize().
*/
void
meta_window_frame_rect_to_client_rect (MetaWindow *window,
@@ -4344,8 +4332,8 @@ set_workspace_state (MetaWindow *window,
GList *l;
for (l = window->screen->workspaces; l != NULL; l = l->next)
{
MetaWorkspace *ws = l->data;
meta_workspace_remove_window (ws, window);
MetaWorkspace *workspace = l->data;
meta_workspace_remove_window (workspace, window);
}
}
@@ -4359,8 +4347,8 @@ set_workspace_state (MetaWindow *window,
GList *l;
for (l = window->screen->workspaces; l != NULL; l = l->next)
{
MetaWorkspace *ws = l->data;
meta_workspace_add_window (ws, window);
MetaWorkspace *workspace = l->data;
meta_workspace_add_window (workspace, window);
}
}
@@ -4646,7 +4634,12 @@ meta_window_change_workspace_by_index (MetaWindow *window,
workspace = meta_screen_append_new_workspace (screen, FALSE, CurrentTime);
if (workspace)
meta_window_change_workspace (window, workspace);
{
if (window->on_all_workspaces_requested)
meta_window_unstick (window);
meta_window_change_workspace (window, workspace);
}
}
static void
@@ -5665,7 +5658,7 @@ update_move (MetaWindow *window,
int monitor;
window->tile_mode = META_TILE_NONE;
wmonitor = window->monitor;
wmonitor = meta_screen_get_monitor_for_window (window->screen, window);
for (monitor = 0; monitor < window->screen->n_monitor_infos; monitor++)
{
@@ -5735,6 +5728,81 @@ update_move (MetaWindow *window,
meta_window_move_frame (window, TRUE, new_x, new_y);
}
/* When resizing a maximized window by using alt-middle-drag (resizing
* with the grips or the menu for a maximized window is not enabled),
* the user can "break" out of the maximized state. This checks for
* that possibility. During such a break-out resize the user can also
* return to the previous maximization state by resizing back to near
* the original size.
*/
static MetaMaximizeFlags
check_resize_unmaximize(MetaWindow *window,
int dx,
int dy)
{
int threshold;
MetaMaximizeFlags new_unmaximize;
#define DRAG_THRESHOLD_TO_RESIZE_THRESHOLD_FACTOR 3
threshold = meta_prefs_get_drag_threshold () *
DRAG_THRESHOLD_TO_RESIZE_THRESHOLD_FACTOR;
new_unmaximize = 0;
if (window->maximized_horizontally ||
window->tile_mode != META_TILE_NONE ||
(window->display->grab_resize_unmaximize & META_MAXIMIZE_HORIZONTAL) != 0)
{
int x_amount;
/* We allow breaking out of maximization in either direction, to make
* the window larger than the monitor as well as smaller than the
* monitor. If we wanted to only allow resizing smaller than the
* monitor, we'd use - dx for NE/E/SE and dx for SW/W/NW.
*/
if ((window->display->grab_op & (META_GRAB_OP_WINDOW_DIR_WEST | META_GRAB_OP_WINDOW_DIR_EAST)) != 0)
x_amount = dx < 0 ? - dx : dx;
else
x_amount = 0;
if (x_amount > threshold)
new_unmaximize |= META_MAXIMIZE_HORIZONTAL;
}
if (window->maximized_vertically ||
(window->display->grab_resize_unmaximize & META_MAXIMIZE_VERTICAL) != 0)
{
int y_amount;
if ((window->display->grab_op & (META_GRAB_OP_WINDOW_DIR_NORTH | META_GRAB_OP_WINDOW_DIR_SOUTH)) != 0)
y_amount = dy < 0 ? - dy : dy;
else
y_amount = 0;
if (y_amount > threshold)
new_unmaximize |= META_MAXIMIZE_VERTICAL;
}
/* Metacity doesn't have a full user interface for only horizontally or
* vertically maximized, so while only unmaximizing in the direction drags
* has some advantages, it will also confuse the user. So, we always
* unmaximize both ways if possible.
*/
if (new_unmaximize != 0)
{
new_unmaximize = 0;
if (window->maximized_horizontally ||
(window->display->grab_resize_unmaximize & META_MAXIMIZE_HORIZONTAL) != 0)
new_unmaximize |= META_MAXIMIZE_HORIZONTAL;
if (window->maximized_vertically ||
(window->display->grab_resize_unmaximize & META_MAXIMIZE_VERTICAL) != 0)
new_unmaximize |= META_MAXIMIZE_VERTICAL;
}
return new_unmaximize;
}
static gboolean
update_resize_timeout (gpointer data)
{
@@ -5759,6 +5827,7 @@ update_resize (MetaWindow *window,
int gravity;
MetaRectangle old;
double remaining = 0;
MetaMaximizeFlags new_unmaximize;
window->display->grab_latest_motion_x = x;
window->display->grab_latest_motion_y = y;
@@ -5805,6 +5874,8 @@ update_resize (MetaWindow *window,
meta_window_update_keyboard_resize (window, TRUE);
}
new_unmaximize = check_resize_unmaximize (window, dx, dy);
if (window->display->grab_op & META_GRAB_OP_WINDOW_DIR_EAST)
new_w += dx;
else if (window->display->grab_op & META_GRAB_OP_WINDOW_DIR_WEST)
@@ -5873,7 +5944,29 @@ update_resize (MetaWindow *window,
snap,
FALSE);
meta_window_resize_frame_with_gravity (window, TRUE, new_w, new_h, gravity);
if (new_unmaximize == window->display->grab_resize_unmaximize)
{
meta_window_resize_frame_with_gravity (window, TRUE, new_w, new_h, gravity);
}
else
{
if ((new_unmaximize & ~window->display->grab_resize_unmaximize) != 0)
{
meta_window_unmaximize_with_gravity (window,
(new_unmaximize & ~window->display->grab_resize_unmaximize),
new_w, new_h, gravity);
}
if ((window->display->grab_resize_unmaximize & ~new_unmaximize))
{
MetaRectangle saved_rect = window->saved_rect;
meta_window_maximize (window,
(window->display->grab_resize_unmaximize & ~new_unmaximize));
window->saved_rect = saved_rect;
}
}
window->display->grab_resize_unmaximize = new_unmaximize;
/* Store the latest resize time, if we actually resized. */
if (window->rect.width != old.width || window->rect.height != old.height)
@@ -6074,8 +6167,12 @@ void
meta_window_get_work_area_current_monitor (MetaWindow *window,
MetaRectangle *area)
{
const MetaMonitorInfo *monitor = NULL;
monitor = meta_screen_get_monitor_for_window (window->screen,
window);
meta_window_get_work_area_for_monitor (window,
window->monitor->number,
monitor->number,
area);
}
@@ -6304,7 +6401,7 @@ find_ancestor_func (MetaWindow *window,
* so by traversing the @transient's ancestors until it either locates @window
* or reaches an ancestor that is not transient.
*
* Return Value: %TRUE if window is an ancestor of transient.
* Return Value: (transfer none): %TRUE if window is an ancestor of transient.
*/
gboolean
meta_window_is_ancestor_of_transient (MetaWindow *window,
@@ -7042,7 +7139,7 @@ meta_window_get_transient_for (MetaWindow *window)
* Returns pid of the process that created this window, if known (obtained from
* the _NET_WM_PID property).
*
* Return value: the pid, or -1 if not known.
* Return value: (transfer none): the pid, or -1 if not known.
*/
int
meta_window_get_pid (MetaWindow *window)
@@ -7880,9 +7977,3 @@ meta_window_grab_op_ended (MetaWindow *window,
{
META_WINDOW_GET_CLASS (window)->grab_op_ended (window, op);
}
void
meta_window_emit_size_changed (MetaWindow *window)
{
g_signal_emit (window, window_signals[SIZE_CHANGED], 0);
}

View File

@@ -1055,7 +1055,7 @@ meta_workspace_get_onmonitor_region (MetaWorkspace *workspace,
}
#ifdef WITH_VERBOSE_MODE
static const char *
static char *
meta_motion_direction_to_string (MetaMotionDirection direction)
{
switch (direction)

View File

@@ -372,6 +372,12 @@ typedef enum
* @META_BUTTON_FUNCTION_MINIMIZE: Minimize
* @META_BUTTON_FUNCTION_MAXIMIZE: Maximize
* @META_BUTTON_FUNCTION_CLOSE: Close
* @META_BUTTON_FUNCTION_SHADE: Shade
* @META_BUTTON_FUNCTION_ABOVE: Above
* @META_BUTTON_FUNCTION_STICK: Stick
* @META_BUTTON_FUNCTION_UNSHADE: Unshade
* @META_BUTTON_FUNCTION_UNABOVE: Unabove
* @META_BUTTON_FUNCTION_UNSTICK: Unstick
* @META_BUTTON_FUNCTION_LAST: Marks the end of the #MetaButtonFunction enumeration
*
* Function a window button can have. Note, you can't add stuff here
@@ -384,6 +390,12 @@ typedef enum
META_BUTTON_FUNCTION_MINIMIZE,
META_BUTTON_FUNCTION_MAXIMIZE,
META_BUTTON_FUNCTION_CLOSE,
META_BUTTON_FUNCTION_SHADE,
META_BUTTON_FUNCTION_ABOVE,
META_BUTTON_FUNCTION_STICK,
META_BUTTON_FUNCTION_UNSHADE,
META_BUTTON_FUNCTION_UNABOVE,
META_BUTTON_FUNCTION_UNSTICK,
META_BUTTON_FUNCTION_APPMENU,
META_BUTTON_FUNCTION_LAST
} MetaButtonFunction;
@@ -393,10 +405,10 @@ typedef enum
/* Keep array size in sync with MAX_BUTTONS_PER_CORNER */
/**
* MetaButtonLayout:
* @left_buttons: (array fixed-size=5):
* @right_buttons: (array fixed-size=5):
* @left_buttons_has_spacer: (array fixed-size=5):
* @right_buttons_has_spacer: (array fixed-size=5):
* @left_buttons: (array fixed-size=11):
* @right_buttons: (array fixed-size=11):
* @left_buttons_has_spacer: (array fixed-size=11):
* @right_buttons_has_spacer: (array fixed-size=11):
*/
typedef struct _MetaButtonLayout MetaButtonLayout;
struct _MetaButtonLayout

View File

@@ -54,13 +54,6 @@ typedef enum
META_COMP_EFFECT_NONE
} MetaCompEffect;
typedef enum {
META_SIZE_CHANGE_MAXIMIZE,
META_SIZE_CHANGE_UNMAXIMIZE,
META_SIZE_CHANGE_FULLSCREEN,
META_SIZE_CHANGE_UNFULLSCREEN,
} MetaSizeChange;
MetaCompositor *meta_compositor_new (MetaDisplay *display);
void meta_compositor_destroy (MetaCompositor *compositor);
@@ -96,11 +89,14 @@ void meta_compositor_switch_workspace (MetaCompositor *compositor,
MetaWorkspace *to,
MetaMotionDirection direction);
void meta_compositor_size_change_window (MetaCompositor *compositor,
MetaWindow *window,
MetaSizeChange which_change,
MetaRectangle *old_frame_rect,
MetaRectangle *old_buffer_rect);
void meta_compositor_maximize_window (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *old_rect,
MetaRectangle *new_rect);
void meta_compositor_unmaximize_window (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *old_rect,
MetaRectangle *new_rect);
void meta_compositor_sync_window_geometry (MetaCompositor *compositor,
MetaWindow *window,

View File

@@ -49,7 +49,7 @@ typedef enum
} MetaExitCode;
/* exit immediately */
void meta_exit (MetaExitCode code) G_GNUC_NORETURN;
void meta_exit (MetaExitCode code);
/* g_main_loop_quit() then fall out of main() */
void meta_quit (MetaExitCode code);

View File

@@ -55,7 +55,8 @@ struct _MetaPlugin
* MetaPluginClass:
* @start: virtual function called when the compositor starts managing a screen
* @minimize: virtual function called when a window is minimized
* @size_change: virtual function called when a window changes size to/from constraints
* @maximize: virtual function called when a window is maximized
* @unmaximize: virtual function called when a window is unmaximized
* @map: virtual function called when a window is mapped
* @destroy: virtual function called when a window is destroyed
* @switch_workspace: virtual function called when the user switches to another
@@ -102,11 +103,39 @@ struct _MetaPluginClass
void (*unminimize) (MetaPlugin *plugin,
MetaWindowActor *actor);
void (*size_change) (MetaPlugin *plugin,
/**
* MetaPluginClass::maximize:
* @actor: a #MetaWindowActor
* @x: target X coordinate
* @y: target Y coordinate
* @width: target width
* @height: target height
*
* Virtual function called when the window represented by @actor is maximized.
*/
void (*maximize) (MetaPlugin *plugin,
MetaWindowActor *actor,
MetaSizeChange which_change,
MetaRectangle *old_frame_rect,
MetaRectangle *old_buffer_rect);
gint x,
gint y,
gint width,
gint height);
/**
* MetaPluginClass::unmaximize:
* @actor: a #MetaWindowActor
* @x: target X coordinate
* @y: target Y coordinate
* @width: target width
* @height: target height
*
* Virtual function called when the window represented by @actor is unmaximized.
*/
void (*unmaximize) (MetaPlugin *plugin,
MetaWindowActor *actor,
gint x,
gint y,
gint width,
gint height);
/**
* MetaPluginClass::map:
@@ -357,8 +386,12 @@ meta_plugin_unminimize_completed (MetaPlugin *plugin,
MetaWindowActor *actor);
void
meta_plugin_size_change_completed (MetaPlugin *plugin,
MetaWindowActor *actor);
meta_plugin_maximize_completed (MetaPlugin *plugin,
MetaWindowActor *actor);
void
meta_plugin_unmaximize_completed (MetaPlugin *plugin,
MetaWindowActor *actor);
void
meta_plugin_map_completed (MetaPlugin *plugin,

View File

@@ -23,11 +23,7 @@
#ifndef __META_SHADOW_FACTORY_H__
#define __META_SHADOW_FACTORY_H__
#include <cairo.h>
#include <clutter/clutter.h>
#include <meta/meta-window-shape.h>
GType meta_shadow_get_type (void) G_GNUC_CONST;
#include <glib-object.h>
/**
* MetaShadowParams:
@@ -85,38 +81,4 @@ void meta_shadow_factory_get_params (MetaShadowFactory *factory,
gboolean focused,
MetaShadowParams *params);
/**
* MetaShadow:
* #MetaShadow holds a shadow texture along with information about how to
* apply that texture to draw a window texture. (E.g., it knows how big the
* unscaled borders are on each side of the shadow texture.)
*/
typedef struct _MetaShadow MetaShadow;
MetaShadow *meta_shadow_ref (MetaShadow *shadow);
void meta_shadow_unref (MetaShadow *shadow);
void meta_shadow_paint (MetaShadow *shadow,
int window_x,
int window_y,
int window_width,
int window_height,
guint8 opacity,
cairo_region_t *clip,
gboolean clip_strictly);
void meta_shadow_get_bounds (MetaShadow *shadow,
int window_x,
int window_y,
int window_width,
int window_height,
cairo_rectangle_int_t *bounds);
MetaShadowFactory *meta_shadow_factory_new (void);
MetaShadow *meta_shadow_factory_get_shadow (MetaShadowFactory *factory,
MetaWindowShape *shape,
int width,
int height,
const char *class_name,
gboolean focused);
#endif /* __META_SHADOW_FACTORY_H__ */

View File

@@ -62,10 +62,4 @@ MetaWindow * meta_window_actor_get_meta_window (MetaWindowActor *self
ClutterActor * meta_window_actor_get_texture (MetaWindowActor *self);
gboolean meta_window_actor_is_destroyed (MetaWindowActor *self);
typedef enum {
META_SHADOW_MODE_AUTO,
META_SHADOW_MODE_FORCED_OFF,
META_SHADOW_MODE_FORCED_ON,
} MetaShadowMode;
#endif /* META_WINDOW_ACTOR_H */

View File

@@ -66,21 +66,6 @@ int meta_screen_get_active_workspace_index (MetaScreen *screen);
MetaWorkspace * meta_screen_get_active_workspace (MetaScreen *screen);
/**
* MetaScreenDirection:
* @META_SCREEN_UP: up
* @META_SCREEN_DOWN: down
* @META_SCREEN_LEFT: left
* @META_SCREEN_RIGHT: right
*/
typedef enum
{
META_SCREEN_UP,
META_SCREEN_DOWN,
META_SCREEN_LEFT,
META_SCREEN_RIGHT
} MetaScreenDirection;
int meta_screen_get_n_monitors (MetaScreen *screen);
int meta_screen_get_primary_monitor (MetaScreen *screen);
int meta_screen_get_current_monitor (MetaScreen *screen);
@@ -97,10 +82,6 @@ gboolean meta_screen_get_monitor_in_fullscreen (MetaScreen *screen,
int meta_screen_get_monitor_index_for_rect (MetaScreen *screen,
MetaRectangle *rect);
int meta_screen_get_monitor_neighbor_index (MetaScreen *screen,
int which_monitor,
MetaScreenDirection dir);
void meta_screen_focus_default_window (MetaScreen *screen,
guint32 timestamp);

View File

@@ -1,5 +1,5 @@
/*** BEGIN file-header ***/
#include <meta/meta-enum-types.h>
#include "mutter-enum-types.h"
/*** END file-header ***/
/*** BEGIN file-production ***/

View File

@@ -1,6 +1,6 @@
/*** BEGIN file-header ***/
#ifndef __META_ENUM_TYPES_H__
#define __META_ENUM_TYPES_H__
#ifndef __MUTTER_ENUM_TYPES_H__
#define __MUTTER_ENUM_TYPES_H__
#include <glib-object.h>

View File

@@ -1 +0,0 @@
timestamp

View File

@@ -25,7 +25,7 @@
#include <string.h>
#include <X11/extensions/sync.h>
const char *client_id = "0";
char *client_id = "0";
static gboolean wayland;
GHashTable *windows;

View File

@@ -1094,6 +1094,7 @@ main (int argc, char **argv)
if (all_tests)
{
GFile *test_dir = g_file_new_for_path (MUTTER_PKGDATADIR "/tests");
GError *error = NULL;
if (!find_metatests_in_directory (test_dir, tests, &error))
{
@@ -1119,7 +1120,7 @@ main (int argc, char **argv)
/* Then initalize mutter with a different set of arguments */
char *fake_args[] = { NULL, (char *)"--wayland" };
char *fake_args[] = { NULL, "--wayland" };
fake_args[0] = argv[0];
char **fake_argv = fake_args;
int fake_argc = 2;

View File

@@ -970,6 +970,12 @@ meta_frame_left_click_event (MetaUIFrame *frame,
case META_FRAME_CONTROL_UNMAXIMIZE:
case META_FRAME_CONTROL_MINIMIZE:
case META_FRAME_CONTROL_DELETE:
case META_FRAME_CONTROL_SHADE:
case META_FRAME_CONTROL_UNSHADE:
case META_FRAME_CONTROL_ABOVE:
case META_FRAME_CONTROL_UNABOVE:
case META_FRAME_CONTROL_STICK:
case META_FRAME_CONTROL_UNSTICK:
case META_FRAME_CONTROL_MENU:
case META_FRAME_CONTROL_APPMENU:
frame->grab_button = event->button;
@@ -1047,11 +1053,6 @@ meta_frame_left_click_event (MetaUIFrame *frame,
}
return TRUE;
case META_FRAME_CONTROL_NONE:
/* We can get this for example when trying to resize window
* that cannot be resized (e. g. it is maximized and the theme
* currently used has borders for maximized windows), see #751884 */
return FALSE;
default:
g_assert_not_reached ();
}
@@ -1148,6 +1149,24 @@ handle_button_release_event (MetaUIFrame *frame,
case META_FRAME_CONTROL_DELETE:
meta_window_delete (frame->meta_window, event->time);
break;
case META_FRAME_CONTROL_SHADE:
meta_window_shade (frame->meta_window, event->time);
break;
case META_FRAME_CONTROL_UNSHADE:
meta_window_unshade (frame->meta_window, event->time);
break;
case META_FRAME_CONTROL_ABOVE:
meta_window_make_above (frame->meta_window);
break;
case META_FRAME_CONTROL_UNABOVE:
meta_window_unmake_above (frame->meta_window);
break;
case META_FRAME_CONTROL_STICK:
meta_window_stick (frame->meta_window);
break;
case META_FRAME_CONTROL_UNSTICK:
meta_window_unstick (frame->meta_window);
break;
default:
break;
}
@@ -1196,6 +1215,18 @@ meta_ui_frame_update_prelit_control (MetaUIFrame *frame,
break;
case META_FRAME_CONTROL_UNMAXIMIZE:
break;
case META_FRAME_CONTROL_SHADE:
break;
case META_FRAME_CONTROL_UNSHADE:
break;
case META_FRAME_CONTROL_ABOVE:
break;
case META_FRAME_CONTROL_UNABOVE:
break;
case META_FRAME_CONTROL_STICK:
break;
case META_FRAME_CONTROL_UNSTICK:
break;
case META_FRAME_CONTROL_RESIZE_SE:
cursor = META_CURSOR_SE_RESIZE;
break;
@@ -1234,6 +1265,12 @@ meta_ui_frame_update_prelit_control (MetaUIFrame *frame,
case META_FRAME_CONTROL_MINIMIZE:
case META_FRAME_CONTROL_MAXIMIZE:
case META_FRAME_CONTROL_DELETE:
case META_FRAME_CONTROL_SHADE:
case META_FRAME_CONTROL_UNSHADE:
case META_FRAME_CONTROL_ABOVE:
case META_FRAME_CONTROL_UNABOVE:
case META_FRAME_CONTROL_STICK:
case META_FRAME_CONTROL_UNSTICK:
case META_FRAME_CONTROL_UNMAXIMIZE:
/* leave control set */
break;
@@ -1445,6 +1482,24 @@ meta_ui_frame_paint (MetaUIFrame *frame,
case META_FRAME_CONTROL_UNMAXIMIZE:
button_type = META_BUTTON_TYPE_MAXIMIZE;
break;
case META_FRAME_CONTROL_SHADE:
button_type = META_BUTTON_TYPE_SHADE;
break;
case META_FRAME_CONTROL_UNSHADE:
button_type = META_BUTTON_TYPE_UNSHADE;
break;
case META_FRAME_CONTROL_ABOVE:
button_type = META_BUTTON_TYPE_ABOVE;
break;
case META_FRAME_CONTROL_UNABOVE:
button_type = META_BUTTON_TYPE_UNABOVE;
break;
case META_FRAME_CONTROL_STICK:
button_type = META_BUTTON_TYPE_STICK;
break;
case META_FRAME_CONTROL_UNSTICK:
button_type = META_BUTTON_TYPE_UNSTICK;
break;
case META_FRAME_CONTROL_DELETE:
button_type = META_BUTTON_TYPE_CLOSE;
break;
@@ -1564,6 +1619,24 @@ control_rect (MetaFrameControl control,
case META_FRAME_CONTROL_UNMAXIMIZE:
rect = &fgeom->max_rect.visible;
break;
case META_FRAME_CONTROL_SHADE:
rect = &fgeom->shade_rect.visible;
break;
case META_FRAME_CONTROL_UNSHADE:
rect = &fgeom->unshade_rect.visible;
break;
case META_FRAME_CONTROL_ABOVE:
rect = &fgeom->above_rect.visible;
break;
case META_FRAME_CONTROL_UNABOVE:
rect = &fgeom->unabove_rect.visible;
break;
case META_FRAME_CONTROL_STICK:
rect = &fgeom->stick_rect.visible;
break;
case META_FRAME_CONTROL_UNSTICK:
rect = &fgeom->unstick_rect.visible;
break;
case META_FRAME_CONTROL_RESIZE_SE:
break;
case META_FRAME_CONTROL_RESIZE_S:
@@ -1648,6 +1721,36 @@ get_control (MetaUIFrame *frame, int root_x, int root_y)
return META_FRAME_CONTROL_MAXIMIZE;
}
if (POINT_IN_RECT (x, y, fgeom.shade_rect.clickable))
{
return META_FRAME_CONTROL_SHADE;
}
if (POINT_IN_RECT (x, y, fgeom.unshade_rect.clickable))
{
return META_FRAME_CONTROL_UNSHADE;
}
if (POINT_IN_RECT (x, y, fgeom.above_rect.clickable))
{
return META_FRAME_CONTROL_ABOVE;
}
if (POINT_IN_RECT (x, y, fgeom.unabove_rect.clickable))
{
return META_FRAME_CONTROL_UNABOVE;
}
if (POINT_IN_RECT (x, y, fgeom.stick_rect.clickable))
{
return META_FRAME_CONTROL_STICK;
}
if (POINT_IN_RECT (x, y, fgeom.unstick_rect.clickable))
{
return META_FRAME_CONTROL_UNSTICK;
}
/* South resize always has priority over north resize,
* in case of overlap.
*/

View File

@@ -27,7 +27,6 @@
#include <meta/common.h>
#include <meta/types.h>
#include "theme-private.h"
#include "ui.h"
typedef enum
{
@@ -39,6 +38,12 @@ typedef enum
META_FRAME_CONTROL_MINIMIZE,
META_FRAME_CONTROL_MAXIMIZE,
META_FRAME_CONTROL_UNMAXIMIZE,
META_FRAME_CONTROL_SHADE,
META_FRAME_CONTROL_UNSHADE,
META_FRAME_CONTROL_ABOVE,
META_FRAME_CONTROL_UNABOVE,
META_FRAME_CONTROL_STICK,
META_FRAME_CONTROL_UNSTICK,
META_FRAME_CONTROL_RESIZE_SE,
META_FRAME_CONTROL_RESIZE_S,
META_FRAME_CONTROL_RESIZE_SW,
@@ -64,6 +69,8 @@ typedef enum
typedef struct _MetaFrames MetaFrames;
typedef struct _MetaFramesClass MetaFramesClass;
typedef struct _MetaUIFrame MetaUIFrame;
struct _MetaUIFrame
{
MetaFrames *frames;

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