Compare commits

..

19 Commits

Author SHA1 Message Date
Owen W. Taylor
8a0de6dfd3 Avoid restacking animating hidden actors
Since the stack passed to the compositor now accurately reflects
the X stacking order, we need to treat hidden windows (which are
at the bottom of the X stacking order) specially - when the
compositor stacking order is synced, try to keep animating hidden
actors in their old positions in the stack.

http://bugzilla.gnome.org/show_bug.cgi?id=585984
2009-06-27 09:58:45 -04:00
Owen W. Taylor
2bf0b2b6de Merge branch 'master' into override-redirect-exclusion 2009-06-19 11:42:03 -04:00
Owen W. Taylor
eed2a2d324 Fix shadowing problem breaking MetaStackTracker
A variable shadowing problem introduced in cleanup was causing
queued elements to be removed too early.

http://bugzilla.gnome.org/show_bug.cgi?id=585984
2009-06-17 14:23:57 -04:00
Owen W. Taylor
9828007a02 Merge branch 'master' into override-redirect-exclusion
Conflicts:
	src/core/bell.c
2009-06-17 13:40:42 -04:00
Owen W. Taylor
1f890672bb Use MetaStackTracker to avoid a round-trip XQueryTree()
With MetaStackTracker, it's no longer necessary to XQueryTree to
get a reasonably-up-to-date view of the server stacking order.

Add some comments explaining unclear aspects of
raise_window_relative_to_managed_windows() and with future possible
improvements.

http://bugzilla.gnome.org/show_bug.cgi?id=585984
2009-06-16 09:56:43 -04:00
Owen W. Taylor
ef966854d5 Don't do stacking for override-redirect windows
Don't add override-redirect windows to MetaStack; we shouldn't
be restacking them.

Since we *aren't* stacking the override-redirect windows, we need to
be careful that to ignore them when looking for the top managed
window.

http://bugzilla.gnome.org/show_bug.cgi?id=585984
2009-06-16 09:56:42 -04:00
Owen W. Taylor
7309b6cfe3 Move compositor-stack handling to MetaStackTracker
In order to properly track the stacking order for override-redirect
windows, move meta_compositor_sync_stack() call into MetaStackTracker.
In the new location, we sync the stack as a before-redraw idle function,
rather then using the freeze-thaw facilities of MetaStack. This is
simpler, and also properly compresses multiple stack changes on
notifications received from the X server.

http://bugzilla.gnome.org/show_bug.cgi?id=585984
2009-06-16 09:56:42 -04:00
Owen W. Taylor
3705a224f0 Add better tracking of real stacking order
Wedging override-redirect windows into the constraint code in stack.c
results in Mutter getting confused about the stacking order of
these windows with respect to other windows, and may also in some
cases cause Mutter to restack override-redirect windows.

core/stack-tracker.c core/stack-tracker.h: MetaStackTracker - combine
  events received from the X server with local changes we have made
  to come up with the best possible idea of what the stacking order
  is at any one point in time.

core/screen.c core/screen-private.h: Create a MetaStackTracker for
  the screen.

core/display.c: Feed relevant events to MetaStackTracker

core/frame.c core/screen.c core/stack.c: When we make changes to the
  stacking order or add windows, record those changes immediatley
  in MetaStackTracker so we have the information without waiting
  for a round-trip.

include/ui.h ui/ui.c: meta_ui_create_frame_window add a return value
  for the X request serial used to create the window.

http://bugzilla.gnome.org/show_bug.cgi?id=585984
2009-06-16 09:56:42 -04:00
Owen W. Taylor
2ebedb822d Avoid moving and resizing override-redirect windows
Override-redirect windows should not be moved or resized by the
window manager.

- Mark override-redirect windows as already placed to avoid
  placing them when first shown.
- Don't move-resize newly created override-redirect MetaWindow
- Don't queue a resize on override-redirect windows when reading
  their WM_TRANSIENT_FOR hint.
- Add g_return_if_fail (!window->override_redirect) to catch
  unexpected code paths that might result in override-redirect
  windows being moved or resized.
http://bugzilla.gnome.org/show_bug.cgi?id=582639
2009-06-16 09:56:42 -04:00
Owen W. Taylor
d6576d9b70 Don't add override-redirect windows to workspaces
Normally a window that is "on all workspaces", is also on a particular
workspace (to deal with being unstuck.) This is pointless for
override-redirect windows.

http://bugzilla.gnome.org/show_bug.cgi?id=582639
2009-06-16 09:56:42 -04:00
Owen W. Taylor
6516c19ec5 Ignore client messages sent to override-redirect windows
If someone asks us to close, maximize, etc, an override-redirect
window, just ignore the request.

http://bugzilla.gnome.org/show_bug.cgi?id=582639
2009-06-16 09:56:42 -04:00
Owen W. Taylor
5518fee61c meta_screen_foreach_window(): Skip override-redirect windows
Don't include override-redirect windows when iterating the windows
in the screen. We don't need them for any of the current uses:

 - Queueing redraws and resizes on managed windows
 - Checking which windows should be added to a new workspace

http://bugzilla.gnome.org/show_bug.cgi?id=582639
2009-06-16 09:56:42 -04:00
Owen W. Taylor
ace0521cba meta_display_list_windows: Exclude override-redirect
Don't include override-redirect windows in the list return by
meta_display_list_windows(), since we almost never want to handle
them when considering "all window" for the display. Add a separate
meta_display_list_all_windows() that includes override-redirect
windows.

http://bugzilla.gnome.org/show_bug.cgi?id=582639
2009-06-16 09:56:42 -04:00
Owen W. Taylor
0091a3aab5 Don't read most properties for override-redirect windows
Skipping handling of properties for override redirect windows has
two advantages: first it reduces the amount of work needed to get
an override-redirect window (menu, tooltip, drag icon) onto the
screen. But more importantly, it reduces the number of code-paths
for an override-redirect to get into some code portion where it
isn't expected.

* Integrate the list of properties we load initially with the
  list of property hooks; this avoids having two separate lists
  that we have to keep in sync.

* Add a flag to MetaWindowPropHooks to indicate whether the
  property should be handled for override-redirect windows;
  currently we load a) properties that identify the window -
  useful for debugging purposes b) WM_TRANSIENT_FOR (could be
  used to associate menus with toplevels.)

* For properties that aren't always loaded through window-props.c,
  add !window->override checks to places that trigger loading,
  and add g_return_if_fail(!window->override) to the load
  functions as a double-check.

http://bugzilla.gnome.org/show_bug.cgi?id=582639
2009-06-16 09:56:42 -04:00
Owen W. Taylor
268b92a4ec Add checks against inappropriate changes to override-redirect window
Add g_return_if_fail() to check that window-management functions like
meta_window_maximize() aren't called on override-redirect windows.

This reveals that were were "unminimizing" override-redirect windows
when adding them; avoid doing that.

http://bugzilla.gnome.org/show_bug.cgi?id=582639
2009-06-16 09:56:41 -04:00
Owen W. Taylor
29bb4c27e3 Fix property notifications for certain properties
If a property has a reload function, but the standard property-fetching
mechanism isn't used (hooks->type == META_PROP_VALUE_INVALID), then the
a logic error (introduced in January) caused the hook to never be run.

This meant that changes to struts and icons weren't noticed.

Same as: http://bugzilla.gnome.org/show_bug.cgi?id=572573
The fix here is different in detail from that applied to Metacity, but
similar in spirit.

http://bugzilla.gnome.org/show_bug.cgi?id=585980
2009-06-16 09:56:41 -04:00
Owen W. Taylor
bd3bdc51b9 Load NET_WM_USER_TIME from the right window
On subsequent changes, if there is a NET_WM_USER_TIME_WINDOW, then
read the property from that rather than from the main window.
(Fix an accidental regression: the right Window was being computed
but no longer passed in.)

http://bugzilla.gnome.org/show_bug.cgi?id=585979
2009-06-16 09:56:41 -04:00
Owen W. Taylor
0123dab87a Fix missing static for meta_window_show()
Definition of meta_window_show() was missing static although it
was forward-declared with static.

http://bugzilla.gnome.org/show_bug.cgi?id=585978
2009-06-16 09:56:41 -04:00
Owen W. Taylor
413acc9574 Regularize main loop priorities
If there is a client that is continually redrawing, then
sources that are less-prioritized than CLUTTER_PRIORITY_REDRAW
will never get run. This patch sorts out how all the different
main loop sources fit in CLUTTER_PRIORITY_REDRAW.

common.h: Document all the relevant priorities and how they
  fit in with each other.
ui.h common.h: Move META_PRIORITY_RESIZE to to common.h with
  other priorities.
src/core/window.c src/core/screen.c: Change calc-showing,
  update-icon, and update-work-area idles to be prioritized above
  redraws so they don't get starved.
bell.c: Make the visual bell priority the same as the clutter
  redraw priority.
delete.c: Use a G_PRIORITY_DEFAULT idle when responding to the
  dialog response; we want to handle it as soon as practical.

http://bugzilla.gnome.org/show_bug.cgi?id=568874
2009-06-16 09:56:41 -04:00
241 changed files with 128627 additions and 107172 deletions

41
.gitignore vendored
View File

@@ -13,25 +13,17 @@ config.sub
configure
depcomp
install-sh
intltool-extract.in
intltool-merge.in
libtool
ltmain.sh
missing
.deps
src/50-mutter-navigation.xml
src/50-mutter-system.xml
src/50-mutter-windows.xml
src/mutter-wm.desktop
src/mutter.desktop
src/metacity-wm.desktop
*.o
*.a
*.lo
*.la
.libs
*.swp
*.gir
*.typelib
tidy-enum-types.[ch]
tidy-marshal.[ch]
stamp-tidy-enum-types.h
@@ -43,35 +35,26 @@ stamp-h1
stamp-it
.intltool-merge-cache
POTFILES
po/*.pot
50-metacity-desktop-key.xml
50-metacity-key.xml
inlinepixbufs.h
libmutter.pc
mutter
mutter-theme-viewer
mutter.desktop
org.gnome.mutter.gschema.valid
org.gnome.mutter.gschema.xml
libmetacity-private.pc
metacity
metacity-dialog
metacity-theme-viewer
metacity.desktop
metacity.schemas
testasyncgetprop
testboxes
testgradient
mutter-grayscale
mutter-mag
mutter-message
mutter-window-demo
metacity-grayscale
metacity-mag
metacity-message
metacity-window-demo
focus-window
test-attached
test-gravity
test-resizing
test-size-hints
# We can't say just "wm-tester" here or it will ignore the directory
# rather than the binary
src/wm-tester/wm-tester
wm-tester
INSTALL
mkinstalldirs
src/mutter-enum-types.[ch]
src/stamp-mutter-enum-types.h
src/mutter-marshal.[ch]
src/stamp-mutter-marshal.h
src/mutter-plugins.pc

View File

@@ -42,10 +42,10 @@ Minimal Building/Testing Environment
build a development version of Metacity -- odds are, you may be able
to build metacity from CVS without building any other modules.
As long as you have gtk+ >= 3.0 and GIO >= 2.25.10 with your distro
(gtk+ >= 2.6 if you manually revert the change from bug 348633), you
should be able to install your distro's development packages
(e.g. gtk2-devel, glib-devel, startup-notification-devel on
As long as you have gtk+ >= 2.10 and GConf with your distro (gtk+ >=
2.6 if you manually revert the change from bug 348633), you should
be able to install your distro's development packages
(e.g. gtk2-devel, GConf2-devel, startup-notification-devel on
Fedora; also, remember to install the gnome-common package which is
needed for building cvs versions of Gnome modules like Metacity) as
well as the standard development tools (gcc, autoconf, automake,

1302
NEWS

File diff suppressed because it is too large Load Diff

31
README
View File

@@ -18,8 +18,9 @@ COMPILING MUTTER
You need GTK+ 2.2. For startup notification to work you need
libstartup-notification at
http://www.freedesktop.org/software/startup-notification/ or on the
GNOME ftp site.
You need Clutter 1.0. You need gobject-introspection 0.6.3.
GNOME ftp site. You also need GConf 1.2 (unless building a funky
extra-small embedded metacity with --disable-gconf, see below).
You need Clutter 0.9.3. You need gobject-introspection 0.6.3.
REPORTING BUGS AND SUBMITTING PATCHES
===
@@ -58,24 +59,25 @@ MUTTER FEATURES
and should work with KWin, fvwm2, and other EWMH-compliant WMs.)
- Has a simple theme system and a couple of extra themes come with it.
Change themes via gsettings:
gsettings set org.gnome.desktop.wm.preferences theme Crux
gsettings set org.gnome.desktop.wm.preferences theme Gorilla
gsettings set org.gnome.desktop.wm.preferences theme Atlanta
gsettings set org.gnome.desktop.wm.preferences theme Bright
Change themes via gconf-editor or gconftool or GNOME themes control
panel:
gconftool-2 --type=string --set /apps/metacity/general/theme Crux
gconftool-2 --type=string --set /apps/metacity/general/theme Gorilla
gconftool-2 --type=string --set /apps/metacity/general/theme Atlanta
gconftool-2 --type=string --set /apps/metacity/general/theme Bright
See theme-format.txt for docs on the theme format. Use
metacity-theme-viewer to preview themes.
- Change number of workspaces via gsettings:
gsettings set org.gnome.desktop.wm.preferences num-workspaces 5
- Change number of workspaces via gconf-editor or gconftool:
gconftool-2 --type=int --set /apps/metacity/general/num_workspaces 5
Can also change workspaces from GNOME 2 pager.
- Change focus mode:
gsettings set org.gnome.desktop.wm.preferences focus-mode mouse
gsettings set org.gnome.desktop.wm.preferences focus-mode sloppy
gsettings set org.gnome.desktop.wm.preferences focus-mode click
gconftool-2 --type=string --set /apps/metacity/general/focus_mode mouse
gconftool-2 --type=string --set /apps/metacity/general/focus_mode sloppy
gconftool-2 --type=string --set /apps/metacity/general/focus_mode click
- Global keybinding defaults include:
@@ -90,9 +92,10 @@ MUTTER FEATURES
Change keybindings for example:
gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-1 '[<Alt>F1]'
unst gconftool-2 --type=string --set /apps/metacity/global_keybindings/switch_to_workspace_1 '<Alt>F1'
Also try the GNOME keyboard shortcuts control panel.
Also try the GNOME keyboard shortcuts control panel, or
gconf-editor.
- Window keybindings:

View File

@@ -1,13 +1,15 @@
AC_PREREQ(2.50)
m4_define([mutter_major_version], [3])
m4_define([mutter_minor_version], [7])
m4_define([mutter_micro_version], [2])
m4_define([mutter_major_version], [2])
m4_define([mutter_minor_version], [27])
# Fibonacci sequence for micro version numbering:
# 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987
m4_define([mutter_micro_version], [0])
m4_define([mutter_version],
[mutter_major_version.mutter_minor_version.mutter_micro_version])
m4_define([mutter_plugin_api_version], [3])
m4_define([mutter_plugin_api_version], [2])
AC_INIT([mutter], [mutter_version],
[http://bugzilla.gnome.org/enter_bug.cgi?product=mutter])
@@ -15,9 +17,8 @@ AC_INIT([mutter], [mutter_version],
AC_CONFIG_SRCDIR(src/core/display.c)
AC_CONFIG_HEADERS(config.h)
AM_INIT_AUTOMAKE([1.11 no-dist-gzip dist-xz tar-ustar])
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],)
AM_MAINTAINER_MODE([enable])
AM_INIT_AUTOMAKE
AM_MAINTAINER_MODE
MUTTER_MAJOR_VERSION=mutter_major_version
MUTTER_MINOR_VERSION=mutter_minor_version
@@ -45,9 +46,6 @@ AC_HEADER_STDC
AC_LIBTOOL_WIN32_DLL
AM_PROG_LIBTOOL
# Sets GLIB_GENMARSHAL and GLIB_MKENUMS
AM_PATH_GLIB_2_0()
#### Integer sizes
AC_CHECK_SIZEOF(char)
@@ -61,23 +59,80 @@ AC_CHECK_SIZEOF(__int64)
## byte order
AC_C_BIGENDIAN
CANBERRA_GTK=libcanberra-gtk3
CANBERRA_GTK_VERSION=0.26
#### Warnings
CLUTTER_PACKAGE=clutter-1.0
changequote(,)dnl
if test "x$GCC" = "xyes"; then
case " $CFLAGS " in
*[\ \ ]-Wall[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wall" ;;
esac
MUTTER_PC_MODULES="
gtk+-3.0 >= 3.3.7
gio-2.0 >= 2.25.10
pango >= 1.2.0
cairo >= 1.10.0
gsettings-desktop-schemas >= 3.3.0
xcomposite >= 0.2 xfixes xrender xdamage
$CLUTTER_PACKAGE >= 1.9.10
cogl-1.0 >= 1.9.6
"
# case " $CFLAGS " in
# *[\ \ ]-Wshadow[\ \ ]*) ;;
# *) CFLAGS="$CFLAGS -Wshadow" ;;
# esac
GLIB_GSETTINGS
case " $CFLAGS " in
*[\ \ ]-Wchar-subscripts[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wchar-subscripts" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wmissing-declarations[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wmissing-declarations" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wmissing-prototypes[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wmissing-prototypes" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wnested-externs[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wnested-externs" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wpointer-arith[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wpointer-arith" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wcast-align[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wcast-align" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wsign-compare[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wsign-compare" ;;
esac
if test "x$enable_ansi" = "xyes"; then
case " $CFLAGS " in
*[\ \ ]-ansi[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -ansi" ;;
esac
case " $CFLAGS " in
*[\ \ ]-pedantic[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -pedantic" ;;
esac
fi
fi
changequote([,])dnl
MUTTER_PC_MODULES='gtk+-2.0 >= 2.10.0 pango >= 1.2.0'
AC_ARG_ENABLE(gconf,
AC_HELP_STRING([--disable-gconf],
[disable gconf usage, for embedded/size-sensitive non-GNOME builds]),,
enable_gconf=yes)
if test x$enable_gconf = xyes; then
AC_DEFINE(HAVE_GCONF,1,[Build with gconf support])
MUTTER_PC_MODULES="$MUTTER_PC_MODULES gconf-2.0 >= 1.2.0"
fi
AC_ARG_ENABLE(verbose-mode,
AC_HELP_STRING([--disable-verbose-mode],
@@ -98,29 +153,53 @@ AC_ARG_ENABLE(startup-notification,
[disable mutter's startup notification support, for embedded/size-sensitive custom non-GNOME builds]),,
enable_startup_notification=auto)
AC_ARG_WITH(libcanberra,
AC_HELP_STRING([--without-libcanberra],
[disable the use of libcanberra for playing sounds]),,
with_libcanberra=auto)
AC_ARG_ENABLE(compositor,
AC_HELP_STRING([--disable-compositor],
[disable mutter's compositing manager]),,
enable_compositor=auto)
AC_ARG_ENABLE(clutter,
AC_HELP_STRING([--without-clutter],
[disable the use of clutter for compositing]),,
with_clutter=auto)
AC_ARG_ENABLE(introspection,
AC_HELP_STRING([--without-introspection],
[disable the use of GObject introspection]),,
with_introspection=auto)
AC_ARG_ENABLE(xsync,
AC_HELP_STRING([--disable-xsync],
[disable mutter's use of the XSync extension]),,
enable_xsync=auto)
AC_ARG_ENABLE(render,
AC_HELP_STRING([--disable-render],
[disable mutter's use of the RENDER extension]),,
enable_render=auto)
AC_ARG_ENABLE(shape,
AC_HELP_STRING([--disable-shape],
[disable mutter's use of the shaped window extension]),,
enable_shape=auto)
## try definining HAVE_BACKTRACE
AC_CHECK_HEADERS(execinfo.h, [AC_CHECK_FUNCS(backtrace)])
AM_GLIB_GNU_GETTEXT
## here we get the flags we'll actually use
# GRegex requires Glib-2.14.0
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.14.0)
# gtk_window_set_icon_name requires gtk2+-2.6.0
PKG_CHECK_MODULES(MUTTER_MESSAGE, gtk+-3.0)
PKG_CHECK_MODULES(MUTTER_WINDOW_DEMO, gtk+-3.0)
# GOptionEntry requires glib-2.6.0
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.6.0)
# gtk_window_set_icon_name requires gtk2+-2.60
PKG_CHECK_MODULES(MUTTER_MESSAGE, gtk+-2.0 >= 2.6.0)
PKG_CHECK_MODULES(MUTTER_WINDOW_DEMO, gtk+-2.0 >= 2.6.0)
if $PKG_CONFIG --atleast-version 1.2.0 pangoxft; then
echo "pangoxft found"
else
AC_MSG_ERROR("Pango 1.2.0 or greater based on Xft2 is required")
fi
# Unconditionally use this dir to avoid a circular dep with gnomecc
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
@@ -152,38 +231,122 @@ else
echo "Building without libstartup-notification"
fi
have_libcanberra=no
AC_MSG_CHECKING([libcanberra-gtk])
if test x$with_libcanberra = xno ; then
AC_MSG_RESULT([disabled])
## init this, it gets set either in the compositor check below
## or the render-specific check later
have_xrender=no
XCOMPOSITE_VERSION=0.2
if test x$enable_compositor = xyes; then
have_xcomposite=yes
elif test x$enable_compositor = xauto; then
echo "Building compositing manager by default now."
have_xcomposite=yes
else
if $PKG_CONFIG --exists $CANBERRA_GTK '>=' $CANBERRA_GTK_VERSION; then
have_libcanberra=yes
AC_MSG_RESULT(yes)
MUTTER_PC_MODULES="$MUTTER_PC_MODULES $CANBERRA_GTK"
AC_DEFINE([HAVE_LIBCANBERRA], 1, [Building with libcanberra for playing sounds])
have_xcomposite=no
fi
if test x$with_clutter = xyes; then
have_xcomposite=yes
have_clutter=yes
elif test x$with_clutter = xauto; then
echo "Building clutter compositing manager by default now."
have_xcomposite=yes
have_clutter=yes
else
have_clutter=no
fi
AM_CONDITIONAL(WITH_CLUTTER, test "$have_clutter" = "yes")
if test x$have_xcomposite = xyes; then
AC_MSG_CHECKING([Xcomposite >= $XCOMPOSITE_VERSION])
if $PKG_CONFIG --atleast-version $XCOMPOSITE_VERSION xcomposite; then
AC_MSG_RESULT([yes])
else
AC_MSG_ERROR([no. Use --disable-compositor to disable.])
fi
fi
if test x$have_xcomposite = xyes; then
MUTTER_PC_MODULES="$MUTTER_PC_MODULES xcomposite >= $XCOMPOSITE_VERSION xfixes xrender xdamage"
AC_DEFINE(HAVE_COMPOSITE_EXTENSIONS, 1, [Building with compositing manager support])
echo "Building with compositing manager"
## force on render also
have_xrender=yes
else
echo "Building without compositing manager"
fi
## if no compositor, still possibly enable render
if test x$have_xcomposite = xno; then
XRENDER_VERSION=0.0
AC_MSG_CHECKING([xrender >= $XRENDER_VERSION])
if $PKG_CONFIG --atleast-version $XRENDER_VERSION xrender; then
have_xrender=yes
else
AC_MSG_RESULT(no)
if test x$with_libcanberra = xyes ; then
AC_MSG_ERROR([libcanberra forced and libcanberra-gtk was not found])
fi
have_xrender=no
fi
AC_MSG_RESULT($have_xrender)
if test x$enable_render = xyes; then
have_xrender=yes
echo "Render support forced on"
elif test x$enable_render = xauto; then
true
else
have_xrender=no
fi
if test x$have_xrender = xyes; then
echo "Building with Render"
MUTTER_PC_MODULES="$MUTTER_PC_MODULES xrender >= $XRENDER_VERSION"
fi
fi ## have_composite
if test x$have_xrender = xyes; then
AC_DEFINE(HAVE_RENDER, , [Building with Render extension support])
fi
CLUTTER_PACKAGE=clutter-0.9
AC_SUBST(CLUTTER_PACKAGE)
if test x$have_clutter = xyes; then
MUTTER_PC_MODULES="$MUTTER_PC_MODULES $CLUTTER_PACKAGE "
PKG_CHECK_MODULES(CLUTTER, $CLUTTER_PACKAGE)
AC_DEFINE(WITH_CLUTTER, , [Building with Clutter compositor])
dnl Check for the clutter-glx-texture-pixmap header
mutter_save_cppflags="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $CLUTTER_CFLAGS"
AC_CHECK_HEADER([clutter/glx/clutter-glx-texture-pixmap.h],
[have_glx_texture_pixmap=yes],
[have_glx_texture_pixmap=no])
CPPFLAGS="$mutter_save_cppflags"
if test x$have_glx_texture_pixmap = xyes; then
AC_DEFINE(HAVE_GLX_TEXTURE_PIXMAP, ,
[Is ClutterGLXTexturePixmap available?])
fi
fi
INTROSPECTION_VERSION=0.9.5
GOBJECT_INTROSPECTION_CHECK([$INTROSPECTION_VERSION])
if test x$found_introspection != xno; then
AC_DEFINE(HAVE_INTROSPECTION, 1, [Define if GObject introspection is available])
MUTTER_PC_MODULES="$MUTTER_PC_MODULES gobject-introspection-1.0"
# Since we don't make any guarantees about stability and we don't support
# parallel install, there's no real reason to change directories, filenames,
# etc. as we change the Mutter tarball version. Note that this must match
# api_version in src/Makefile.am
META_GIR=Meta_3_0_gir
# META_GIR=[Meta_]mutter_major_version[_]mutter_minor_version[_gir]
AC_SUBST(META_GIR)
if test x$with_introspection != xno; then
PKG_CHECK_MODULES(INTROSPECTION, gobject-introspection-1.0, have_introspection=yes, have_introspection=no)
if test x$have_introspection=xyes; then
MUTTER_PC_MODULES="$MUTTER_PC_MODULES gobject-introspection-1.0"
AC_DEFINE(HAVE_INTROSPECTION, 1, [Define if GObject introspection is available])
G_IR_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0`
AC_SUBST(G_IR_SCANNER)
G_IR_COMPILER=`$PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0`
AC_SUBST(G_IR_COMPILER)
G_IR_GENERATE=`$PKG_CONFIG --variable=g_ir_generate gobject-introspection-1.0`
AC_SUBST(G_IR_GENERATE)
GIRDIR=`$PKG_CONFIG --variable=girdir gobject-introspection-1.0`
AC_SUBST(GIRDIR)
TYPELIBDIR="$($PKG_CONFIG --variable=typelibdir gobject-introspection-1.0)"
AC_SUBST(TYPELIBDIR)
fi
fi
AM_CONDITIONAL(WITH_INTROSPECTION, test "$have_introspection" = "yes")
AC_MSG_CHECKING([Xcursor])
if $PKG_CONFIG xcursor; then
@@ -201,39 +364,64 @@ fi
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
# This is used for plugins
AC_SUBST(CLUTTER_PACKAGE)
PKG_CHECK_MODULES(CLUTTER, $CLUTTER_PACKAGE)
AC_PATH_XTRA
ALL_X_LIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
# Check for Xinerama extension - we only support the "XFree86" style,
# and not the older Solaris-only version; recent Solaris supports the
# XFree86 style.
# Check for Xinerama extension (Solaris impl or Xfree impl)
mutter_save_cppflags="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
have_xinerama=yes
AC_CHECK_LIB(Xinerama, XineramaQueryExtension,
[AC_CHECK_HEADER(X11/extensions/Xinerama.h,
[X_EXTRA_LIBS="-lXinerama $X_EXTRA_LIBS"
if test -z "`echo $ALL_X_LIBS | grep "\-lXext" 2> /dev/null`"; then
X_EXTRA_LIBS="-lXext $X_EXTRA_LIBS"
fi],
have_xinerama=no,
[#include <X11/Xlib.h>])],
have_xinerama=no, -lXext $ALL_X_LIBS)
AC_MSG_CHECKING(for Xinerama support)
AC_MSG_RESULT($have_xinerama)
AC_ARG_ENABLE(xinerama,
AC_HELP_STRING([--disable-xinerama],
[disable mutter's use of the Xinerama extension]),
try_xinerama=$enable_xinerama,try_xinerama=yes)
use_solaris_xinerama=no
use_xfree_xinerama=no
if test "${try_xinerama}" != no; then
case "$host" in
*-*-solaris*)
# Check for solaris
use_solaris_xinerama=yes
AC_CHECK_LIB(Xext, XineramaGetInfo,
use_solaris_xinerama=yes, use_solaris_xinerama=no,
$ALL_X_LIBS)
if test "x$use_solaris_xinerama" = "xyes"; then
AC_CHECK_HEADER(X11/extensions/xinerama.h,
if test -z "`echo $ALL_X_LIBS | grep "\-lXext" 2> /dev/null`"; then
X_EXTRA_LIBS="-lXext $X_EXTRA_LIBS"
fi
AC_DEFINE(HAVE_SOLARIS_XINERAMA, , [Have Solaris-style Xinerama])
AC_DEFINE(HAVE_XINERAMA, , [Have some version of Xinerama]),
use_solaris_xinerama=no,
[#include <X11/Xlib.h>])
fi
AC_MSG_CHECKING(for Xinerama support on Solaris)
AC_MSG_RESULT($use_solaris_xinerama);
;;
*)
# Check for XFree
use_xfree_xinerama=yes
AC_CHECK_LIB(Xinerama, XineramaQueryExtension,
[AC_CHECK_HEADER(X11/extensions/Xinerama.h,
X_EXTRA_LIBS="-lXinerama $X_EXTRA_LIBS"
if test -z "`echo $ALL_X_LIBS | grep "\-lXext" 2> /dev/null`"; then
X_EXTRA_LIBS="-lXext $X_EXTRA_LIBS"
fi
AC_DEFINE(HAVE_XFREE_XINERAMA, , [Have XFree86-style Xinerama])
AC_DEFINE(HAVE_XINERAMA,, [Have some version of Xinerama]),
use_xfree_xinerama=no,
[#include <X11/Xlib.h>])],
use_xfree_xinerama=no, -lXext $ALL_X_LIBS)
AC_MSG_CHECKING(for Xinerama support on XFree86)
AC_MSG_RESULT($use_xfree_xinerama);
;;
esac
fi
CPPFLAGS="$mutter_save_cppflags"
if test x$have_xinerama = xno; then
AC_MSG_ERROR([Xinerama extension was not found])
fi
SHAPE_LIBS=
found_shape=no
AC_CHECK_LIB(Xext, XShapeQueryExtension,
@@ -305,7 +493,7 @@ fi
MUTTER_LIBS="$MUTTER_LIBS $XSYNC_LIBS $RANDR_LIBS $SHAPE_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS -lm"
MUTTER_MESSAGE_LIBS="$MUTTER_MESSAGE_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
MUTTER_WINDOW_DEMO_LIBS="$MUTTER_WINDOW_DEMO_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS -lm"
MUTTER_WINDOW_DEMO_LIBS="$MUTTER_WINDOW_DEMO_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
MUTTER_PROPS_LIBS="$MUTTER_PROPS_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
found_sm=no
@@ -349,6 +537,18 @@ fi
AC_SUBST(GDK_PIXBUF_CSOURCE)
if test x$enable_gconf = xyes; then
AC_PATH_PROG(GCONFTOOL, gconftool-2, no)
if test x"$GCONFTOOL" = xno; then
AC_MSG_ERROR([gconftool-2 executable not found in your path - should be installed with GConf])
fi
AM_GCONF_SOURCE_2
else
GCONF_SCHEMAS_INSTALL_TRUE='#'
GCONF_SCHEMAS_INSTALL_FALSE=
fi
AC_PATH_PROG(ZENITY, zenity, no)
if test x"$ZENITY" = xno; then
AC_MSG_ERROR([zenity not found in your path - needed for dialogs])
@@ -361,74 +561,13 @@ if test "x$enable_debug" = "xyes"; then
CFLAGS="$CFLAGS -g -O"
fi
# For fix-meta-rectangle.py
AM_PATH_PYTHON([2.5])
#### Warnings (last since -Werror can disturb other tests)
# Stay command-line compatible with the gnome-common configure option. Here
# minimum/yes/maximum are the same, however.
AC_ARG_ENABLE(compile_warnings,
AS_HELP_STRING([--enable-compile-warnings=@<:@no/minimum/yes/maximum/error@:>@],[Turn on compiler warnings]),,
enable_compile_warnings=error)
changequote(,)dnl
if test "$enable_compile_warnings" != no ; then
if test "x$GCC" = "xyes"; then
case " $CFLAGS " in
*[\ \ ]-Wall[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wall" ;;
esac
# case " $CFLAGS " in
# *[\ \ ]-Wshadow[\ \ ]*) ;;
# *) CFLAGS="$CFLAGS -Wshadow" ;;
# esac
case " $CFLAGS " in
*[\ \ ]-Wchar-subscripts[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wchar-subscripts" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wmissing-declarations[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wmissing-declarations" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wmissing-prototypes[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wmissing-prototypes" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wnested-externs[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wnested-externs" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wpointer-arith[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wpointer-arith" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wcast-align[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wcast-align" ;;
esac
case " $CFLAGS " in
*[\ \ ]-Wsign-compare[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Wsign-compare" ;;
esac
if test "$enable_compile_warnings" = error; then
case " $CFLAGS " in
*[\ \ ]-Werror[\ \ ]*) ;;
*) CFLAGS="$CFLAGS -Werror -Wno-error=deprecated-declarations" ;;
esac
fi
fi
# Warnings are there for a reason
if test "x$GCC" = "xyes"; then
CFLAGS="$CFLAGS -Wall -Werror -ansi"
fi
changequote([,])dnl
# Use gnome-doc-utils:
GNOME_DOC_INIT([0.8.0])
AC_CONFIG_FILES([
Makefile
@@ -436,15 +575,22 @@ doc/Makefile
doc/man/Makefile
src/Makefile
src/wm-tester/Makefile
src/libmutter.pc
src/libmutter-private.pc
src/mutter-plugins.pc
src/tools/Makefile
src/compositor/plugins/Makefile
src/compositor/mutter/plugins/Makefile
po/Makefile.in
])
AC_OUTPUT
if test x$enable_gconf = xno; then
echo "*** WARNING WARNING WARNING WARNING WARNING"
echo "*** Building without GConf. This means there's no"
echo "*** way to change prefs except hacking source code."
echo "*** This is intended for embedded systems etc., not for normal use."
fi
if test x$enable_verbose_mode = xno; then
echo "*** WARNING WARNING WARNING WARNING WARNING"
echo "*** Building without verbose mode"
@@ -455,28 +601,33 @@ fi
dnl ==========================================================================
echo "
mutter-$VERSION
mutter-$VERSION:
prefix: ${prefix}
source code location: ${srcdir}
compiler: ${CC}
GConf: ${enable_gconf}
XFree86 Xinerama: ${use_xfree_xinerama}
Solaris Xinerama: ${use_solaris_xinerama}
Startup notification: ${have_startup_notification}
libcanberra: ${have_libcanberra}
Introspection: ${found_introspection}
Compositing manager: ${have_xcomposite}
Introspection: ${have_introspection}
Session management: ${found_sm}
Shape extension: ${found_shape}
Resize-and-rotate: ${found_randr}
Xsync: ${found_xsync}
Render: ${have_xrender}
Xcursor: ${have_xcursor}
Clutter: ${have_clutter}
"
MUTTER_MINOR_VERSION=mutter_minor_version
if expr $MUTTER_MINOR_VERSION % 2 > /dev/null ; then
stable_version=`expr $MUTTER_MINOR_VERSION - 1`
if test $(( $(echo $MUTTER_MINOR_VERSION) %2)) == "1"; then
stable_version=$(( ($MUTTER_MINOR_VERSION / 2) * 2))
echo "This is the UNSTABLE branch of mutter"
echo -n "Use 3.$stable_version.x for stable "
echo "(gnome-3-$stable_version branch in git)"
echo -n "Use 2.$stable_version.x for stable "
echo "(gnome-2-$stable_version branch in Subversion)"
else
echo "This is the stable branch of mutter"
fi

View File

@@ -31,7 +31,8 @@ workspaces. In these cases, there needs to be a rule consistent with
the above about the new window to choose.
Focus method Behavior
click Focus the window on top
click Focus the most recently used window (same as the window
on top)
sloppy Focus the window containing the pointer if there is such
a window, otherwise focus the most recently used window.
mouse Focus the non-DESKTOP window containing the pointer if

View File

@@ -46,13 +46,13 @@ because the original program does not have a manual page.
Restart \fBmutter\fP(1) which is running.
.TP
.B reload-theme
Reload a theme which is specified on gsettings database.
Reload a theme which is specified on gconf database.
.TP
.B enable-keybindings
Enable all of keybindings which is specified on gsettings database.
Enable all of keybindings which is specified on gconf database.
.TP
.B disable-keybindings
Disable all of keybindings which is specified on gsettings database.
Disable all of keybindings which is specified on gconf database.
.SH SEE ALSO
.BR mutter (1)
.SH AUTHOR

View File

@@ -51,7 +51,7 @@ Print the version number.
.B \-?, \-\-help
Show summary of options.
.SH CONFIGURATION
\fBmutter\fP configuration can be found under \fIPreferences\fP->\fIWindows\fP and \fIPreferences\fP->\fIKeyboard Shortcuts\fP on the menu-panel. Advanced configuration can be achieved directly through gsettings.
\fBmutter\fP configuration can be found under \fIPreferences\fP->\fIWindows\fP and \fIPreferences\fP->\fIKeyboard Shortcuts\fP on the menu-panel. Advanced configuration can be achieved directly through gconf editing (gconf-editor or gconftool-2).
.SH SEE ALSO
.BR mutter-message (1)
.SH AUTHOR

View File

@@ -4,7 +4,6 @@ of the theme format, and a given theme can support more than one format.
Version 1: THEMEDIR/metacity-1/metacity-theme-1.xml
(original metacity format)
Version 2: THEMEDIR/metacity-1/metacity-theme-2.xml
Version 3: THEMEDIR/metacity-1/metacity-theme-3.xml
The subdirectory name is "metacity-1" in all versions.
@@ -22,71 +21,6 @@ This document has separate sections for each format version. You may
want to read the document in reverse order, since the base features
are discussed under version 1.
New Features in Theme Format Version 3.4
========================================
An additional color type is added to pick up custom colors defined
in the GTK+ theme's CSS:
gtk:custom(name,fallback)
where <name> refers to a custom color defined with @define-color in
the GTK+ theme, and <fallback> provides an alternative color definition
in case the color referenced by <name> is not found.
New Features in Theme Format Version 3.3
========================================
Add two additional button background functions - left_single_background and
right_single_background - for button groups with just a single button.
There are now additional frame states to style left/right tiled windows
differently ("tiled_left", "tiled_right", "tiled_left_and_shaded",
"tiled_right_and_shaded").
New Features in Theme Format Version 3.2
========================================
A new window type 'attached' is added for modal dialogs which are
attached to their parent window. (When the attach_modal_dialogs preference
is turned on.) If no style is defined for the 'attached' window type,
the 'border' window type will be used instead.
New Features in Theme Format Version 3.1
========================================
Additional predefined variables are added for positioning expressions:
frame_x_center: the X center of the entire frame, with respect to the
piece currently being drawn.
frame_y_center: the Y center of the entire frame, with respect to the
piece currently being drawn.
The <title/> element now supports an "ellipsize_width" attribute. When
specified, this gives a width at which to ellipsize the title. If not
specified, the title will simply be clipped to the title area.
New Features in Theme Format Version 3
======================================
Format version 3 has exactly one new feature; any element in the file
can now have a version attribute:
version="[<|<=|=>|>] MAJOR.MINOR"
(< and > should be to be entity escaped as &lt; and &gt;). If this
version check is not met, then the element and its children will be
ignored. This allows having alternate sections of the theme file for
older and newer version of the Metacity theme format.
When placed on the toplevel <metacity_theme> element, an unsatisfied
version check will not just cause the contents of the file to be
ignored, it will also cause the lookup of a theme file to proceed on
and look for an older format 2 or format 1 file. This allows making a
metacity-theme-3.xml file that is only used the format version 3.2 or
newer is supported, and using metacity-theme-1.xml for older window
managers.
New Features in Theme Format Version 2
======================================

View File

@@ -6,16 +6,6 @@
<name xml:lang="en">mutter</name>
<shortdesc xml:lang="en">Window and compositing manager based on Clutter</shortdesc>
<description>Mutter is a window and compositing manager that displays and
manages your desktop via OpenGL. Mutter combines a sophisticated display engine
using the Clutter toolkit with solid window-management logic inherited from the
Metacity window manager.
While Mutter can be used stand-alone, it is primarily intended to be used as
the display core of a larger system such as GNOME Shell. For this reason,
Mutter is very extensible via plugins, which are used both to add fancy visual
effects and to rework the window management behaviors to meet the needs of the
environment.</description>
<!--
<homepage rdf:resource="http://www.gnome.org/" />
-->
@@ -39,11 +29,4 @@ environment.</description>
<gnome:userid>otaylor</gnome:userid>
</foaf:Person>
</maintainer>
<maintainer>
<foaf:Person>
<foaf:name>Florian Müllner</foaf:name>
<foaf:mbox rdf:resource="mailto:fmuellner@gnome.org" />
<gnome:userid>fmuellner</gnome:userid>
</foaf:Person>
</maintainer>
</Project>

View File

@@ -10,7 +10,6 @@ be@latin
bg
bn
bn_IN
br
bs
ca
ca@valencia
@@ -22,7 +21,6 @@ dz
el
en_CA
en_GB
eo
es
et
eu
@@ -58,7 +56,6 @@ mn
mr
ms
nb
nds
ne
nl
nn
@@ -83,7 +80,6 @@ te
th
tk
tr
ug
uk
vi
wa

View File

@@ -1,17 +1,11 @@
# List of source files containing translatable strings.
# Please keep this file sorted alphabetically.
src/50-mutter-navigation.xml.in
src/50-mutter-system.xml.in
src/50-mutter-windows.xml.in
src/compositor/compositor.c
src/core/bell.c
src/core/core.c
src/core/delete.c
src/core/display.c
src/core/errors.c
src/core/keybindings.c
src/core/main.c
src/core/mutter.c
src/core/prefs.c
src/core/screen.c
src/core/session.c
@@ -19,9 +13,10 @@ src/core/util.c
src/core/window.c
src/core/window-props.c
src/core/xprops.c
src/include/all-keybindings.h
src/mutter.desktop.in
src/mutter-wm.desktop.in
src/org.gnome.mutter.gschema.xml.in
src/mutter.schemas.in
src/tools/mutter-message.c
src/ui/frames.c
src/ui/menu.c

3910
po/ar.po

File diff suppressed because it is too large Load Diff

4140
po/as.po

File diff suppressed because it is too large Load Diff

1951
po/ast.po

File diff suppressed because it is too large Load Diff

3470
po/be.po

File diff suppressed because it is too large Load Diff

2126
po/bg.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1835
po/br.po

File diff suppressed because it is too large Load Diff

3444
po/ca.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2247
po/cs.po

File diff suppressed because it is too large Load Diff

3696
po/da.po

File diff suppressed because it is too large Load Diff

3835
po/de.po

File diff suppressed because it is too large Load Diff

2207
po/el.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1922
po/eo.po

File diff suppressed because it is too large Load Diff

2986
po/es.po

File diff suppressed because it is too large Load Diff

2844
po/et.po

File diff suppressed because it is too large Load Diff

2364
po/eu.po

File diff suppressed because it is too large Load Diff

6282
po/fa.po

File diff suppressed because it is too large Load Diff

2277
po/fi.po

File diff suppressed because it is too large Load Diff

3659
po/fr.po

File diff suppressed because it is too large Load Diff

4018
po/gl.po

File diff suppressed because it is too large Load Diff

2267
po/gu.po

File diff suppressed because it is too large Load Diff

3522
po/he.po

File diff suppressed because it is too large Load Diff

2968
po/hi.po

File diff suppressed because it is too large Load Diff

2433
po/hu.po

File diff suppressed because it is too large Load Diff

4918
po/id.po

File diff suppressed because it is too large Load Diff

2328
po/it.po

File diff suppressed because it is too large Load Diff

2647
po/ja.po

File diff suppressed because it is too large Load Diff

5714
po/kn.po

File diff suppressed because it is too large Load Diff

3278
po/ko.po

File diff suppressed because it is too large Load Diff

3743
po/lt.po

File diff suppressed because it is too large Load Diff

3170
po/lv.po

File diff suppressed because it is too large Load Diff

4490
po/ml.po

File diff suppressed because it is too large Load Diff

3183
po/mr.po

File diff suppressed because it is too large Load Diff

2052
po/nb.po

File diff suppressed because it is too large Load Diff

1814
po/nds.po

File diff suppressed because it is too large Load Diff

2339
po/nl.po

File diff suppressed because it is too large Load Diff

View File

@@ -2456,29 +2456,3 @@ msgstr "y ମୂଲ୍ଯ %d ଥିଲା, %d ପ୍ରତ୍ଯାଶିତ ଥ
msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n"
msgstr "%2$g ସେକଣ୍ଡରେ %1$d ସ୍ଥାନ ନିର୍ଣ୍ଣୟ ଅଭିବ୍ଯକ୍ତି ବିଶ୍ଳେଷିତ (%3$g ସେକଣ୍ଡ ମାଧ୍ଯମାନ)\n"
#: ../src/50-mutter-launchers.xml.in.h:1
#, fuzzy
msgid "Launchers"
msgstr "ପ୍ରାରମ୍ଭକର୍ତ୍ତାମାନେ"
#: ../src/50-mutter-navigation.xml.in.h:1
#, fuzzy
msgid "Navigation"
msgstr "ଅନ୍ୱେଷଣ"
#: ../src/50-mutter-screenshot.xml.in.h:1
#, fuzzy
#| msgid "Take a screenshot"
msgid "Screenshots"
msgstr "ପରଦା ପ୍ରତିଛବିଗୁଡ଼ିକ"
#: ../src/50-mutter-system.xml.in.h:1
#, fuzzy
msgid "System"
msgstr "ତନ୍ତ୍ର"
#: ../src/50-mutter-windows.xml.in.h:1
#, fuzzy
#| msgid "/_Windows"
msgid "Windows"
msgstr "ୱିଣ୍ଡୋମାନ"

3086
po/pa.po

File diff suppressed because it is too large Load Diff

3623
po/pl.po

File diff suppressed because it is too large Load Diff

2932
po/pt.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2866
po/ro.po

File diff suppressed because it is too large Load Diff

3340
po/ru.po

File diff suppressed because it is too large Load Diff

2118
po/sk.po

File diff suppressed because it is too large Load Diff

3157
po/sl.po

File diff suppressed because it is too large Load Diff

3653
po/sr.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2125
po/sv.po

File diff suppressed because it is too large Load Diff

2954
po/ta.po

File diff suppressed because it is too large Load Diff

2732
po/te.po

File diff suppressed because it is too large Load Diff

2680
po/th.po

File diff suppressed because it is too large Load Diff

2762
po/tr.po

File diff suppressed because it is too large Load Diff

2025
po/ug.po

File diff suppressed because it is too large Load Diff

6426
po/uk.po

File diff suppressed because it is too large Load Diff

4538
po/vi.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,77 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<KeyListEntries schema="org.gnome.desktop.wm.keybindings"
group="system"
_name="Navigation"
wm_name="Mutter"
package="mutter">
<KeyListEntry name="move-to-workspace-1"
_description="Move window to workspace 1" />
<KeyListEntry name="move-to-workspace-2"
_description="Move window to workspace 2" />
<KeyListEntry name="move-to-workspace-3"
_description="Move window to workspace 3" />
<KeyListEntry name="move-to-workspace-4"
_description="Move window to workspace 4" />
<KeyListEntry name="move-to-workspace-left"
_description="Move window one workspace to the left" />
<KeyListEntry name="move-to-workspace-right"
_description="Move window one workspace to the right" />
<KeyListEntry name="move-to-workspace-up"
_description="Move window one workspace up" />
<KeyListEntry name="move-to-workspace-down"
_description="Move window one workspace down" />
<KeyListEntry name="switch-windows"
_description="Switch applications"/>
<KeyListEntry name="switch-group"
_description="Switch windows of an application"/>
<KeyListEntry name="switch-panels"
_description="Switch system controls"/>
<KeyListEntry name="cycle-windows"
_description="Switch windows directly"/>
<KeyListEntry name="cycle-group"
_description="Switch windows of an app directly"/>
<KeyListEntry name="cycle-panels"
_description="Switch system controls directly"/>
<KeyListEntry name="show-desktop"
_description="Hide all normal windows"/>
<KeyListEntry name="switch-to-workspace-1"
_description="Switch to workspace 1" />
<KeyListEntry name="switch-to-workspace-2"
_description="Switch to workspace 2" />
<KeyListEntry name="switch-to-workspace-3"
_description="Switch to workspace 3" />
<KeyListEntry name="switch-to-workspace-4"
_description="Switch to workspace 4" />
<KeyListEntry name="switch-to-workspace-left"
_description="Move to workspace left" />
<KeyListEntry name="switch-to-workspace-right"
_description="Move to workspace right" />
<KeyListEntry name="switch-to-workspace-up"
_description="Move to workspace above" />
<KeyListEntry name="switch-to-workspace-down"
_description="Move to workspace below" />
</KeyListEntries>

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<KeyListEntries schema="org.gnome.desktop.wm.keybindings"
group="system"
_name="System"
wm_name="Mutter"
package="mutter">
<KeyListEntry name="panel-run-dialog" _description="Show the run command prompt"/>
<KeyListEntry name="panel-main-menu" _description="Show the activities overview"/>
</KeyListEntries>

View File

@@ -1,50 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<KeyListEntries schema="org.gnome.desktop.wm.keybindings"
group="system"
_name="Windows"
wm_name="Mutter"
package="mutter">
<KeyListEntry name="activate-window-menu" _description="Activate the window menu"/>
<KeyListEntry name="toggle-fullscreen" _description="Toggle fullscreen mode"/>
<KeyListEntry name="toggle-maximized" _description="Toggle maximization state"/>
<KeyListEntry name="maximize" _description="Maximize window"/>
<KeyListEntry name="unmaximize" _description="Restore window"/>
<KeyListEntry name="toggle-shaded" _description="Toggle shaded state"/>
<KeyListEntry name="close" _description="Close window"/>
<KeyListEntry name="minimize" _description="Minimize window"/>
<KeyListEntry name="begin-move" _description="Move window"/>
<KeyListEntry name="begin-resize" _description="Resize window"/>
<KeyListEntry name="toggle-on-all-workspaces"
_description="Toggle window on all workspaces or one"/>
<KeyListEntry name="raise-or-lower" _description="Raise window if covered, otherwise lower it"/>
<KeyListEntry name="raise" _description="Raise window above other windows"/>
<KeyListEntry name="lower" _description="Lower window below other windows"/>
<KeyListEntry name="maximize-vertically" _description="Maximize window vertically"/>
<KeyListEntry name="maximize-horizontally" _description="Maximize window horizontally"/>
<KeyListEntry name="toggle-tiled-left"
schema="org.gnome.mutter.keybindings"
_description="View split on left"/>
<KeyListEntry name="toggle-tiled-right"
schema="org.gnome.mutter.keybindings"
_description="View split on right"/>
</KeyListEntries>

View File

@@ -1,114 +1,71 @@
# Flag build for parallelism; see https://savannah.gnu.org/patch/?6905
.AUTOPARALLEL:
lib_LTLIBRARIES = libmutter-private.la
lib_LTLIBRARIES = libmutter.la
SUBDIRS=wm-tester tools
SUBDIRS=wm-tester tools compositor/plugins
if WITH_CLUTTER
SUBDIRS += compositor/mutter/plugins
endif
INCLUDES= \
$(MUTTER_CFLAGS) \
-I$(srcdir) \
-I$(srcdir)/core \
-I$(srcdir)/ui \
-I$(srcdir)/compositor \
-DMUTTER_LIBEXECDIR=\"$(libexecdir)\" \
-DHOST_ALIAS=\"@HOST_ALIAS@\" \
-DMUTTER_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" \
-DMUTTER_PKGDATADIR=\"$(pkgdatadir)\" \
-DMUTTER_DATADIR=\"$(datadir)\" \
-DG_LOG_DOMAIN=\"mutter\" \
-DSN_API_NOT_YET_FROZEN=1 \
-DMUTTER_MAJOR_VERSION=$(MUTTER_MAJOR_VERSION) \
-DMUTTER_MINOR_VERSION=$(MUTTER_MINOR_VERSION) \
-DMUTTER_MICRO_VERSION=$(MUTTER_MICRO_VERSION) \
-DMUTTER_PLUGIN_API_VERSION=$(MUTTER_PLUGIN_API_VERSION) \
-DMUTTER_PKGLIBDIR=\"$(pkglibdir)\" \
-DMUTTER_PLUGIN_DIR=\"@MUTTER_PLUGIN_DIR@\" \
-DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\"
INCLUDES=@MUTTER_CFLAGS@ -I $(srcdir)/include -I$(srcdir)/compositor -DMUTTER_LIBEXECDIR=\"$(libexecdir)\" -DHOST_ALIAS=\"@HOST_ALIAS@\" -DMUTTER_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" -DMUTTER_PKGDATADIR=\"$(pkgdatadir)\" -DMUTTER_DATADIR=\"$(datadir)\" -DG_LOG_DOMAIN=\"mutter\" -DSN_API_NOT_YET_FROZEN=1 -DMUTTER_MAJOR_VERSION=$(MUTTER_MAJOR_VERSION) -DMUTTER_MINOR_VERSION=$(MUTTER_MINOR_VERSION) -DMUTTER_MICRO_VERSION=$(MUTTER_MICRO_VERSION) -DMUTTER_PLUGIN_API_VERSION=$(MUTTER_PLUGIN_API_VERSION) -DMUTTER_PKGLIBDIR=\"$(pkglibdir)\" -DMUTTER_PLUGIN_DIR=\"@MUTTER_PLUGIN_DIR@\"
mutter_built_sources = \
mutter-enum-types.h \
mutter-enum-types.c
libmutter_la_SOURCES = \
mutter_SOURCES= \
core/async-getprop.c \
core/async-getprop.h \
core/alttabhandler.c \
include/alttabhandler.h \
core/alttabhandlerdefault.c \
include/alttabhandlerdefault.h \
core/bell.c \
core/bell.h \
core/boxes.c \
core/boxes-private.h \
meta/boxes.h \
compositor/cogl-utils.c \
compositor/cogl-utils.h \
include/boxes.h \
compositor/compositor.c \
compositor/compositor-private.h \
compositor/meta-background-actor.c \
compositor/meta-background-actor-private.h \
compositor/meta-module.c \
compositor/meta-module.h \
compositor/meta-plugin.c \
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-texture-rectangle.c \
compositor/meta-texture-rectangle.h \
compositor/meta-texture-tower.c \
compositor/meta-texture-tower.h \
compositor/meta-window-actor.c \
compositor/meta-window-actor-private.h \
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 \
meta/meta-background-actor.h \
meta/meta-plugin.h \
meta/meta-shadow-factory.h \
meta/meta-window-actor.h \
meta/compositor-mutter.h \
core/above-tab-keycode.c \
compositor/compositor-xrender.c \
compositor/compositor-xrender.h \
include/compositor.h \
core/constraints.c \
core/constraints.h \
core/core.c \
core/delete.c \
core/display.c \
core/display-private.h \
meta/display.h \
include/display.h \
ui/draw-workspace.c \
ui/draw-workspace.h \
core/edge-resistance.c \
core/edge-resistance.h \
core/effects.c \
core/effects.h \
core/errors.c \
meta/errors.h \
include/errors.h \
core/eventqueue.c \
core/eventqueue.h \
core/frame.c \
core/frame.h \
core/frame-private.h \
include/frame.h \
ui/gradient.c \
meta/gradient.h \
ui/gradient.h \
core/group-private.h \
core/group-props.c \
core/group-props.h \
core/group.c \
meta/group.h \
include/group.h \
core/iconcache.c \
core/iconcache.h \
core/keybindings.c \
core/keybindings-private.h \
core/main.c \
core/mutter-Xatomtype.h \
include/main.h \
core/mutter-Xatomtype.h \
core/place.c \
core/place.h \
core/prefs.c \
meta/prefs.h \
include/prefs.h \
core/screen.c \
core/screen-private.h \
meta/screen.h \
meta/types.h \
include/screen.h \
include/types.h \
core/session.c \
core/session.h \
core/stack.c \
@@ -116,20 +73,22 @@ libmutter_la_SOURCES = \
core/stack-tracker.c \
core/stack-tracker.h \
core/util.c \
meta/util.h \
include/util.h \
core/window-props.c \
core/window-props.h \
core/window.c \
core/window-private.h \
meta/window.h \
include/window.h \
core/workspace.c \
core/workspace-private.h \
core/xprops.c \
core/xprops.h \
meta/common.h \
core/core.h \
ui/ui.h \
include/xprops.h \
include/common.h \
include/core.h \
include/ui.h \
inlinepixbufs.h \
ui/fixedtip.c \
ui/fixedtip.h \
ui/frames.c \
ui/frames.h \
ui/menu.c \
@@ -137,56 +96,81 @@ libmutter_la_SOURCES = \
ui/metaaccellabel.c \
ui/metaaccellabel.h \
ui/resizepopup.c \
ui/resizepopup.h \
include/resizepopup.h \
ui/tabpopup.c \
ui/tabpopup.h \
ui/tile-preview.c \
ui/tile-preview.h \
include/tabpopup.h \
ui/theme-parser.c \
ui/theme-parser.h \
ui/theme.c \
meta/theme.h \
ui/theme-private.h \
ui/theme.h \
ui/themewidget.c \
ui/themewidget.h \
ui/ui.c \
meta/preview-widget.h \
include/all-keybindings.h
if WITH_CLUTTER
mutter_SOURCES += \
compositor/mutter/compositor-mutter.c \
compositor/mutter/mutter-shaped-texture.c \
compositor/mutter/mutter-shaped-texture.h \
compositor/mutter/mutter-plugin-manager.c \
compositor/mutter/mutter-plugin-manager.h \
compositor/mutter/tidy/tidy-texture-frame.c \
compositor/mutter/tidy/tidy-texture-frame.h \
compositor/mutter/mutter-module.c \
compositor/mutter/mutter-module.h \
compositor/mutter/mutter-plugin.c \
include/mutter-plugin.h \
include/compositor-mutter.h
endif
# by setting libmutter_private_la_CFLAGS, the files shared with
# mutter proper will be compiled with different names.
libmutter_private_la_CFLAGS =
libmutter_private_la_SOURCES= \
core/boxes.c \
include/boxes.h \
ui/gradient.c \
ui/gradient.h \
core/util.c \
include/util.h \
include/common.h \
ui/preview-widget.c \
$(mutter_built_sources)
ui/preview-widget.h \
ui/theme-parser.c \
ui/theme-parser.h \
ui/theme.c \
ui/theme.h
libmutter_la_LDFLAGS = -no-undefined
libmutter_la_LIBADD = $(MUTTER_LIBS)
libmutter_private_la_LDFLAGS = -no-undefined
libmutter_private_la_LIBADD = @MUTTER_LIBS@
libmutterincludedir = $(includedir)/mutter/mutter-private
# Headers installed for plugins; introspected information will
# be extracted into Mutter-<version>.gir
libmutterinclude_base_headers = \
meta/boxes.h \
meta/common.h \
meta/compositor-mutter.h \
meta/compositor.h \
meta/display.h \
meta/errors.h \
meta/gradient.h \
meta/group.h \
meta/keybindings.h \
meta/main.h \
meta/meta-background-actor.h \
meta/meta-plugin.h \
meta/meta-shaped-texture.h \
meta/meta-shadow-factory.h \
meta/meta-window-actor.h \
meta/prefs.h \
meta/screen.h \
meta/theme.h \
meta/types.h \
meta/util.h \
meta/window.h \
meta/workspace.h
include/alttabhandler.h \
include/boxes.h \
ui/gradient.h \
include/util.h \
include/common.h \
ui/preview-widget.h \
ui/theme-parser.h \
ui/theme.h \
include/prefs.h \
include/window.h \
include/workspace.h \
include/compositor.h \
include/compositor-mutter.h \
include/types.h \
include/screen.h \
include/display.h \
include/group.h \
include/keybindings.h \
include/mutter-plugin.h
# Excluded from scanning for introspection but installed
# atomnames.h: macros cause problems for scanning process
libmutterinclude_extra_headers = \
meta/preview-widget.h \
meta/atomnames.h
libmutterincludedir = $(includedir)/mutter/meta
include/atomnames.h
libmutterinclude_HEADERS = \
$(libmutterinclude_base_headers) \
@@ -197,18 +181,9 @@ mutter_theme_viewer_SOURCES= \
bin_PROGRAMS=mutter mutter-theme-viewer
mutter_SOURCES = core/mutter.c
mutter_LDADD = $(MUTTER_LIBS) libmutter.la
if HAVE_INTROSPECTION
include $(INTROSPECTION_MAKEFILE)
# Since we don't make any guarantees about stability and we don't support
# parallel install, there's no real reason to change directories, filenames,
# etc. as we change the Mutter tarball version.
#api_version = $(MUTTER_MAJOR_VERSION).$(MUTTER_MINOR_VERSION)
api_version = 3.0
api_version = $(MUTTER_MAJOR_VERSION).$(MUTTER_MINOR_VERSION)
if WITH_INTROSPECTION
# These files are in package-private directories, even though they may be used
# by plugins. If you're writing a plugin, use g-ir-compiler --add-include-path
# and g-ir-compiler --includedir.
@@ -218,32 +193,44 @@ gir_DATA = Meta-$(api_version).gir
typelibdir = $(pkglibdir)
typelib_DATA = Meta-$(api_version).typelib
INTROSPECTION_GIRS = Meta-$(api_version).gir
Meta-$(api_version).gir: libmutter.la
@META_GIR@_INCLUDES = GObject-2.0 GDesktopEnums-3.0 Gdk-3.0 Gtk-3.0 Clutter-1.0 xlib-2.0 xfixes-4.0 Cogl-1.0
@META_GIR@_EXPORT_PACKAGES = libmutter
@META_GIR@_CFLAGS = $(INCLUDES)
@META_GIR@_LIBS = libmutter.la
@META_GIR@_FILES = \
mutter-enum-types.h \
$(libmutterinclude_base_headers) \
$(filter %.c,$(libmutter_la_SOURCES))
@META_GIR@_SCANNERFLAGS = --warn-all --warn-error
# We need to strip out the attribute that would point back to libmutter-introspect
# so that libgirepository looks for symbols in the executable instead
Meta-$(api_version).gir: $(G_IR_SCANNER) mutter $(libmutterinclude_HEADERS) $(mutter_SOURCES)
$(G_IR_SCANNER) \
--namespace=Meta \
--nsversion=$(api_version) \
--include=GObject-2.0 \
--include=Gdk-2.0 \
--include=Gtk-2.0 \
--include=Clutter-0.9 \
--pkg=clutter-0.9 \
--pkg=gtk+-2.0 \
--include=xfixes-4.0 \
--program=./mutter \
$(filter %.c,$(mutter_SOURCES)) \
$(libmutterinclude_base_headers) \
$(INCLUDES) \
-o $@
Meta-$(api_version).typelib: $(G_IR_COMPILER) Meta-$(api_version).gir
LD_LIBRARY_PATH=$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}. $(G_IR_COMPILER) Meta-$(api_version).gir -o $@
endif
mutter_theme_viewer_LDADD= $(MUTTER_LIBS) libmutter.la
EFENCE=
mutter_LDADD=@MUTTER_LIBS@ libmutter-private.la $(EFENCE)
mutter_LDFLAGS=-export-dynamic
testboxes_SOURCES = core/testboxes.c
testgradient_SOURCES = ui/testgradient.c
testasyncgetprop_SOURCES = core/testasyncgetprop.c
mutter_theme_viewer_LDADD= @MUTTER_LIBS@ libmutter-private.la
testboxes_SOURCES=include/util.h core/util.c include/boxes.h core/boxes.c core/testboxes.c
testgradient_SOURCES=ui/gradient.h ui/gradient.c ui/testgradient.c
testasyncgetprop_SOURCES=core/async-getprop.h core/async-getprop.c core/testasyncgetprop.c
noinst_PROGRAMS=testboxes testgradient testasyncgetprop
testboxes_LDADD = $(MUTTER_LIBS) libmutter.la
testgradient_LDADD = $(MUTTER_LIBS) libmutter.la
testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter.la
testboxes_LDADD= @MUTTER_LIBS@ libmutter-private.la
testgradient_LDADD= @MUTTER_LIBS@ libmutter-private.la
testasyncgetprop_LDADD= @MUTTER_LIBS@ libmutter-private.la
@INTLTOOL_DESKTOP_RULE@
@@ -257,19 +244,20 @@ wmproperties_in_files=mutter-wm.desktop.in
wmproperties_files=$(wmproperties_in_files:.desktop.in=.desktop)
wmproperties_DATA = $(wmproperties_files)
xmldir = @GNOME_KEYBINDINGS_KEYSDIR@
xml_in_files = \
50-mutter-navigation.xml.in \
50-mutter-system.xml.in \
50-mutter-windows.xml.in
xml_DATA = $(xml_in_files:.xml.in=.xml)
schemadir = @GCONF_SCHEMA_FILE_DIR@
schema_in_files = mutter.schemas.in
schema_DATA = $(schema_in_files:.schemas.in=.schemas)
gsettings_SCHEMAS = org.gnome.mutter.gschema.xml
@INTLTOOL_XML_NOMERGE_RULE@
@GSETTINGS_RULES@
convertdir = $(datadir)/GConf/gsettings
convert_DATA = mutter-schemas.convert
@INTLTOOL_SCHEMAS_RULE@
if GCONF_SCHEMAS_INSTALL
install-data-local:
GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(schema_DATA)
else
install-data-local:
endif
IMAGES=stock_maximize.png stock_minimize.png stock_delete.png
VARIABLES=stock_maximize_data $(srcdir)/stock_maximize.png \
@@ -277,55 +265,21 @@ VARIABLES=stock_maximize_data $(srcdir)/stock_maximize.png \
stock_delete_data $(srcdir)/stock_delete.png
BUILT_SOURCES = inlinepixbufs.h
CLEANFILES = \
inlinepixbufs.h \
mutter.desktop \
mutter-wm.desktop \
org.gnome.mutter.gschema.xml \
$(xml_DATA) \
$(mutter_built_sources) \
$(typelib_DATA) \
$(gir_DATA)
CLEANFILES = inlinepixbufs.h mutter.desktop mutter-wm.desktop mutter.schemas
inlinepixbufs.h: $(IMAGES)
$(GDK_PIXBUF_CSOURCE) --raw --build-list $(VARIABLES) >$(srcdir)/inlinepixbufs.h
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libmutter.pc mutter-plugins.pc
pkgconfig_DATA = libmutter-private.pc mutter-plugins.pc
EXTRA_DIST=$(desktopfiles_files) \
$(wmproperties_files) \
$(IMAGES) \
$(IMAGES) $(schema_DATA) \
$(desktopfiles_in_files) \
$(wmproperties_in_files) \
$(xml_in_files) \
org.gnome.mutter.gschema.xml.in \
mutter-schemas.convert \
libmutter.pc.in \
mutter-plugins.pc.in \
mutter-enum-types.h.in \
mutter-enum-types.c.in
$(schema_in_files) \
libmutter-private.pc.in \
mutter-plugins.pc.in
BUILT_SOURCES += $(mutter_built_sources)
MUTTER_STAMP_FILES = stamp-mutter-enum-types.h
CLEANFILES += $(MUTTER_STAMP_FILES)
mutter-enum-types.h: stamp-mutter-enum-types.h Makefile
@true
stamp-mutter-enum-types.h: $(libmutterinclude_base_headers) mutter-enum-types.h.in
$(AM_V_GEN) ( cd $(srcdir) && \
$(GLIB_MKENUMS) \
--template mutter-enum-types.h.in \
$(libmutterinclude_base_headers) ) >> xgen-teth && \
(cmp -s xgen-teth mutter-enum-types.h || cp xgen-teth mutter-enum-types.h) && \
rm -f xgen-teth && \
echo timestamp > $(@F)
mutter-enum-types.c: stamp-mutter-enum-types.h mutter-enum-types.c.in
$(AM_V_GEN) ( cd $(srcdir) && \
$(GLIB_MKENUMS) \
--template mutter-enum-types.c.in \
$(libmutterinclude_base_headers) ) >> xgen-tetc && \
cp xgen-tetc mutter-enum-types.c && \
rm -f xgen-tetc

View File

@@ -1,110 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Utilities for use with Cogl
*
* Copyright 2010 Red Hat, Inc.
* Copyright 2010 Intel Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include "cogl-utils.h"
/**
* meta_create_color_texture_4ub:
* @red:
* @green:
* @blue:
* @alpha:
* @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE;
* %COGL_TEXTURE_NO_SLICING is useful if the texture will be
* repeated to create a constant color fill, since hardware
* repeat can't be used for a sliced texture.
*
* Creates a texture that is a single pixel with the specified
* unpremultiplied color components.
*
* Return value: (transfer full): a newly created Cogl texture
*/
CoglHandle
meta_create_color_texture_4ub (guint8 red,
guint8 green,
guint8 blue,
guint8 alpha,
CoglTextureFlags flags)
{
CoglColor color;
guint8 pixel[4];
cogl_color_set_from_4ub (&color, red, green, blue, alpha);
cogl_color_premultiply (&color);
pixel[0] = cogl_color_get_red_byte (&color);
pixel[1] = cogl_color_get_green_byte (&color);
pixel[2] = cogl_color_get_blue_byte (&color);
pixel[3] = cogl_color_get_alpha_byte (&color);
return cogl_texture_new_from_data (1, 1,
flags,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
COGL_PIXEL_FORMAT_ANY,
4, pixel);
}
/* Based on gnome-shell/src/st/st-private.c:_st_create_texture_material.c */
/**
* meta_create_texture_material:
* @src_texture: (allow-none): texture to use initially for the layer
*
* Creates a material with a single layer. Using a common template
* allows sharing a shader for different uses in Mutter. To share the same
* shader with all other materials that are just texture plus opacity
* would require Cogl fixes.
* (See http://bugzilla.clutter-project.org/show_bug.cgi?id=2425)
*
* Return value: (transfer full): a newly created Cogl material
*/
CoglHandle
meta_create_texture_material (CoglHandle src_texture)
{
static CoglHandle texture_material_template = COGL_INVALID_HANDLE;
CoglHandle material;
/* We use a material that has a dummy texture as a base for all
texture materials. The idea is that only the Cogl texture object
would be different in the children so it is likely that Cogl will
be able to share GL programs between all the textures. */
if (G_UNLIKELY (texture_material_template == COGL_INVALID_HANDLE))
{
CoglHandle dummy_texture;
dummy_texture = meta_create_color_texture_4ub (0xff, 0xff, 0xff, 0xff,
COGL_TEXTURE_NONE);
texture_material_template = cogl_material_new ();
cogl_material_set_layer (texture_material_template, 0, dummy_texture);
cogl_handle_unref (dummy_texture);
}
material = cogl_material_copy (texture_material_template);
if (src_texture != COGL_INVALID_HANDLE)
cogl_material_set_layer (material, 0, src_texture);
return material;
}

View File

@@ -1,71 +1,90 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2008 Iain Holmes
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef META_COMPOSITOR_PRIVATE_H
#define META_COMPOSITOR_PRIVATE_H
#include <X11/extensions/Xfixes.h>
#include <meta/compositor.h>
#include <meta/display.h>
#include "meta-plugin-manager.h"
#include "meta-window-actor-private.h"
#include <clutter/clutter.h>
typedef struct _MetaCompScreen MetaCompScreen;
#include "compositor.h"
struct _MetaCompositor
{
MetaDisplay *display;
void (* destroy) (MetaCompositor *compositor);
Atom atom_x_root_pixmap;
Atom atom_x_set_root;
Atom atom_net_wm_window_opacity;
guint repaint_func_id;
ClutterActor *shadow_src;
MetaPlugin *modal_plugin;
gboolean show_redraw : 1;
gboolean debug : 1;
gboolean no_mipmaps : 1;
void (*manage_screen) (MetaCompositor *compositor,
MetaScreen *screen);
void (*unmanage_screen) (MetaCompositor *compositor,
MetaScreen *screen);
void (*add_window) (MetaCompositor *compositor,
MetaWindow *window);
void (*remove_window) (MetaCompositor *compositor,
MetaWindow *window);
void (*set_updates) (MetaCompositor *compositor,
MetaWindow *window,
gboolean update);
gboolean (*process_event) (MetaCompositor *compositor,
XEvent *event,
MetaWindow *window);
Pixmap (*get_window_pixmap) (MetaCompositor *compositor,
MetaWindow *window);
void (*set_active_window) (MetaCompositor *compositor,
MetaScreen *screen,
MetaWindow *window);
void (*map_window) (MetaCompositor *compositor,
MetaWindow *window);
void (*unmap_window) (MetaCompositor *compositor,
MetaWindow *window);
void (*minimize_window) (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *window_rect,
MetaRectangle *icon_rect);
void (*unminimize_window) (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *window_rect,
MetaRectangle *icon_rect);
void (*maximize_window) (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *window_rect);
void (*unmaximize_window) (MetaCompositor *compositor,
MetaWindow *window,
MetaRectangle *window_rect);
void (*update_workspace_geometry) (MetaCompositor *compositor,
MetaWorkspace *workspace);
void (*switch_workspace) (MetaCompositor *compositor,
MetaScreen *screen,
MetaWorkspace *from,
MetaWorkspace *to,
MetaMotionDirection direction);
void (*sync_stack) (MetaCompositor *compositor,
MetaScreen *screen,
GList *stack);
void (*set_window_hidden) (MetaCompositor *compositor,
MetaScreen *screen,
MetaWindow *window,
gboolean hidden);
void (*sync_window_geometry) (MetaCompositor *compositor,
MetaWindow *window);
void (*sync_screen_size) (MetaCompositor *compositor,
MetaScreen *screen,
guint width,
guint height);
};
struct _MetaCompScreen
{
MetaScreen *screen;
ClutterActor *stage, *window_group, *overlay_group;
ClutterActor *background_actor;
ClutterActor *hidden_group;
GList *windows;
GHashTable *windows_by_xid;
Window output;
/* Used for unredirecting fullscreen windows */
guint disable_unredirect_count;
MetaWindowActor *unredirected_window;
/* Before we create the output window */
XserverRegion pending_input_region;
gint switch_workspace_in_progress;
MetaPluginManager *plugin_mgr;
};
void meta_switch_workspace_completed (MetaScreen *screen);
gboolean meta_begin_modal_for_plugin (MetaScreen *screen,
MetaPlugin *plugin,
Window grab_window,
Cursor cursor,
MetaModalOptions options,
guint32 timestamp);
void meta_end_modal_for_plugin (MetaScreen *screen,
MetaPlugin *plugin,
guint32 timestamp);
void meta_check_end_modal (MetaScreen *screen);
#endif /* META_COMPOSITOR_PRIVATE_H */
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,10 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* Meta tile preview */
/*
* Copyright (C) 2010 Florian Müllner
*
/*
* Copyright (C) 2007 Iain Holmes
* Based on xcompmgr - (c) 2003 Keith Packard
* xfwm4 - (c) 2005-2007 Olivier Fourdan
*
* 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
@@ -14,25 +14,18 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef META_TILE_PREVIEW_H
#define META_TILE_PREVIEW_H
#include <meta/boxes.h>
#ifndef META_COMPOSITOR_XRENDER_H_
#define META_COMPOSITOR_XRENDER_H_
typedef struct _MetaTilePreview MetaTilePreview;
#include "types.h"
MetaTilePreview *meta_tile_preview_new (int screen_number);
void meta_tile_preview_free (MetaTilePreview *preview);
void meta_tile_preview_show (MetaTilePreview *preview,
MetaRectangle *rect);
void meta_tile_preview_hide (MetaTilePreview *preview);
Window meta_tile_preview_get_xwindow (MetaTilePreview *preview,
gulong *create_serial);
MetaCompositor *meta_compositor_xrender_new (MetaDisplay *display);
#endif /* META_TILE_PREVIEW_H */
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#ifndef META_BACKGROUND_ACTOR_PRIVATE_H
#define META_BACKGROUND_ACTOR_PRIVATE_H
#include <meta/screen.h>
#include <meta/meta-background-actor.h>
void meta_background_actor_set_visible_region (MetaBackgroundActor *self,
cairo_region_t *visible_region);
void meta_background_actor_update (MetaScreen *screen);
void meta_background_actor_screen_size_changed (MetaScreen *screen);
#endif /* META_BACKGROUND_ACTOR_PRIVATE_H */

View File

@@ -1,705 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* meta-background-actor.c: Actor for painting the root window background
*
* Copyright 2009 Sander Dijkhuis
* Copyright 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Portions adapted from gnome-shell/src/shell-global.c
*/
#include <config.h>
#define COGL_ENABLE_EXPERIMENTAL_API
#include <cogl/cogl-texture-pixmap-x11.h>
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#include <clutter/clutter.h>
#include <X11/Xatom.h>
#include "cogl-utils.h"
#include "compositor-private.h"
#include <meta/errors.h>
#include "meta-background-actor-private.h"
/* We allow creating multiple MetaBackgroundActors for the same MetaScreen to
* allow different rendering options to be set for different copies.
* But we want to share the same underlying CoglTexture for efficiency and
* to avoid driver bugs that might occur if we created multiple CoglTexturePixmaps
* for the same pixmap.
*
* This structure holds common information.
*/
typedef struct _MetaScreenBackground MetaScreenBackground;
struct _MetaScreenBackground
{
MetaScreen *screen;
GSList *actors;
float texture_width;
float texture_height;
CoglTexture *texture;
CoglMaterialWrapMode wrap_mode;
guint have_pixmap : 1;
};
struct _MetaBackgroundActorPrivate
{
MetaScreenBackground *background;
CoglPipeline *pipeline;
cairo_region_t *visible_region;
float dim_factor;
};
enum
{
PROP_0,
PROP_DIM_FACTOR,
PROP_LAST
};
static GParamSpec *obj_props[PROP_LAST];
G_DEFINE_TYPE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR);
static void set_texture (MetaScreenBackground *background,
CoglHandle texture);
static void set_texture_to_stage_color (MetaScreenBackground *background);
static void
on_notify_stage_color (GObject *stage,
GParamSpec *pspec,
MetaScreenBackground *background)
{
if (!background->have_pixmap)
set_texture_to_stage_color (background);
}
static void
free_screen_background (MetaScreenBackground *background)
{
set_texture (background, COGL_INVALID_HANDLE);
if (background->screen != NULL)
{
ClutterActor *stage = meta_get_stage_for_screen (background->screen);
g_signal_handlers_disconnect_by_func (stage,
(gpointer) on_notify_stage_color,
background);
background->screen = NULL;
}
}
static MetaScreenBackground *
meta_screen_background_get (MetaScreen *screen)
{
MetaScreenBackground *background;
background = g_object_get_data (G_OBJECT (screen), "meta-screen-background");
if (background == NULL)
{
ClutterActor *stage;
background = g_new0 (MetaScreenBackground, 1);
background->screen = screen;
g_object_set_data_full (G_OBJECT (screen), "meta-screen-background",
background, (GDestroyNotify) free_screen_background);
stage = meta_get_stage_for_screen (screen);
g_signal_connect (stage, "notify::color",
G_CALLBACK (on_notify_stage_color), background);
meta_background_actor_update (screen);
}
return background;
}
static void
update_wrap_mode_of_actor (MetaBackgroundActor *self)
{
MetaBackgroundActorPrivate *priv = self->priv;
cogl_pipeline_set_layer_wrap_mode (priv->pipeline, 0, priv->background->wrap_mode);
}
static void
update_wrap_mode (MetaScreenBackground *background)
{
GSList *l;
int width, height;
meta_screen_get_size (background->screen, &width, &height);
/* We turn off repeating when we have a full-screen pixmap to keep from
* getting artifacts from one side of the image sneaking into the other
* side of the image via bilinear filtering.
*/
if (width == background->texture_width && height == background->texture_height)
background->wrap_mode = COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE;
else
background->wrap_mode = COGL_MATERIAL_WRAP_MODE_REPEAT;
for (l = background->actors; l; l = l->next)
update_wrap_mode_of_actor (l->data);
}
static void
set_texture_on_actor (MetaBackgroundActor *self)
{
MetaBackgroundActorPrivate *priv = self->priv;
MetaDisplay *display = meta_screen_get_display (priv->background->screen);
/* This may trigger destruction of an old texture pixmap, which, if
* the underlying X pixmap is already gone has the tendency to trigger
* X errors inside DRI. For safety, trap errors */
meta_error_trap_push (display);
cogl_pipeline_set_layer_texture (priv->pipeline, 0, priv->background->texture);
meta_error_trap_pop (display);
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
}
static void
set_texture (MetaScreenBackground *background,
CoglHandle texture)
{
MetaDisplay *display = meta_screen_get_display (background->screen);
GSList *l;
/* This may trigger destruction of an old texture pixmap, which, if
* the underlying X pixmap is already gone has the tendency to trigger
* X errors inside DRI. For safety, trap errors */
meta_error_trap_push (display);
if (background->texture != COGL_INVALID_HANDLE)
{
cogl_handle_unref (background->texture);
background->texture = COGL_INVALID_HANDLE;
}
meta_error_trap_pop (display);
if (texture != COGL_INVALID_HANDLE)
background->texture = cogl_handle_ref (texture);
background->texture_width = cogl_texture_get_width (background->texture);
background->texture_height = cogl_texture_get_height (background->texture);
for (l = background->actors; l; l = l->next)
set_texture_on_actor (l->data);
update_wrap_mode (background);
}
/* Sets our pipeline to paint with a 1x1 texture of the stage's background
* color; doing this when we have no pixmap allows the application to turn
* off painting the stage. There might be a performance benefit to
* painting in this case with a solid color, but the normal solid color
* case is a 1x1 root pixmap, so we'd have to reverse-engineer that to
* actually pick up the (small?) performance win. This is just a fallback.
*/
static void
set_texture_to_stage_color (MetaScreenBackground *background)
{
ClutterActor *stage = meta_get_stage_for_screen (background->screen);
ClutterColor color;
CoglHandle texture;
clutter_stage_get_color (CLUTTER_STAGE (stage), &color);
/* Slicing will prevent COGL from using hardware texturing for
* the tiled 1x1 pixmap, and will cause it to draw the window
* background in millions of separate 1x1 rectangles */
texture = meta_create_color_texture_4ub (color.red, color.green,
color.blue, 0xff,
COGL_TEXTURE_NO_SLICING);
set_texture (background, texture);
cogl_handle_unref (texture);
}
static void
meta_background_actor_dispose (GObject *object)
{
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object);
MetaBackgroundActorPrivate *priv = self->priv;
meta_background_actor_set_visible_region (self, NULL);
if (priv->background != NULL)
{
priv->background->actors = g_slist_remove (priv->background->actors, self);
priv->background = NULL;
}
g_clear_pointer(&priv->pipeline, cogl_object_unref);
G_OBJECT_CLASS (meta_background_actor_parent_class)->dispose (object);
}
static void
meta_background_actor_get_preferred_width (ClutterActor *actor,
gfloat for_height,
gfloat *min_width_p,
gfloat *natural_width_p)
{
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (actor);
MetaBackgroundActorPrivate *priv = self->priv;
int width, height;
meta_screen_get_size (priv->background->screen, &width, &height);
if (min_width_p)
*min_width_p = width;
if (natural_width_p)
*natural_width_p = width;
}
static void
meta_background_actor_get_preferred_height (ClutterActor *actor,
gfloat for_width,
gfloat *min_height_p,
gfloat *natural_height_p)
{
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (actor);
MetaBackgroundActorPrivate *priv = self->priv;
int width, height;
meta_screen_get_size (priv->background->screen, &width, &height);
if (min_height_p)
*min_height_p = height;
if (natural_height_p)
*natural_height_p = height;
}
static void
meta_background_actor_paint (ClutterActor *actor)
{
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (actor);
MetaBackgroundActorPrivate *priv = self->priv;
guint8 opacity = clutter_actor_get_paint_opacity (actor);
guint8 color_component;
int width, height;
meta_screen_get_size (priv->background->screen, &width, &height);
color_component = (int)(0.5 + opacity * priv->dim_factor);
cogl_pipeline_set_color4ub (priv->pipeline,
color_component,
color_component,
color_component,
opacity);
cogl_set_source (priv->pipeline);
if (priv->visible_region)
{
int n_rectangles = cairo_region_num_rectangles (priv->visible_region);
int i;
for (i = 0; i < n_rectangles; i++)
{
cairo_rectangle_int_t rect;
cairo_region_get_rectangle (priv->visible_region, i, &rect);
cogl_rectangle_with_texture_coords (rect.x, rect.y,
rect.x + rect.width, rect.y + rect.height,
rect.x / priv->background->texture_width,
rect.y / priv->background->texture_height,
(rect.x + rect.width) / priv->background->texture_width,
(rect.y + rect.height) / priv->background->texture_height);
}
}
else
{
cogl_rectangle_with_texture_coords (0.0f, 0.0f,
width, height,
0.0f, 0.0f,
width / priv->background->texture_width,
height / priv->background->texture_height);
}
}
static gboolean
meta_background_actor_get_paint_volume (ClutterActor *actor,
ClutterPaintVolume *volume)
{
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (actor);
MetaBackgroundActorPrivate *priv = self->priv;
int width, height;
meta_screen_get_size (priv->background->screen, &width, &height);
clutter_paint_volume_set_width (volume, width);
clutter_paint_volume_set_height (volume, height);
return TRUE;
}
static void
meta_background_actor_set_dim_factor (MetaBackgroundActor *self,
gfloat dim_factor)
{
MetaBackgroundActorPrivate *priv = self->priv;
if (priv->dim_factor == dim_factor)
return;
priv->dim_factor = dim_factor;
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_DIM_FACTOR]);
}
static void
meta_background_actor_get_property(GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object);
MetaBackgroundActorPrivate *priv = self->priv;
switch (prop_id)
{
case PROP_DIM_FACTOR:
g_value_set_float (value, priv->dim_factor);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
meta_background_actor_set_property(GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object);
switch (prop_id)
{
case PROP_DIM_FACTOR:
meta_background_actor_set_dim_factor (self, g_value_get_float (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
meta_background_actor_class_init (MetaBackgroundActorClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
GParamSpec *pspec;
g_type_class_add_private (klass, sizeof (MetaBackgroundActorPrivate));
object_class->dispose = meta_background_actor_dispose;
object_class->get_property = meta_background_actor_get_property;
object_class->set_property = meta_background_actor_set_property;
actor_class->get_preferred_width = meta_background_actor_get_preferred_width;
actor_class->get_preferred_height = meta_background_actor_get_preferred_height;
actor_class->paint = meta_background_actor_paint;
actor_class->get_paint_volume = meta_background_actor_get_paint_volume;
/**
* MetaBackgroundActor:dim-factor:
*
* Factor to dim the background by, between 0.0 (black) and 1.0 (original
* colors)
*/
pspec = g_param_spec_float ("dim-factor",
"Dim factor",
"Factor to dim the background by",
0.0, 1.0,
1.0,
G_PARAM_READWRITE);
obj_props[PROP_DIM_FACTOR] = pspec;
g_object_class_install_property (object_class, PROP_DIM_FACTOR, pspec);
}
static void
meta_background_actor_init (MetaBackgroundActor *self)
{
MetaBackgroundActorPrivate *priv;
priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
META_TYPE_BACKGROUND_ACTOR,
MetaBackgroundActorPrivate);
priv->dim_factor = 1.0;
}
/**
* meta_background_actor_new:
* @screen: the #MetaScreen
*
* Creates a new actor to draw the background for the given screen.
*
* Return value: the newly created background actor
*/
ClutterActor *
meta_background_actor_new_for_screen (MetaScreen *screen)
{
MetaBackgroundActor *self;
MetaBackgroundActorPrivate *priv;
g_return_val_if_fail (META_IS_SCREEN (screen), NULL);
self = g_object_new (META_TYPE_BACKGROUND_ACTOR, NULL);
priv = self->priv;
priv->background = meta_screen_background_get (screen);
priv->background->actors = g_slist_prepend (priv->background->actors, self);
/* A CoglMaterial and a CoglPipeline are the same thing */
priv->pipeline = (CoglPipeline*) meta_create_texture_material (NULL);
set_texture_on_actor (self);
update_wrap_mode_of_actor (self);
return CLUTTER_ACTOR (self);
}
/**
* meta_background_actor_update:
* @screen: a #MetaScreen
*
* Refetches the _XROOTPMAP_ID property for the root window and updates
* the contents of the background actor based on that. There's no attempt
* to optimize out pixmap values that don't change (since a root pixmap
* could be replaced by with another pixmap with the same ID under some
* circumstances), so this should only be called when we actually receive
* a PropertyNotify event for the property.
*/
void
meta_background_actor_update (MetaScreen *screen)
{
MetaScreenBackground *background;
MetaDisplay *display;
MetaCompositor *compositor;
Atom type;
int format;
gulong nitems;
gulong bytes_after;
guchar *data;
Pixmap root_pixmap_id;
background = meta_screen_background_get (screen);
display = meta_screen_get_display (screen);
compositor = meta_display_get_compositor (display);
root_pixmap_id = None;
if (!XGetWindowProperty (meta_display_get_xdisplay (display),
meta_screen_get_xroot (screen),
compositor->atom_x_root_pixmap,
0, LONG_MAX,
False,
AnyPropertyType,
&type, &format, &nitems, &bytes_after, &data) &&
type != None)
{
/* Got a property. */
if (type == XA_PIXMAP && format == 32 && nitems == 1)
{
/* Was what we expected. */
root_pixmap_id = *(Pixmap *)data;
}
XFree(data);
}
if (root_pixmap_id != None)
{
CoglHandle texture;
CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
GError *error = NULL;
meta_error_trap_push (display);
texture = cogl_texture_pixmap_x11_new (ctx, root_pixmap_id, FALSE, &error);
meta_error_trap_pop (display);
if (texture != COGL_INVALID_HANDLE)
{
set_texture (background, texture);
cogl_handle_unref (texture);
background->have_pixmap = True;
return;
}
else
{
g_warning ("Failed to create background texture from pixmap: %s",
error->message);
g_error_free (error);
}
}
background->have_pixmap = False;
set_texture_to_stage_color (background);
}
/**
* meta_background_actor_set_visible_region:
* @self: a #MetaBackgroundActor
* @visible_region: (allow-none): the area of the actor (in allocate-relative
* coordinates) that is visible.
*
* Sets the area of the background that is unobscured by overlapping windows.
* This is used to optimize and only paint the visible portions.
*/
void
meta_background_actor_set_visible_region (MetaBackgroundActor *self,
cairo_region_t *visible_region)
{
MetaBackgroundActorPrivate *priv;
g_return_if_fail (META_IS_BACKGROUND_ACTOR (self));
priv = self->priv;
if (priv->visible_region)
{
cairo_region_destroy (priv->visible_region);
priv->visible_region = NULL;
}
if (visible_region)
{
cairo_rectangle_int_t screen_rect = { 0 };
meta_screen_get_size (priv->background->screen, &screen_rect.width, &screen_rect.height);
/* Doing the intersection here is probably unnecessary - MetaWindowGroup
* should never compute a visible area that's larger than the root screen!
* but it's not that expensive and adds some extra robustness.
*/
priv->visible_region = cairo_region_create_rectangle (&screen_rect);
cairo_region_intersect (priv->visible_region, visible_region);
}
}
/**
* meta_background_actor_screen_size_changed:
* @screen: a #MetaScreen
*
* Called by the compositor when the size of the #MetaScreen changes
*/
void
meta_background_actor_screen_size_changed (MetaScreen *screen)
{
MetaScreenBackground *background = meta_screen_background_get (screen);
GSList *l;
update_wrap_mode (background);
for (l = background->actors; l; l = l->next)
clutter_actor_queue_relayout (l->data);
}
/**
* meta_background_actor_add_glsl_snippet:
* @actor: a #MetaBackgroundActor
* @hook: where to insert the code
* @declarations: GLSL declarations
* @code: GLSL code
* @is_replace: wheter Cogl code should be replaced by the custom shader
*
* Adds a GLSL snippet to the pipeline used for drawing the background.
* See #CoglSnippet for details.
*/
void
meta_background_actor_add_glsl_snippet (MetaBackgroundActor *actor,
MetaSnippetHook hook,
const char *declarations,
const char *code,
gboolean is_replace)
{
MetaBackgroundActorPrivate *priv;
CoglSnippet *snippet;
g_return_if_fail (META_IS_BACKGROUND_ACTOR (actor));
priv = actor->priv;
if (is_replace)
{
snippet = cogl_snippet_new (hook, declarations, NULL);
cogl_snippet_set_replace (snippet, code);
}
else
{
snippet = cogl_snippet_new (hook, declarations, code);
}
if (hook == META_SNIPPET_HOOK_VERTEX ||
hook == META_SNIPPET_HOOK_FRAGMENT)
cogl_pipeline_add_snippet (priv->pipeline, snippet);
else
cogl_pipeline_add_layer_snippet (priv->pipeline, 0, snippet);
cogl_object_unref (snippet);
}
/**
* meta_background_actor_set_uniform_float:
* @actor: a #MetaBackgroundActor
* @uniform_name:
* @n_components: number of components (for vector uniforms)
* @count: number of uniforms (for array uniforms)
* @uniform: (array length=uniform_length): the float values to set
* @uniform_length: the length of @uniform. Must be exactly @n_components x @count,
* and is provided mainly for language bindings.
*
* Sets a new GLSL uniform to the provided value. This is mostly
* useful in congiunction with meta_background_actor_add_glsl_snippet().
*/
void
meta_background_actor_set_uniform_float (MetaBackgroundActor *actor,
const char *uniform_name,
int n_components,
int count,
const float *uniform,
int uniform_length)
{
MetaBackgroundActorPrivate *priv;
g_return_if_fail (META_IS_BACKGROUND_ACTOR (actor));
g_return_if_fail (uniform_length == n_components * count);
priv = actor->priv;
cogl_pipeline_set_uniform_float (priv->pipeline,
cogl_pipeline_get_uniform_location (priv->pipeline,
uniform_name),
n_components, count, uniform);
}

View File

@@ -1,325 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (c) 2008 Intel Corp.
*
* Author: Tomas Frydrych <tf@linux.intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include "config.h"
#include "compositor-private.h"
#include "meta-plugin-manager.h"
#include <meta/prefs.h>
#include <meta/errors.h>
#include <meta/workspace.h>
#include "meta-module.h"
#include "window-private.h"
#include <string.h>
#include <stdlib.h>
#include <clutter/x11/clutter-x11.h>
static GType plugin_type = G_TYPE_NONE;
struct MetaPluginManager
{
MetaScreen *screen;
MetaPlugin *plugin;
};
void
meta_plugin_manager_set_plugin_type (GType gtype)
{
if (plugin_type != G_TYPE_NONE)
meta_fatal ("Mutter plugin already set: %s", g_type_name (plugin_type));
plugin_type = gtype;
}
/*
* Loads the given plugin.
*/
void
meta_plugin_manager_load (const gchar *plugin_name)
{
const gchar *dpath = MUTTER_PLUGIN_DIR "/";
gchar *path;
MetaModule *module;
if (g_path_is_absolute (plugin_name))
path = g_strdup (plugin_name);
else
path = g_strconcat (dpath, plugin_name, ".so", NULL);
module = g_object_new (META_TYPE_MODULE, "path", path, NULL);
if (!module || !g_type_module_use (G_TYPE_MODULE (module)))
{
/* This is fatal under the assumption that a monitoring
* process like gnome-session will take over and handle
* our untimely exit.
*/
g_printerr ("Unable to load plugin module [%s]: %s",
path, g_module_error());
exit (1);
}
meta_plugin_manager_set_plugin_type (meta_module_get_plugin_type (module));
g_type_module_unuse (G_TYPE_MODULE (module));
g_free (path);
}
MetaPluginManager *
meta_plugin_manager_new (MetaScreen *screen)
{
MetaPluginManager *plugin_mgr;
MetaPluginClass *klass;
MetaPlugin *plugin;
plugin_mgr = g_new0 (MetaPluginManager, 1);
plugin_mgr->screen = screen;
plugin_mgr->plugin = plugin = g_object_new (plugin_type, "screen", screen, NULL);
klass = META_PLUGIN_GET_CLASS (plugin);
if (klass->start)
klass->start (plugin);
return plugin_mgr;
}
static void
meta_plugin_manager_kill_window_effects (MetaPluginManager *plugin_mgr,
MetaWindowActor *actor)
{
MetaPlugin *plugin = plugin_mgr->plugin;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
if (klass->kill_window_effects)
klass->kill_window_effects (plugin, actor);
}
static void
meta_plugin_manager_kill_switch_workspace (MetaPluginManager *plugin_mgr)
{
MetaPlugin *plugin = plugin_mgr->plugin;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
if (klass->kill_switch_workspace)
klass->kill_switch_workspace (plugin);
}
/*
* Public method that the compositor hooks into for events that require
* no additional parameters.
*
* 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_simple (MetaPluginManager *plugin_mgr,
MetaWindowActor *actor,
unsigned long event)
{
MetaPlugin *plugin = plugin_mgr->plugin;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen);
gboolean retval = FALSE;
if (display->display_opening)
return FALSE;
switch (event)
{
case META_PLUGIN_MINIMIZE:
if (klass->minimize)
{
retval = TRUE;
meta_plugin_manager_kill_window_effects (plugin_mgr,
actor);
_meta_plugin_effect_started (plugin);
klass->minimize (plugin, actor);
}
break;
case META_PLUGIN_MAP:
if (klass->map)
{
retval = TRUE;
meta_plugin_manager_kill_window_effects (plugin_mgr,
actor);
_meta_plugin_effect_started (plugin);
klass->map (plugin, actor);
}
break;
case META_PLUGIN_DESTROY:
if (klass->destroy)
{
retval = TRUE;
_meta_plugin_effect_started (plugin);
klass->destroy (plugin, actor);
}
break;
default:
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_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 = meta_screen_get_display (plugin_mgr->screen);
gboolean retval = FALSE;
if (display->display_opening)
return FALSE;
switch (event)
{
case META_PLUGIN_MAXIMIZE:
if (klass->maximize)
{
retval = TRUE;
meta_plugin_manager_kill_window_effects (plugin_mgr,
actor);
_meta_plugin_effect_started (plugin);
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);
_meta_plugin_effect_started (plugin);
klass->unmaximize (plugin, actor,
target_x, target_y,
target_width, target_height);
}
break;
default:
g_warning ("Incorrect handler called for event %lu", event);
}
return retval;
}
/*
* The public method that the compositor hooks into for desktop switching.
*
* 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_switch_workspace (MetaPluginManager *plugin_mgr,
gint from,
gint to,
MetaMotionDirection direction)
{
MetaPlugin *plugin = plugin_mgr->plugin;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen);
gboolean retval = FALSE;
if (display->display_opening)
return FALSE;
if (klass->switch_workspace)
{
retval = TRUE;
meta_plugin_manager_kill_switch_workspace (plugin_mgr);
_meta_plugin_effect_started (plugin);
klass->switch_workspace (plugin, from, to, direction);
}
return retval;
}
gboolean
meta_plugin_manager_filter_keybinding (MetaPluginManager *plugin_mgr,
MetaKeyBinding *binding)
{
MetaPlugin *plugin = plugin_mgr->plugin;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
if (klass->keybinding_filter)
return klass->keybinding_filter (plugin, binding);
return FALSE;
}
/*
* The public method that the compositor hooks into for desktop switching.
*
* 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_xevent_filter (MetaPluginManager *plugin_mgr,
XEvent *xev)
{
MetaPlugin *plugin = plugin_mgr->plugin;
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
if (!plugin_mgr)
return FALSE;
/* We need to make sure that clutter gets certain events, like
* ConfigureNotify on the stage window. If there is a plugin that
* provides an xevent_filter function, then it's the responsibility
* of that plugin to pass events to Clutter. Otherwise, we send the
* event directly to Clutter ourselves.
*/
if (klass->xevent_filter)
return klass->xevent_filter (plugin, xev);
else
return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE;
}

View File

@@ -1,76 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (c) 2008 Intel Corp.
*
* Author: Tomas Frydrych <tf@linux.intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef META_PLUGIN_MANAGER_H_
#define META_PLUGIN_MANAGER_H_
#include <meta/types.h>
#include <meta/screen.h>
#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_ALL_EFFECTS (~0)
/**
* MetaPluginManager: (skip)
*
*/
typedef struct MetaPluginManager MetaPluginManager;
MetaPluginManager * meta_plugin_manager_new (MetaScreen *screen);
void meta_plugin_manager_load (const gchar *plugin_name);
gboolean meta_plugin_manager_event_simple (MetaPluginManager *mgr,
MetaWindowActor *actor,
unsigned long event);
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,
gint to,
MetaMotionDirection direction);
gboolean meta_plugin_manager_filter_keybinding (MetaPluginManager *mgr,
MetaKeyBinding *binding);
gboolean meta_plugin_manager_xevent_filter (MetaPluginManager *mgr,
XEvent *xev);
#endif

View File

@@ -1,333 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (c) 2008 Intel Corp.
*
* Author: Tomas Frydrych <tf@linux.intel.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <meta/meta-plugin.h>
#include "meta-plugin-manager.h"
#include <meta/screen.h>
#include <meta/display.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xfixes.h>
#include <X11/extensions/shape.h>
#include <clutter/x11/clutter-x11.h>
#include "compositor-private.h"
#include "meta-window-actor-private.h"
G_DEFINE_ABSTRACT_TYPE (MetaPlugin, meta_plugin, G_TYPE_OBJECT);
#define META_PLUGIN_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), META_TYPE_PLUGIN, MetaPluginPrivate))
enum
{
PROP_0,
PROP_SCREEN,
PROP_DEBUG_MODE,
};
struct _MetaPluginPrivate
{
MetaScreen *screen;
gint running;
gboolean debug : 1;
};
static void
meta_plugin_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
MetaPluginPrivate *priv = META_PLUGIN (object)->priv;
switch (prop_id)
{
case PROP_SCREEN:
priv->screen = g_value_get_object (value);
break;
case PROP_DEBUG_MODE:
priv->debug = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
meta_plugin_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
MetaPluginPrivate *priv = META_PLUGIN (object)->priv;
switch (prop_id)
{
case PROP_SCREEN:
g_value_set_object (value, priv->screen);
break;
case PROP_DEBUG_MODE:
g_value_set_boolean (value, priv->debug);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
meta_plugin_class_init (MetaPluginClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->set_property = meta_plugin_set_property;
gobject_class->get_property = meta_plugin_get_property;
g_object_class_install_property (gobject_class,
PROP_SCREEN,
g_param_spec_object ("screen",
"MetaScreen",
"MetaScreen",
META_TYPE_SCREEN,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_DEBUG_MODE,
g_param_spec_boolean ("debug-mode",
"Debug Mode",
"Debug Mode",
FALSE,
G_PARAM_READABLE));
g_type_class_add_private (gobject_class, sizeof (MetaPluginPrivate));
}
static void
meta_plugin_init (MetaPlugin *self)
{
MetaPluginPrivate *priv;
self->priv = priv = META_PLUGIN_GET_PRIVATE (self);
}
gboolean
meta_plugin_running (MetaPlugin *plugin)
{
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
return (priv->running > 0);
}
gboolean
meta_plugin_debug_mode (MetaPlugin *plugin)
{
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
return priv->debug;
}
const MetaPluginInfo *
meta_plugin_get_info (MetaPlugin *plugin)
{
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
if (klass && klass->plugin_info)
return klass->plugin_info (plugin);
return NULL;
}
/**
* _meta_plugin_effect_started:
* @plugin: the plugin
*
* Mark that an effect has started for the plugin. This is called
* internally by MetaPluginManager.
*/
void
_meta_plugin_effect_started (MetaPlugin *plugin)
{
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
priv->running++;
}
void
meta_plugin_switch_workspace_completed (MetaPlugin *plugin)
{
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
MetaScreen *screen = priv->screen;
if (priv->running-- < 0)
{
g_warning ("Error in running effect accounting, adjusting.");
priv->running = 0;
}
meta_switch_workspace_completed (screen);
}
static void
meta_plugin_window_effect_completed (MetaPlugin *plugin,
MetaWindowActor *actor,
unsigned long event)
{
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
if (priv->running-- < 0)
{
g_warning ("Error in running effect accounting, adjusting.");
priv->running = 0;
}
if (!actor)
{
const MetaPluginInfo *info;
const gchar *name = NULL;
if (plugin && (info = meta_plugin_get_info (plugin)))
name = info->name;
g_warning ("Plugin [%s] passed NULL for actor!",
name ? name : "unknown");
}
meta_window_actor_effect_completed (actor, event);
}
void
meta_plugin_minimize_completed (MetaPlugin *plugin,
MetaWindowActor *actor)
{
meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_MINIMIZE);
}
void
meta_plugin_maximize_completed (MetaPlugin *plugin,
MetaWindowActor *actor)
{
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
meta_plugin_map_completed (MetaPlugin *plugin,
MetaWindowActor *actor)
{
meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_MAP);
}
void
meta_plugin_destroy_completed (MetaPlugin *plugin,
MetaWindowActor *actor)
{
meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_DESTROY);
}
/**
* meta_plugin_begin_modal:
* @plugin: a #MetaPlugin
* @grab_window: the X window to grab the keyboard and mouse on
* @cursor: the cursor to use for the pointer grab, or None,
* to use the normal cursor for the grab window and
* its descendants.
* @options: flags that modify the behavior of the modal grab
* @timestamp: the timestamp used for establishing grabs
*
* This function is used to grab the keyboard and mouse for the exclusive
* use of the plugin. Correct operation requires that both the keyboard
* and mouse are grabbed, or thing will break. (In particular, other
* passive X grabs in Meta can trigger but not be handled by the normal
* keybinding handling code.) However, the plugin can establish the keyboard
* and/or mouse grabs ahead of time and pass in the
* %META_MODAL_POINTER_ALREADY_GRABBED and/or %META_MODAL_KEYBOARD_ALREADY_GRABBED
* options. This facility is provided for two reasons: first to allow using
* this function to establish modality after a passive grab, and second to
* allow using obscure features of XGrabPointer() and XGrabKeyboard() without
* having to add them to this API.
*
* Return value: whether we successfully grabbed the keyboard and
* mouse and made the plugin modal.
*/
gboolean
meta_plugin_begin_modal (MetaPlugin *plugin,
Window grab_window,
Cursor cursor,
MetaModalOptions options,
guint32 timestamp)
{
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
return meta_begin_modal_for_plugin (priv->screen, plugin,
grab_window, cursor, options, timestamp);
}
/**
* meta_plugin_end_modal:
* @plugin: a #MetaPlugin
* @timestamp: the time used for releasing grabs
*
* Ends the modal operation begun with meta_plugin_begin_modal(). This
* ungrabs both the mouse and keyboard even when
* %META_MODAL_POINTER_ALREADY_GRABBED or
* %META_MODAL_KEYBOARD_ALREADY_GRABBED were provided as options
* when beginnning the modal operation.
*/
void
meta_plugin_end_modal (MetaPlugin *plugin,
guint32 timestamp)
{
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
meta_end_modal_for_plugin (priv->screen, plugin, timestamp);
}
/**
* meta_plugin_get_screen:
* @plugin: a #MetaPlugin
*
* Gets the #MetaScreen corresponding to a plugin. Each plugin instance
* is associated with exactly one screen; if Metacity is managing
* multiple screens, multiple plugin instances will be created.
*
* Return value: (transfer none): the #MetaScreen for the plugin
*/
MetaScreen *
meta_plugin_get_screen (MetaPlugin *plugin)
{
MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
return priv->screen;
}

View File

@@ -1,68 +0,0 @@
/* -*- 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#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);
CoglHandle 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__ */

File diff suppressed because it is too large Load Diff

View File

@@ -1,679 +0,0 @@
/*
* shaped texture
*
* An actor to draw a masked texture.
*
* Authored By Neil Roberts <neil@linux.intel.com>
* and Jasper St. Pierre <jstpierre@mecheye.net>
*
* Copyright (C) 2008 Intel Corporation
* Copyright (C) 2012 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <config.h>
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#define COGL_ENABLE_EXPERIMENTAL_API
#include <meta/meta-shaped-texture.h>
#include "meta-texture-tower.h"
#include <clutter/clutter.h>
#include <cogl/cogl.h>
#include <cogl/cogl-texture-pixmap-x11.h>
#include <gdk/gdk.h> /* for gdk_rectangle_intersect() */
static void meta_shaped_texture_dispose (GObject *object);
static void meta_shaped_texture_paint (ClutterActor *actor);
static void meta_shaped_texture_pick (ClutterActor *actor,
const ClutterColor *color);
static void meta_shaped_texture_get_preferred_width (ClutterActor *self,
gfloat for_height,
gfloat *min_width_p,
gfloat *natural_width_p);
static void meta_shaped_texture_get_preferred_height (ClutterActor *self,
gfloat for_width,
gfloat *min_height_p,
gfloat *natural_height_p);
static gboolean meta_shaped_texture_get_paint_volume (ClutterActor *self, ClutterPaintVolume *volume);
G_DEFINE_TYPE (MetaShapedTexture, meta_shaped_texture,
CLUTTER_TYPE_ACTOR);
#define META_SHAPED_TEXTURE_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), META_TYPE_SHAPED_TEXTURE, \
MetaShapedTexturePrivate))
struct _MetaShapedTexturePrivate
{
MetaTextureTower *paint_tower;
Pixmap pixmap;
CoglHandle texture;
CoglHandle mask_texture;
CoglHandle material;
CoglHandle material_unshaped;
cairo_region_t *clip_region;
guint tex_width, tex_height;
guint create_mipmaps : 1;
};
static void
meta_shaped_texture_class_init (MetaShapedTextureClass *klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
ClutterActorClass *actor_class = (ClutterActorClass *) klass;
gobject_class->dispose = meta_shaped_texture_dispose;
actor_class->get_preferred_width = meta_shaped_texture_get_preferred_width;
actor_class->get_preferred_height = meta_shaped_texture_get_preferred_height;
actor_class->paint = meta_shaped_texture_paint;
actor_class->pick = meta_shaped_texture_pick;
actor_class->get_paint_volume = meta_shaped_texture_get_paint_volume;
g_type_class_add_private (klass, sizeof (MetaShapedTexturePrivate));
}
static void
meta_shaped_texture_init (MetaShapedTexture *self)
{
MetaShapedTexturePrivate *priv;
priv = self->priv = META_SHAPED_TEXTURE_GET_PRIVATE (self);
priv->paint_tower = meta_texture_tower_new ();
priv->texture = COGL_INVALID_HANDLE;
priv->mask_texture = COGL_INVALID_HANDLE;
priv->create_mipmaps = TRUE;
}
static void
meta_shaped_texture_dispose (GObject *object)
{
MetaShapedTexture *self = (MetaShapedTexture *) object;
MetaShapedTexturePrivate *priv = self->priv;
if (priv->paint_tower)
meta_texture_tower_free (priv->paint_tower);
priv->paint_tower = NULL;
if (priv->material != COGL_INVALID_HANDLE)
{
cogl_handle_unref (priv->material);
priv->material = COGL_INVALID_HANDLE;
}
if (priv->material_unshaped != COGL_INVALID_HANDLE)
{
cogl_handle_unref (priv->material_unshaped);
priv->material_unshaped = COGL_INVALID_HANDLE;
}
if (priv->texture != COGL_INVALID_HANDLE)
{
cogl_handle_unref (priv->texture);
priv->texture = COGL_INVALID_HANDLE;
}
meta_shaped_texture_set_mask_texture (self, COGL_INVALID_HANDLE);
meta_shaped_texture_set_clip_region (self, NULL);
G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object);
}
static void
meta_shaped_texture_paint (ClutterActor *actor)
{
MetaShapedTexture *stex = (MetaShapedTexture *) actor;
MetaShapedTexturePrivate *priv = stex->priv;
CoglHandle paint_tex;
guint tex_width, tex_height;
ClutterActorBox alloc;
static CoglHandle material_template = COGL_INVALID_HANDLE;
static CoglHandle material_unshaped_template = COGL_INVALID_HANDLE;
CoglHandle material;
if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
return;
if (!CLUTTER_ACTOR_IS_REALIZED (CLUTTER_ACTOR (stex)))
clutter_actor_realize (CLUTTER_ACTOR (stex));
/* The GL EXT_texture_from_pixmap extension does allow for it to be
* used together with SGIS_generate_mipmap, however this is very
* rarely supported. Also, even when it is supported there
* are distinct performance implications from:
*
* - Updating mipmaps that we don't need
* - Having to reallocate pixmaps on the server into larger buffers
*
* So, we just unconditionally use our mipmap emulation code. If we
* wanted to use SGIS_generate_mipmap, we'd have to query COGL to
* see if it was supported (no API currently), and then if and only
* if that was the case, set the clutter texture quality to HIGH.
* Setting the texture quality to high without SGIS_generate_mipmap
* support for TFP textures will result in fallbacks to XGetImage.
*/
if (priv->create_mipmaps)
paint_tex = meta_texture_tower_get_paint_texture (priv->paint_tower);
else
paint_tex = priv->texture;
if (paint_tex == COGL_INVALID_HANDLE)
return;
tex_width = priv->tex_width;
tex_height = priv->tex_height;
if (tex_width == 0 || tex_height == 0) /* no contents yet */
return;
if (priv->mask_texture == COGL_INVALID_HANDLE)
{
/* Use a single-layer texture if we don't have a mask. */
if (priv->material_unshaped == COGL_INVALID_HANDLE)
{
if (G_UNLIKELY (material_unshaped_template == COGL_INVALID_HANDLE))
material_unshaped_template = cogl_material_new ();
priv->material_unshaped = cogl_material_copy (material_unshaped_template);
}
material = priv->material_unshaped;
}
else
{
if (priv->material == COGL_INVALID_HANDLE)
{
if (G_UNLIKELY (material_template == COGL_INVALID_HANDLE))
{
material_template = cogl_material_new ();
cogl_material_set_layer_combine (material_template, 1,
"RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
NULL);
}
priv->material = cogl_material_copy (material_template);
}
material = priv->material;
cogl_material_set_layer (material, 1, priv->mask_texture);
}
cogl_material_set_layer (material, 0, paint_tex);
{
CoglColor color;
guchar opacity = clutter_actor_get_paint_opacity (actor);
cogl_color_set_from_4ub (&color, opacity, opacity, opacity, opacity);
cogl_material_set_color (material, &color);
}
cogl_set_source (material);
clutter_actor_get_allocation_box (actor, &alloc);
if (priv->clip_region)
{
int n_rects;
int i;
cairo_rectangle_int_t tex_rect = { 0, 0, tex_width, tex_height };
/* Limit to how many separate rectangles we'll draw; beyond this just
* fall back and draw the whole thing */
# define MAX_RECTS 16
n_rects = cairo_region_num_rectangles (priv->clip_region);
if (n_rects <= MAX_RECTS)
{
float coords[8];
float x1, y1, x2, y2;
for (i = 0; i < n_rects; i++)
{
cairo_rectangle_int_t rect;
cairo_region_get_rectangle (priv->clip_region, i, &rect);
if (!gdk_rectangle_intersect (&tex_rect, &rect, &rect))
continue;
x1 = rect.x;
y1 = rect.y;
x2 = rect.x + rect.width;
y2 = rect.y + rect.height;
coords[0] = rect.x / (alloc.x2 - alloc.x1);
coords[1] = rect.y / (alloc.y2 - alloc.y1);
coords[2] = (rect.x + rect.width) / (alloc.x2 - alloc.x1);
coords[3] = (rect.y + rect.height) / (alloc.y2 - alloc.y1);
coords[4] = coords[0];
coords[5] = coords[1];
coords[6] = coords[2];
coords[7] = coords[3];
cogl_rectangle_with_multitexture_coords (x1, y1, x2, y2,
&coords[0], 8);
}
return;
}
}
cogl_rectangle (0, 0,
alloc.x2 - alloc.x1,
alloc.y2 - alloc.y1);
}
static void
meta_shaped_texture_pick (ClutterActor *actor,
const ClutterColor *color)
{
MetaShapedTexture *stex = (MetaShapedTexture *) actor;
MetaShapedTexturePrivate *priv = stex->priv;
/* If there is no region then use the regular pick */
if (priv->mask_texture == COGL_INVALID_HANDLE)
CLUTTER_ACTOR_CLASS (meta_shaped_texture_parent_class)
->pick (actor, color);
else if (clutter_actor_should_pick_paint (actor))
{
CoglHandle paint_tex;
ClutterActorBox alloc;
guint tex_width, tex_height;
paint_tex = priv->texture;
if (paint_tex == COGL_INVALID_HANDLE)
return;
tex_width = cogl_texture_get_width (paint_tex);
tex_height = cogl_texture_get_height (paint_tex);
if (tex_width == 0 || tex_height == 0) /* no contents yet */
return;
cogl_set_source_color4ub (color->red, color->green, color->blue,
color->alpha);
clutter_actor_get_allocation_box (actor, &alloc);
/* Paint the mask rectangle in the given color */
cogl_set_source_texture (priv->mask_texture);
cogl_rectangle_with_texture_coords (0, 0,
alloc.x2 - alloc.x1,
alloc.y2 - alloc.y1,
0, 0, 1, 1);
}
}
static void
meta_shaped_texture_get_preferred_width (ClutterActor *self,
gfloat for_height,
gfloat *min_width_p,
gfloat *natural_width_p)
{
MetaShapedTexturePrivate *priv;
g_return_if_fail (META_IS_SHAPED_TEXTURE (self));
priv = META_SHAPED_TEXTURE (self)->priv;
if (min_width_p)
*min_width_p = 0;
if (natural_width_p)
*natural_width_p = priv->tex_width;
}
static void
meta_shaped_texture_get_preferred_height (ClutterActor *self,
gfloat for_width,
gfloat *min_height_p,
gfloat *natural_height_p)
{
MetaShapedTexturePrivate *priv;
g_return_if_fail (META_IS_SHAPED_TEXTURE (self));
priv = META_SHAPED_TEXTURE (self)->priv;
if (min_height_p)
*min_height_p = 0;
if (natural_height_p)
*natural_height_p = priv->tex_height;
}
static gboolean
meta_shaped_texture_get_paint_volume (ClutterActor *self,
ClutterPaintVolume *volume)
{
return clutter_paint_volume_set_from_allocation (volume, self);
}
ClutterActor *
meta_shaped_texture_new (void)
{
ClutterActor *self = g_object_new (META_TYPE_SHAPED_TEXTURE, NULL);
return self;
}
void
meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
gboolean create_mipmaps)
{
MetaShapedTexturePrivate *priv;
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
priv = stex->priv;
create_mipmaps = create_mipmaps != FALSE;
if (create_mipmaps != priv->create_mipmaps)
{
CoglHandle base_texture;
priv->create_mipmaps = create_mipmaps;
base_texture = create_mipmaps ?
priv->texture : COGL_INVALID_HANDLE;
meta_texture_tower_set_base_texture (priv->paint_tower, base_texture);
}
}
void
meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
CoglHandle mask_texture)
{
MetaShapedTexturePrivate *priv;
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
priv = stex->priv;
if (priv->mask_texture != COGL_INVALID_HANDLE)
{
cogl_handle_unref (priv->mask_texture);
priv->mask_texture = COGL_INVALID_HANDLE;
}
if (mask_texture != COGL_INVALID_HANDLE)
{
priv->mask_texture = mask_texture;
cogl_handle_ref (priv->mask_texture);
}
clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
}
void
meta_shaped_texture_update_area (MetaShapedTexture *stex,
int x,
int y,
int width,
int height)
{
MetaShapedTexturePrivate *priv;
const cairo_rectangle_int_t clip = { x, y, width, height };
priv = stex->priv;
if (priv->texture == COGL_INVALID_HANDLE)
return;
cogl_texture_pixmap_x11_update_area (priv->texture, x, y, width, height);
meta_texture_tower_update_area (priv->paint_tower, x, y, width, height);
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &clip);
}
static void
set_cogl_texture (MetaShapedTexture *stex,
CoglHandle cogl_tex)
{
MetaShapedTexturePrivate *priv;
guint width, height;
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
priv = stex->priv;
if (priv->texture != COGL_INVALID_HANDLE)
cogl_handle_unref (priv->texture);
priv->texture = cogl_tex;
if (priv->material != COGL_INVALID_HANDLE)
cogl_material_set_layer (priv->material, 0, cogl_tex);
if (priv->material_unshaped != COGL_INVALID_HANDLE)
cogl_material_set_layer (priv->material_unshaped, 0, cogl_tex);
if (cogl_tex != COGL_INVALID_HANDLE)
{
width = cogl_texture_get_width (cogl_tex);
height = cogl_texture_get_height (cogl_tex);
if (width != priv->tex_width ||
height != priv->tex_height)
{
priv->tex_width = width;
priv->tex_height = height;
clutter_actor_queue_relayout (CLUTTER_ACTOR (stex));
}
}
else
{
/* size changed to 0 going to an invalid handle */
priv->tex_width = 0;
priv->tex_height = 0;
clutter_actor_queue_relayout (CLUTTER_ACTOR (stex));
}
clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
}
/**
* meta_shaped_texture_set_pixmap:
* @stex: The #MetaShapedTexture
* @pixmap: The pixmap you want the stex to assume
*/
void
meta_shaped_texture_set_pixmap (MetaShapedTexture *stex,
Pixmap pixmap)
{
MetaShapedTexturePrivate *priv;
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
priv = stex->priv;
if (priv->pixmap == pixmap)
return;
priv->pixmap = pixmap;
if (pixmap != None)
{
CoglContext *ctx =
clutter_backend_get_cogl_context (clutter_get_default_backend ());
set_cogl_texture (stex, cogl_texture_pixmap_x11_new (ctx, pixmap, FALSE, NULL));
}
else
set_cogl_texture (stex, COGL_INVALID_HANDLE);
if (priv->create_mipmaps)
meta_texture_tower_set_base_texture (priv->paint_tower, priv->texture);
}
/**
* meta_shaped_texture_get_texture:
* @stex: The #MetaShapedTexture
*
* Returns: (transfer none): the unshaped texture
*/
CoglHandle
meta_shaped_texture_get_texture (MetaShapedTexture *stex)
{
g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), COGL_INVALID_HANDLE);
return stex->priv->texture;
}
/**
* meta_shaped_texture_set_clip_region:
* @stex: a #MetaShapedTexture
* @clip_region: (transfer full): the region of the texture that
* is visible and should be painted.
*
* Provides a hint to the texture about what areas of the texture
* are not completely obscured and thus need to be painted. This
* is an optimization and is not supposed to have any effect on
* the output.
*
* Typically a parent container will set the clip region before
* painting its children, and then unset it afterwards.
*/
void
meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
cairo_region_t *clip_region)
{
MetaShapedTexturePrivate *priv;
g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
priv = stex->priv;
if (priv->clip_region)
{
cairo_region_destroy (priv->clip_region);
priv->clip_region = NULL;
}
if (clip_region)
priv->clip_region = cairo_region_copy (clip_region);
else
priv->clip_region = NULL;
}
/**
* meta_shaped_texture_get_image:
* @stex: A #MetaShapedTexture
* @clip: A clipping rectangle, to help prevent extra processing.
* In the case that the clipping rectangle is partially or fully
* outside the bounds of the texture, the rectangle will be clipped.
*
* Flattens the two layers of the shaped texture into one ARGB32
* image by alpha blending the two images, and returns the flattened
* image.
*
* Returns: (transfer full): a new cairo surface to be freed with
* cairo_surface_destroy().
*/
cairo_surface_t *
meta_shaped_texture_get_image (MetaShapedTexture *stex,
cairo_rectangle_int_t *clip)
{
CoglHandle texture, mask_texture;
cairo_rectangle_int_t texture_rect = { 0, 0, 0, 0 };
cairo_surface_t *surface;
g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
texture = stex->priv->texture;
if (texture == NULL)
return NULL;
texture_rect.width = cogl_texture_get_width (texture);
texture_rect.height = cogl_texture_get_height (texture);
if (clip != NULL)
{
/* GdkRectangle is just a typedef of cairo_rectangle_int_t,
* so we can use the gdk_rectangle_* APIs on these. */
if (!gdk_rectangle_intersect (&texture_rect, clip, clip))
return NULL;
}
if (clip != NULL)
texture = cogl_texture_new_from_sub_texture (texture,
clip->x,
clip->y,
clip->width,
clip->height);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
cogl_texture_get_width (texture),
cogl_texture_get_height (texture));
cogl_texture_get_data (texture, CLUTTER_CAIRO_FORMAT_ARGB32,
cairo_image_surface_get_stride (surface),
cairo_image_surface_get_data (surface));
cairo_surface_mark_dirty (surface);
if (clip != NULL)
cogl_object_unref (texture);
mask_texture = stex->priv->mask_texture;
if (mask_texture != COGL_INVALID_HANDLE)
{
cairo_t *cr;
cairo_surface_t *mask_surface;
if (clip != NULL)
mask_texture = cogl_texture_new_from_sub_texture (mask_texture,
clip->x,
clip->y,
clip->width,
clip->height);
mask_surface = cairo_image_surface_create (CAIRO_FORMAT_A8,
cogl_texture_get_width (mask_texture),
cogl_texture_get_height (mask_texture));
cogl_texture_get_data (mask_texture, COGL_PIXEL_FORMAT_A_8,
cairo_image_surface_get_stride (mask_surface),
cairo_image_surface_get_data (mask_surface));
cairo_surface_mark_dirty (mask_surface);
cr = cairo_create (surface);
cairo_set_source_surface (cr, mask_surface, 0, 0);
cairo_set_operator (cr, CAIRO_OPERATOR_DEST_IN);
cairo_paint (cr);
cairo_destroy (cr);
cairo_surface_destroy (mask_surface);
if (clip != NULL)
cogl_object_unref (mask_texture);
}
return surface;
}

View File

@@ -1,101 +0,0 @@
/*
* texture rectangle
*
* A small utility function to help create a rectangle texture
*
* Authored By Neil Roberts <neil@linux.intel.com>
*
* Copyright (C) 2011, 2012 Intel Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <config.h>
#define CLUTTER_ENABLE_EXPERIMENTAL_API
#define COGL_ENABLE_EXPERIMENTAL_API
#include <clutter/clutter.h>
#include "meta-texture-rectangle.h"
CoglTexture *
meta_texture_rectangle_new (unsigned int width,
unsigned int height,
CoglPixelFormat format,
CoglPixelFormat internal_format,
unsigned int rowstride,
const guint8 *data,
GError **error)
{
ClutterBackend *backend =
clutter_get_default_backend ();
CoglContext *context =
clutter_backend_get_cogl_context (backend);
CoglTextureRectangle *tex_rect;
tex_rect = cogl_texture_rectangle_new_with_size (context,
width, height,
internal_format,
error);
if (tex_rect == NULL)
return NULL;
if (data)
cogl_texture_set_region (COGL_TEXTURE (tex_rect),
0, 0, /* src_x/y */
0, 0, /* dst_x/y */
width, height, /* dst_width/height */
width, height, /* width/height */
format,
rowstride,
data);
return COGL_TEXTURE (tex_rect);
}
static void
texture_rectangle_check_cb (CoglTexture *sub_texture,
const float *sub_texture_coords,
const float *meta_coords,
void *user_data)
{
gboolean *result = user_data;
if (cogl_is_texture_rectangle (sub_texture))
*result = TRUE;
}
/* Determines if the given texture is using a rectangle texture as its
* primitive texture type. Eventually this function could be replaced
* with cogl_texture_get_type if Cogl makes that public.
*
* http://git.gnome.org/browse/cogl/commit/?h=8012eee31
*/
gboolean
meta_texture_rectangle_check (CoglTexture *texture)
{
gboolean result = FALSE;
cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (texture),
0.0f, 0.0f, /* tx_1 / ty_1 */
1.0f, 1.0f, /* tx_2 / ty_2 */
COGL_PIPELINE_WRAP_MODE_REPEAT,
COGL_PIPELINE_WRAP_MODE_REPEAT,
texture_rectangle_check_cb,
&result);
return result;
}

View File

@@ -1,47 +0,0 @@
/*
* texture rectangle
*
* A small utility function to help create a rectangle texture
*
* Authored By Neil Roberts <neil@linux.intel.com>
*
* Copyright (C) 2011 Intel Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef __META_TEXTURE_RECTANGLE_H__
#define __META_TEXTURE_RECTANGLE_H__
#include <cogl/cogl.h>
G_BEGIN_DECLS
CoglTexture *
meta_texture_rectangle_new (unsigned int width,
unsigned int height,
CoglPixelFormat format,
CoglPixelFormat internal_format,
unsigned int rowstride,
const guint8 *data,
GError **error);
gboolean
meta_texture_rectangle_check (CoglTexture *texture);
G_END_DECLS
#endif /* __META_TEXTURE_RECTANGLE_H__ */

View File

@@ -1,624 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* MetaTextureTower
*
* Mipmap emulation by creation of scaled down images
*
* Copyright (C) 2009 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <math.h>
#include <string.h>
#include "meta-texture-tower.h"
#include "meta-texture-rectangle.h"
#ifndef M_LOG2E
#define M_LOG2E 1.4426950408889634074
#endif
#define MAX_TEXTURE_LEVELS 12
/* If the texture format in memory doesn't match this, then Mesa
* will do the conversion, so things will still work, but it might
* be slow depending on how efficient Mesa is. These should be the
* native formats unless the display is 16bpp. If conversions
* here are a bottleneck, investigate whether we are converting when
* storing window data *into* the texture before adding extra code
* to handle multiple texture formats.
*/
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
#define TEXTURE_FORMAT COGL_PIXEL_FORMAT_BGRA_8888_PRE
#else
#define TEXTURE_FORMAT COGL_PIXEL_FORMAT_ARGB_8888_PRE
#endif
typedef struct
{
guint16 x1;
guint16 y1;
guint16 x2;
guint16 y2;
} Box;
struct _MetaTextureTower
{
int n_levels;
CoglHandle textures[MAX_TEXTURE_LEVELS];
CoglHandle fbos[MAX_TEXTURE_LEVELS];
Box invalid[MAX_TEXTURE_LEVELS];
};
/**
* meta_texture_tower_new:
*
* Creates a new texture tower. The base texture has to be set with
* meta_texture_tower_set_base_texture() before use.
*
* Return value: the new texture tower. Free with meta_texture_tower_free()
*/
MetaTextureTower *
meta_texture_tower_new (void)
{
MetaTextureTower *tower;
tower = g_slice_new0 (MetaTextureTower);
return tower;
}
/**
* meta_texture_tower_free:
* @tower: a #MetaTextureTower
*
* Frees a texture tower created with meta_texture_tower_new().
*/
void
meta_texture_tower_free (MetaTextureTower *tower)
{
g_return_if_fail (tower != NULL);
meta_texture_tower_set_base_texture (tower, COGL_INVALID_HANDLE);
g_slice_free (MetaTextureTower, tower);
}
/**
* meta_texture_tower_set_base_texture:
* @tower: a #MetaTextureTower
* @texture: the new texture used as a base for scaled down versions
*
* Sets the base texture that is the scaled texture that the
* scaled textures of the tower are derived from. The texture itself
* will be used as level 0 of the tower and will be referenced until
* unset or until the tower is freed.
*/
void
meta_texture_tower_set_base_texture (MetaTextureTower *tower,
CoglHandle texture)
{
int i;
g_return_if_fail (tower != NULL);
if (texture == tower->textures[0])
return;
if (tower->textures[0] != COGL_INVALID_HANDLE)
{
for (i = 1; i < tower->n_levels; i++)
{
if (tower->textures[i] != COGL_INVALID_HANDLE)
{
cogl_handle_unref (tower->textures[i]);
tower->textures[i] = COGL_INVALID_HANDLE;
}
if (tower->fbos[i] != COGL_INVALID_HANDLE)
{
cogl_handle_unref (tower->fbos[i]);
tower->fbos[i] = COGL_INVALID_HANDLE;
}
}
cogl_handle_unref (tower->textures[0]);
}
tower->textures[0] = texture;
if (tower->textures[0] != COGL_INVALID_HANDLE)
{
int width, height;
cogl_handle_ref (tower->textures[0]);
width = cogl_texture_get_width (tower->textures[0]);
height = cogl_texture_get_height (tower->textures[0]);
tower->n_levels = 1 + MAX ((int)(M_LOG2E * log (width)), (int)(M_LOG2E * log (height)));
tower->n_levels = MIN(tower->n_levels, MAX_TEXTURE_LEVELS);
meta_texture_tower_update_area (tower, 0, 0, width, height);
}
else
{
tower->n_levels = 0;
}
}
/**
* meta_texture_tower_update_area:
* @tower: a #MetaTextureTower
* @x: X coordinate of upper left of rectangle that changed
* @y: Y coordinate of upper left of rectangle that changed
* @width: width of rectangle that changed
* @height: height rectangle that changed
*
* Mark a region of the base texture as having changed; the next
* time a scaled down version of the base texture is retrieved,
* the appropriate area of the scaled down texture will be updated.
*/
void
meta_texture_tower_update_area (MetaTextureTower *tower,
int x,
int y,
int width,
int height)
{
int texture_width, texture_height;
Box invalid;
int i;
g_return_if_fail (tower != NULL);
if (tower->textures[0] == COGL_INVALID_HANDLE)
return;
texture_width = cogl_texture_get_width (tower->textures[0]);
texture_height = cogl_texture_get_height (tower->textures[0]);
invalid.x1 = x;
invalid.y1 = y;
invalid.x2 = x + width;
invalid.y2 = y + height;
for (i = 1; i < tower->n_levels; i++)
{
texture_width = MAX (1, texture_width / 2);
texture_height = MAX (1, texture_height / 2);
invalid.x1 = invalid.x1 / 2;
invalid.y1 = invalid.y1 / 2;
invalid.x2 = MIN (texture_width, (invalid.x2 + 1) / 2);
invalid.y2 = MIN (texture_height, (invalid.y2 + 1) / 2);
if (tower->invalid[i].x1 == tower->invalid[i].x2 ||
tower->invalid[i].y1 == tower->invalid[i].y2)
{
tower->invalid[i] = invalid;
}
else
{
tower->invalid[i].x1 = MIN (tower->invalid[i].x1, invalid.x1);
tower->invalid[i].y1 = MIN (tower->invalid[i].y1, invalid.y1);
tower->invalid[i].x2 = MAX (tower->invalid[i].x2, invalid.x2);
tower->invalid[i].y2 = MAX (tower->invalid[i].y2, invalid.y2);
}
}
}
/* It generally looks worse if we scale up a window texture by even a
* small amount than if we scale it down using bilinear filtering, so
* we always pick the *larger* adjacent level. */
#define LOD_BIAS (-0.49)
/* This determines the appropriate level of detail to use when drawing the
* texture, in a way that corresponds to what the GL specification does
* when mip-mapping. This is probably fancier and slower than what we need,
* but we do the computation only once each time we paint a window, and
* its easier to just use the equations from the specification than to
* come up with something simpler.
*
* If window is being painted at an angle from the viewer, then we have to
* pick a point in the texture; we use the middle of the texture (which is
* why the width/height are passed in.) This is not the normal case for
* Meta.
*/
static int
get_paint_level (int width, int height)
{
CoglMatrix projection, modelview, pm;
float v[4];
double viewport_width, viewport_height;
double u0, v0;
double xc, yc, wc;
double dxdu_, dxdv_, dydu_, dydv_;
double det_, det_sq;
double rho_sq;
double lambda;
/* See
* http://www.opengl.org/registry/doc/glspec32.core.20090803.pdf
* Section 3.8.9, p. 1.6.2. Here we have
*
* u(x,y) = x_o;
* v(x,y) = y_o;
*
* Since we are mapping 1:1 from object coordinates into pixel
* texture coordinates, the clip coordinates are:
*
* (x_c) (x_o) (u)
* (y_c) = (M_projection)(M_modelview) (y_o) = (PM) (v)
* (z_c) (z_o) (0)
* (w_c) (w_o) (1)
*/
cogl_get_projection_matrix (&projection);
cogl_get_modelview_matrix (&modelview);
cogl_matrix_multiply (&pm, &projection, &modelview);
cogl_get_viewport (v);
viewport_width = v[2];
viewport_height = v[3];
u0 = width / 2.;
v0 = height / 2.;
xc = pm.xx * u0 + pm.xy * v0 + pm.xw;
yc = pm.yx * u0 + pm.yy * v0 + pm.yw;
wc = pm.wx * u0 + pm.wy * v0 + pm.ww;
/* We'll simplify the equations below for a bit of micro-optimization.
* The commented out code is the unsimplified version.
// Partial derivates of window coordinates:
//
// x_w = 0.5 * viewport_width * x_c / w_c + viewport_center_x
// y_w = 0.5 * viewport_height * y_c / w_c + viewport_center_y
//
// with respect to u, v, using
// d(a/b)/dx = da/dx * (1/b) - a * db/dx / (b^2)
dxdu = 0.5 * viewport_width * (pm.xx - pm.wx * (xc/wc)) / wc;
dxdv = 0.5 * viewport_width * (pm.xy - pm.wy * (xc/wc)) / wc;
dydu = 0.5 * viewport_height * (pm.yx - pm.wx * (yc/wc)) / wc;
dydv = 0.5 * viewport_height * (pm.yy - pm.wy * (yc/wc)) / wc;
// Compute the inverse partials as the matrix inverse
det = dxdu * dydv - dxdv * dydu;
dudx = dydv / det;
dudy = - dxdv / det;
dvdx = - dydu / det;
dvdy = dvdu / det;
// Scale factor; maximum of the distance in texels for a change of 1 pixel
// in the X direction or 1 pixel in the Y direction
rho = MAX (sqrt (dudx * dudx + dvdx * dvdx), sqrt(dudy * dudy + dvdy * dvdy));
// Level of detail
lambda = log2 (rho) + LOD_BIAS;
*/
/* dxdu * wc, etc */
dxdu_ = 0.5 * viewport_width * (pm.xx - pm.wx * (xc/wc));
dxdv_ = 0.5 * viewport_width * (pm.xy - pm.wy * (xc/wc));
dydu_ = 0.5 * viewport_height * (pm.yx - pm.wx * (yc/wc));
dydv_ = 0.5 * viewport_height * (pm.yy - pm.wy * (yc/wc));
/* det * wc^2 */
det_ = dxdu_ * dydv_ - dxdv_ * dydu_;
det_sq = det_ * det_;
if (det_sq == 0.0)
return -1;
/* (rho * det * wc)^2 */
rho_sq = MAX (dydv_ * dydv_ + dydu_ * dydu_, dxdv_ * dxdv_ + dxdu_ * dxdu_);
lambda = 0.5 * M_LOG2E * log (rho_sq * wc * wc / det_sq) + LOD_BIAS;
#if 0
g_print ("%g %g %g\n", 0.5 * viewport_width * pm.xx / pm.ww, 0.5 * viewport_height * pm.yy / pm.ww, lambda);
#endif
if (lambda <= 0.)
return 0;
else
return (int)(0.5 + lambda);
}
static gboolean
is_power_of_two (int x)
{
return (x & (x - 1)) == 0;
}
static void
texture_tower_create_texture (MetaTextureTower *tower,
int level,
int width,
int height)
{
if ((!is_power_of_two (width) || !is_power_of_two (height)) &&
meta_texture_rectangle_check (tower->textures[level - 1]))
{
tower->textures[level] =
meta_texture_rectangle_new (width, height,
/* data format */
TEXTURE_FORMAT,
/* internal cogl format */
TEXTURE_FORMAT,
/* rowstride */
width * 4,
/* data */
NULL,
/* error */
NULL);
}
else
{
tower->textures[level] = cogl_texture_new_with_size (width, height,
COGL_TEXTURE_NO_AUTO_MIPMAP,
TEXTURE_FORMAT);
}
tower->invalid[level].x1 = 0;
tower->invalid[level].y1 = 0;
tower->invalid[level].x2 = width;
tower->invalid[level].y2 = height;
}
static gboolean
texture_tower_revalidate_fbo (MetaTextureTower *tower,
int level)
{
CoglHandle source_texture = tower->textures[level - 1];
int source_texture_width = cogl_texture_get_width (source_texture);
int source_texture_height = cogl_texture_get_height (source_texture);
CoglHandle dest_texture = tower->textures[level];
int dest_texture_width = cogl_texture_get_width (dest_texture);
int dest_texture_height = cogl_texture_get_height (dest_texture);
Box *invalid = &tower->invalid[level];
CoglMatrix modelview;
if (tower->fbos[level] == COGL_INVALID_HANDLE)
tower->fbos[level] = cogl_offscreen_new_to_texture (dest_texture);
if (tower->fbos[level] == COGL_INVALID_HANDLE)
return FALSE;
cogl_push_framebuffer (tower->fbos[level]);
cogl_ortho (0, dest_texture_width, dest_texture_height, 0, -1., 1.);
cogl_matrix_init_identity (&modelview);
cogl_set_modelview_matrix (&modelview);
cogl_set_source_texture (tower->textures[level - 1]);
cogl_rectangle_with_texture_coords (invalid->x1, invalid->y1,
invalid->x2, invalid->y2,
(2. * invalid->x1) / source_texture_width,
(2. * invalid->y1) / source_texture_height,
(2. * invalid->x2) / source_texture_width,
(2. * invalid->y2) / source_texture_height);
cogl_pop_framebuffer ();
return TRUE;
}
static void
fill_copy (guchar *buf,
const guchar *source,
int width)
{
memcpy (buf, source, width * 4);
}
static void
fill_scale_down (guchar *buf,
const guchar *source,
int width)
{
while (width > 1)
{
buf[0] = (source[0] + source[4]) / 2;
buf[1] = (source[1] + source[5]) / 2;
buf[2] = (source[2] + source[6]) / 2;
buf[3] = (source[3] + source[7]) / 2;
buf += 4;
source += 8;
width -= 2;
}
if (width > 0)
{
buf[0] = source[0] / 2;
buf[1] = source[1] / 2;
buf[2] = source[2] / 2;
buf[3] = source[3] / 2;
}
}
static void
texture_tower_revalidate_client (MetaTextureTower *tower,
int level)
{
CoglHandle source_texture = tower->textures[level - 1];
int source_texture_width = cogl_texture_get_width (source_texture);
int source_texture_height = cogl_texture_get_height (source_texture);
guint source_rowstride;
guchar *source_data;
CoglHandle dest_texture = tower->textures[level];
int dest_texture_width = cogl_texture_get_width (dest_texture);
int dest_texture_height = cogl_texture_get_height (dest_texture);
int dest_x = tower->invalid[level].x1;
int dest_y = tower->invalid[level].y1;
int dest_width = tower->invalid[level].x2 - tower->invalid[level].x1;
int dest_height = tower->invalid[level].y2 - tower->invalid[level].y1;
guchar *dest_data;
guchar *source_tmp1 = NULL, *source_tmp2 = NULL;
int i, j;
source_rowstride = source_texture_width * 4;
source_data = g_malloc (source_texture_height * source_rowstride);
cogl_texture_get_data (source_texture, TEXTURE_FORMAT, source_rowstride,
source_data);
dest_data = g_malloc (dest_height * dest_width * 4);
if (dest_texture_height < source_texture_height)
{
source_tmp1 = g_malloc (dest_width * 4);
source_tmp2 = g_malloc (dest_width * 4);
}
for (i = 0; i < dest_height; i++)
{
guchar *dest_row = dest_data + i * dest_width * 4;
if (dest_texture_height < source_texture_height)
{
guchar *source1, *source2;
guchar *dest;
if (dest_texture_width < source_texture_width)
{
fill_scale_down (source_tmp1,
source_data + ((i + dest_y) * 2) * source_rowstride + dest_x * 2 * 4,
dest_width * 2);
fill_scale_down (source_tmp2,
source_data + ((i + dest_y) * 2 + 1) * source_rowstride + dest_x * 2 * 4,
dest_width * 2);
}
else
{
fill_copy (source_tmp1,
source_data + ((i + dest_y) * 2) * source_rowstride + dest_x * 4,
dest_width);
fill_copy (source_tmp2,
source_data + ((i + dest_y) * 2 + 1) * source_rowstride + dest_x * 4,
dest_width);
}
source1 = source_tmp1;
source2 = source_tmp2;
dest = dest_row;
for (j = 0; j < dest_width * 4; j++)
*(dest++) = (*(source1++) + *(source2++)) / 2;
}
else
{
if (dest_texture_width < source_texture_width)
fill_scale_down (dest_row,
source_data + (i + dest_y) * source_rowstride + dest_x * 2 * 4,
dest_width * 2);
else
fill_copy (dest_row,
source_data + (i + dest_y) * source_rowstride,
dest_width);
}
}
cogl_texture_set_region (dest_texture,
0, 0,
dest_x, dest_y,
dest_width, dest_height,
dest_width, dest_height,
TEXTURE_FORMAT,
4 * dest_width,
dest_data);
if (dest_texture_height < source_texture_height)
{
g_free (source_tmp1);
g_free (source_tmp2);
}
g_free (source_data);
g_free (dest_data);
}
static void
texture_tower_revalidate (MetaTextureTower *tower,
int level)
{
if (!texture_tower_revalidate_fbo (tower, level))
texture_tower_revalidate_client (tower, level);
}
/**
* meta_texture_tower_get_paint_texture:
* @tower: a #MetaTextureTower
*
* Gets the texture from the tower that best matches the current
* rendering scale. (On the assumption here the texture is going to
* be rendered with vertex coordinates that correspond to its
* size in pixels, so a 200x200 texture will be rendered on the
* rectangle (0, 0, 200, 200).
*
* Return value: the COGL texture handle to use for painting, or
* %COGL_INVALID_HANDLE if no base texture has yet been set.
*/
CoglHandle
meta_texture_tower_get_paint_texture (MetaTextureTower *tower)
{
int texture_width, texture_height;
int level;
g_return_val_if_fail (tower != NULL, COGL_INVALID_HANDLE);
if (tower->textures[0] == COGL_INVALID_HANDLE)
return COGL_INVALID_HANDLE;
texture_width = cogl_texture_get_width (tower->textures[0]);
texture_height = cogl_texture_get_height (tower->textures[0]);
level = get_paint_level(texture_width, texture_height);
if (level < 0) /* singular paint matrix, scaled to nothing */
return COGL_INVALID_HANDLE;
level = MIN (level, tower->n_levels - 1);
if (tower->textures[level] == COGL_INVALID_HANDLE ||
(tower->invalid[level].x2 != tower->invalid[level].x1 &&
tower->invalid[level].y2 != tower->invalid[level].y1))
{
int i;
for (i = 1; i <= level; i++)
{
/* Use "floor" convention here to be consistent with the NPOT texture extension */
texture_width = MAX (1, texture_width / 2);
texture_height = MAX (1, texture_height / 2);
if (tower->textures[i] == COGL_INVALID_HANDLE)
texture_tower_create_texture (tower, i, texture_width, texture_height);
}
for (i = 1; i <= level; i++)
{
if (tower->invalid[level].x2 != tower->invalid[level].x1 &&
tower->invalid[level].y2 != tower->invalid[level].y1)
texture_tower_revalidate (tower, i);
}
}
return tower->textures[level];
}

View File

@@ -1,69 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* MetaTextureTower
*
* Mipmap emulation by creation of scaled down images
*
* Copyright (C) 2009 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef __META_TEXTURE_TOWER_H__
#define __META_TEXTURE_TOWER_H__
#include <clutter/clutter.h>
G_BEGIN_DECLS
/**
* SECTION:MetaTextureTower
* @short_description: mipmap emulation by creation of scaled down images
*
* A #MetaTextureTower is used to get good looking scaled down images when
* we can't use the GL drivers mipmap support. There are two separate reasons
*
* - Some cards (including radeon cards <= r5xx) only support
* TEXTURE_RECTANGLE_ARB and not NPOT textures. Rectangular textures
* are defined not to support mipmapping.
* - Even when NPOT textures are available, the combination of NPOT
* textures, texture_from_pixmap, and mipmapping doesn't typically
* work, since the X server doesn't allocate pixmaps in the right
* layout for mipmapping.
*
* So, what we do is create the "mipmap" levels ourselves by successive
* power-of-two scaledowns, and when rendering pick the single texture
* that best matches the scale we are rendering at. (Since we aren't
* typically using perspective transforms, we'll frequently have a single
* scale for the entire texture.)
*/
typedef struct _MetaTextureTower MetaTextureTower;
MetaTextureTower *meta_texture_tower_new (void);
void meta_texture_tower_free (MetaTextureTower *tower);
void meta_texture_tower_set_base_texture (MetaTextureTower *tower,
CoglHandle texture);
void meta_texture_tower_update_area (MetaTextureTower *tower,
int x,
int y,
int width,
int height);
CoglHandle meta_texture_tower_get_paint_texture (MetaTextureTower *tower);
G_BEGIN_DECLS
#endif /* __META_TEXTURE_TOWER_H__ */

View File

@@ -1,60 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#ifndef META_WINDOW_ACTOR_PRIVATE_H
#define META_WINDOW_ACTOR_PRIVATE_H
#include <config.h>
#include <X11/extensions/Xdamage.h>
#include <meta/compositor-mutter.h>
MetaWindowActor *meta_window_actor_new (MetaWindow *window);
void meta_window_actor_destroy (MetaWindowActor *self);
void meta_window_actor_show (MetaWindowActor *self,
MetaCompEffect effect);
void meta_window_actor_hide (MetaWindowActor *self,
MetaCompEffect effect);
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_damage (MetaWindowActor *self,
XDamageNotifyEvent *event);
void meta_window_actor_pre_paint (MetaWindowActor *self);
void meta_window_actor_invalidate_shadow (MetaWindowActor *self);
void meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state);
gboolean meta_window_actor_should_unredirect (MetaWindowActor *self);
void meta_window_actor_get_shape_bounds (MetaWindowActor *self,
cairo_rectangle_int_t *bounds);
gboolean meta_window_actor_effect_in_progress (MetaWindowActor *self);
void meta_window_actor_sync_actor_position (MetaWindowActor *self);
void meta_window_actor_sync_visibility (MetaWindowActor *self);
void meta_window_actor_update_shape (MetaWindowActor *self);
void meta_window_actor_update_opacity (MetaWindowActor *self);
void meta_window_actor_mapped (MetaWindowActor *self);
void meta_window_actor_unmapped (MetaWindowActor *self);
cairo_region_t *meta_window_actor_get_obscured_region (MetaWindowActor *self);
void meta_window_actor_set_visible_region (MetaWindowActor *self,
cairo_region_t *visible_region);
void meta_window_actor_set_visible_region_beneath (MetaWindowActor *self,
cairo_region_t *beneath_region);
void meta_window_actor_reset_visible_regions (MetaWindowActor *self);
void meta_window_actor_effect_completed (MetaWindowActor *actor,
gulong event);
#endif /* META_WINDOW_ACTOR_PRIVATE_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,363 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#include <config.h>
#define _ISOC99_SOURCE /* for roundf */
#include <math.h>
#include <gdk/gdk.h> /* for gdk_rectangle_intersect() */
#include "compositor-private.h"
#include "meta-window-actor-private.h"
#include "meta-window-group.h"
#include "meta-background-actor-private.h"
struct _MetaWindowGroupClass
{
ClutterGroupClass parent_class;
};
struct _MetaWindowGroup
{
ClutterGroup parent;
MetaScreen *screen;
};
G_DEFINE_TYPE (MetaWindowGroup, meta_window_group, CLUTTER_TYPE_GROUP);
/* This file uses pixel-aligned region computation to determine what
* can be clipped out. This only really works if everything is aligned
* to the pixel grid - not scaled or rotated and at integer offsets.
*
* (This could be relaxed - if we turned off filtering for unscaled
* windows then windows would be, by definition aligned to the pixel
* grid. And for rectangular windows without a shape, the outline that
* we draw for an unrotated window is always a rectangle because we
* don't use antialasing for the window boundary - with or without
* filtering, with or without a scale. But figuring out exactly
* what pixels will be drawn by the graphics system in these cases
* gets tricky, so we just go for the easiest part - no scale,
* and at integer offsets.)
*
* The way we check for pixel-aligned is by looking at the
* transformation into screen space of the allocation box of an actor
* and and checking if the corners are "close enough" to integral
* pixel values.
*/
/* The definition of "close enough" to integral pixel values is
* equality when we convert to 24.8 fixed-point.
*/
static inline int
round_to_fixed (float x)
{
return roundf (x * 256);
}
/* This helper function checks if (according to our fixed point precision)
* the vertices @verts form a box of width @widthf and height @heightf
* located at integral coordinates. These coordinates are returned
* in @x_origin and @y_origin.
*/
static gboolean
vertices_are_untransformed (ClutterVertex *verts,
float widthf,
float heightf,
int *x_origin,
int *y_origin)
{
int width, height;
int v0x, v0y, v1x, v1y, v2x, v2y, v3x, v3y;
int x, y;
width = round_to_fixed (widthf); height = round_to_fixed (heightf);
v0x = round_to_fixed (verts[0].x); v0y = round_to_fixed (verts[0].y);
v1x = round_to_fixed (verts[1].x); v1y = round_to_fixed (verts[1].y);
v2x = round_to_fixed (verts[2].x); v2y = round_to_fixed (verts[2].y);
v3x = round_to_fixed (verts[3].x); v3y = round_to_fixed (verts[3].y);
/* Using shifting for converting fixed => int, gets things right for
* negative values. / 256. wouldn't do the same
*/
x = v0x >> 8;
y = v0y >> 8;
/* At integral coordinates? */
if (x * 256 != v0x || y * 256 != v0y)
return FALSE;
/* Not scaled? */
if (v1x - v0x != width || v2y - v0y != height)
return FALSE;
/* Not rotated/skewed? */
if (v0x != v2x || v0y != v1y ||
v3x != v1x || v3y != v2y)
return FALSE;
*x_origin = x;
*y_origin = y;
return TRUE;
}
/* Check if an actor is "untransformed" - which actually means transformed by
* at most a integer-translation. The integer translation, if any, is returned.
*/
static gboolean
actor_is_untransformed (ClutterActor *actor,
int *x_origin,
int *y_origin)
{
gfloat widthf, heightf;
ClutterVertex verts[4];
clutter_actor_get_size (actor, &widthf, &heightf);
clutter_actor_get_abs_allocation_vertices (actor, verts);
return vertices_are_untransformed (verts, widthf, heightf, x_origin, y_origin);
}
/* Help macros to scale from OpenGL <-1,1> coordinates system to
* window coordinates ranging [0,window-size]. Borrowed from clutter-utils.c
*/
#define MTX_GL_SCALE_X(x,w,v1,v2) ((((((x) / (w)) + 1.0f) / 2.0f) * (v1)) + (v2))
#define MTX_GL_SCALE_Y(y,w,v1,v2) ((v1) - (((((y) / (w)) + 1.0f) / 2.0f) * (v1)) + (v2))
/* Check if we're painting the MetaWindowGroup "untransformed". This can
* differ from the result of actor_is_untransformed(window_group) if we're
* inside a clone paint. The integer translation, if any, is returned.
*/
static gboolean
painting_untransformed (MetaWindowGroup *window_group,
int *x_origin,
int *y_origin)
{
CoglMatrix modelview, projection, modelview_projection;
ClutterVertex vertices[4];
int width, height;
float viewport[4];
int i;
cogl_get_modelview_matrix (&modelview);
cogl_get_projection_matrix (&projection);
cogl_matrix_multiply (&modelview_projection,
&projection,
&modelview);
meta_screen_get_size (window_group->screen, &width, &height);
vertices[0].x = 0;
vertices[0].y = 0;
vertices[0].z = 0;
vertices[1].x = width;
vertices[1].y = 0;
vertices[1].z = 0;
vertices[2].x = 0;
vertices[2].y = height;
vertices[2].z = 0;
vertices[3].x = width;
vertices[3].y = height;
vertices[3].z = 0;
cogl_get_viewport (viewport);
for (i = 0; i < 4; i++)
{
float w = 1;
cogl_matrix_transform_point (&modelview_projection, &vertices[i].x, &vertices[i].y, &vertices[i].z, &w);
vertices[i].x = MTX_GL_SCALE_X (vertices[i].x, w,
viewport[2], viewport[0]);
vertices[i].y = MTX_GL_SCALE_Y (vertices[i].y, w,
viewport[3], viewport[1]);
}
return vertices_are_untransformed (vertices, width, height, x_origin, y_origin);
}
static void
meta_window_group_paint (ClutterActor *actor)
{
cairo_region_t *visible_region;
ClutterActor *stage;
cairo_rectangle_int_t visible_rect;
GList *children, *l;
int paint_x_origin, paint_y_origin;
int actor_x_origin, actor_y_origin;
int paint_x_offset, paint_y_offset;
MetaWindowGroup *window_group = META_WINDOW_GROUP (actor);
MetaCompScreen *info = meta_screen_get_compositor_data (window_group->screen);
/* Normally we expect an actor to be drawn at it's position on the screen.
* However, if we're inside the paint of a ClutterClone, that won't be the
* case and we need to compensate. We look at the position of the window
* group under the current model-view matrix and the position of the actor.
* If they are both simply integer translations, then we can compensate
* easily, otherwise we give up.
*
* Possible cleanup: work entirely in paint space - we can compute the
* combination of the model-view matrix with the local matrix for each child
* actor and get a total transformation for that actor for how we are
* painting currently, and never worry about how actors are positioned
* on the stage.
*/
if (!painting_untransformed (window_group, &paint_x_origin, &paint_y_origin) ||
!actor_is_untransformed (actor, &actor_x_origin, &actor_y_origin))
{
CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor);
return;
}
paint_x_offset = paint_x_origin - actor_x_origin;
paint_y_offset = paint_y_origin - actor_y_origin;
/* We walk the list from top to bottom (opposite of painting order),
* and subtract the opaque area of each window out of the visible
* region that we pass to the windows below.
*/
children = clutter_container_get_children (CLUTTER_CONTAINER (actor));
children = g_list_reverse (children);
/* Get the clipped redraw bounds from Clutter so that we can avoid
* painting shadows on windows that don't need to be painted in this
* frame. In the case of a multihead setup with mismatched monitor
* sizes, we could intersect this with an accurate union of the
* monitors to avoid painting shadows that are visible only in the
* holes. */
stage = clutter_actor_get_stage (actor);
clutter_stage_get_redraw_clip_bounds (CLUTTER_STAGE (stage),
&visible_rect);
visible_region = cairo_region_create_rectangle (&visible_rect);
if (info->unredirected_window != NULL)
{
cairo_rectangle_int_t unredirected_rect;
MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window);
meta_window_get_outer_rect (window, (MetaRectangle *)&unredirected_rect);
cairo_region_subtract_rectangle (visible_region, &unredirected_rect);
}
for (l = children; l; l = l->next)
{
if (!CLUTTER_ACTOR_IS_VISIBLE (l->data))
continue;
if (l->data == info->unredirected_window)
continue;
/* If an actor has effects applied, then that can change the area
* it paints and the opacity, so we no longer can figure out what
* portion of the actor is obscured and what portion of the screen
* it obscures, so we skip the actor.
*
* This has a secondary beneficial effect: if a ClutterOffscreenEffect
* is applied to an actor, then our clipped redraws interfere with the
* caching of the FBO - even if we only need to draw a small portion
* of the window right now, ClutterOffscreenEffect may use other portions
* of the FBO later. So, skipping actors with effects applied also
* prevents these bugs.
*
* Theoretically, we should check clutter_actor_get_offscreen_redirect()
* as well for the same reason, but omitted for simplicity in the
* hopes that no-one will do that.
*/
if (clutter_actor_has_effects (l->data))
continue;
if (META_IS_WINDOW_ACTOR (l->data))
{
MetaWindowActor *window_actor = l->data;
int x, y;
if (!actor_is_untransformed (CLUTTER_ACTOR (window_actor), &x, &y))
continue;
x += paint_x_offset;
y += paint_y_offset;
/* Temporarily move to the coordinate system of the actor */
cairo_region_translate (visible_region, - x, - y);
meta_window_actor_set_visible_region (window_actor, visible_region);
if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (window_actor)) == 0xff)
{
cairo_region_t *obscured_region = meta_window_actor_get_obscured_region (window_actor);
if (obscured_region)
cairo_region_subtract (visible_region, obscured_region);
}
meta_window_actor_set_visible_region_beneath (window_actor, visible_region);
cairo_region_translate (visible_region, x, y);
}
else if (META_IS_BACKGROUND_ACTOR (l->data))
{
MetaBackgroundActor *background_actor = l->data;
int x, y;
if (!actor_is_untransformed (CLUTTER_ACTOR (background_actor), &x, &y))
continue;
x += paint_x_offset;
y += paint_y_offset;
cairo_region_translate (visible_region, - x, - y);
meta_background_actor_set_visible_region (background_actor, visible_region);
cairo_region_translate (visible_region, x, y);
}
}
cairo_region_destroy (visible_region);
CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor);
/* Now that we are done painting, unset the visible regions (they will
* mess up painting clones of our actors)
*/
for (l = children; l; l = l->next)
{
if (META_IS_WINDOW_ACTOR (l->data))
{
MetaWindowActor *window_actor = l->data;
meta_window_actor_reset_visible_regions (window_actor);
}
else if (META_IS_BACKGROUND_ACTOR (l->data))
{
MetaBackgroundActor *background_actor = l->data;
meta_background_actor_set_visible_region (background_actor, NULL);
}
}
g_list_free (children);
}
static void
meta_window_group_class_init (MetaWindowGroupClass *klass)
{
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
actor_class->paint = meta_window_group_paint;
}
static void
meta_window_group_init (MetaWindowGroup *window_group)
{
}
ClutterActor *
meta_window_group_new (MetaScreen *screen)
{
MetaWindowGroup *window_group;
window_group = g_object_new (META_TYPE_WINDOW_GROUP, NULL);
window_group->screen = screen;
return CLUTTER_ACTOR (window_group);
}

View File

@@ -1,52 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#ifndef META_WINDOW_GROUP_H
#define META_WINDOW_GROUP_H
#include <clutter/clutter.h>
#include <meta/screen.h>
/**
* MetaWindowGroup:
*
* This class is a subclass of ClutterGroup with special handling for
* MetaWindowActor when painting the group. When we are painting a stack
* of 5-10 maximized windows, the standard bottom-to-top method of
* drawing every actor results in a tremendous amount of overdraw
* and can easily max out the available memory bandwidth on a low-end
* graphics chipset. It's even worse if window textures are being accessed
* over the AGP bus.
*
* The basic technique applied here is to do a pre-pass before painting
* where we walk window from top to bottom and compute the visible area
* at each step by subtracting out the windows above it. The visible
* area is passed to MetaWindowActor which uses it to clip the portion of
* the window which drawn and avoid redrawing the shadow if it is completely
* obscured.
*
* A caveat is that this is ineffective if applications are using ARGB
* visuals, since we have no way of knowing whether a window obscures
* the windows behind it or not. Alternate approaches using the depth
* or stencil buffer rather than client side regions might be able to
* handle alpha windows, but the combination of glAlphaFunc and stenciling
* tends not to be efficient except on newer cards. (And on newer cards
* we have lots of memory and bandwidth.)
*/
#define META_TYPE_WINDOW_GROUP (meta_window_group_get_type ())
#define META_WINDOW_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WINDOW_GROUP, MetaWindowGroup))
#define META_WINDOW_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_WINDOW_GROUP, MetaWindowGroupClass))
#define META_IS_WINDOW_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_WINDOW_GROUP))
#define META_IS_WINDOW_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_WINDOW_GROUP))
#define META_WINDOW_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_WINDOW_GROUP, MetaWindowGroupClass))
typedef struct _MetaWindowGroup MetaWindowGroup;
typedef struct _MetaWindowGroupClass MetaWindowGroupClass;
typedef struct _MetaWindowGroupPrivate MetaWindowGroupPrivate;
GType meta_window_group_get_type (void);
ClutterActor *meta_window_group_new (MetaScreen *screen);
#endif /* META_WINDOW_GROUP_H */

View File

@@ -1,254 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* MetaWindowShape
*
* Extracted invariant window shape
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <string.h>
#include "meta-window-shape.h"
#include "region-utils.h"
struct _MetaWindowShape
{
guint ref_count;
int top, right, bottom, left;
int n_rectangles;
cairo_rectangle_int_t *rectangles;
guint hash;
};
MetaWindowShape *
meta_window_shape_new (cairo_region_t *region)
{
MetaWindowShape *shape;
MetaRegionIterator iter;
cairo_rectangle_int_t extents;
int max_yspan_y1 = 0;
int max_yspan_y2 = 0;
int max_xspan_x1 = -1;
int max_xspan_x2 = -1;
guint hash;
shape = g_slice_new0 (MetaWindowShape);
shape->ref_count = 1;
cairo_region_get_extents (region, &extents);
shape->n_rectangles = cairo_region_num_rectangles (region);
if (shape->n_rectangles == 0)
{
shape->rectangles = NULL;
shape->top = shape->right = shape->bottom = shape->left = 0;
shape->hash = 0;
return shape;
}
for (meta_region_iterator_init (&iter, region);
!meta_region_iterator_at_end (&iter);
meta_region_iterator_next (&iter))
{
int max_line_xspan_x1 = -1;
int max_line_xspan_x2 = -1;
if (iter.rectangle.width > max_line_xspan_x2 - max_line_xspan_x1)
{
max_line_xspan_x1 = iter.rectangle.x;
max_line_xspan_x2 = iter.rectangle.x + iter.rectangle.width;
}
if (iter.line_end)
{
if (iter.rectangle.height > max_yspan_y2 - max_yspan_y1)
{
max_yspan_y1 = iter.rectangle.y;
max_yspan_y2 = iter.rectangle.y + iter.rectangle.height;
}
if (max_xspan_x1 < 0) /* First line */
{
max_xspan_x1 = max_line_xspan_x1;
max_xspan_x2 = max_line_xspan_x2;
}
else
{
max_xspan_x1 = MAX (max_xspan_x1, max_line_xspan_x1);
max_xspan_x2 = MIN (max_xspan_x2, max_line_xspan_x2);
if (max_xspan_x2 < max_xspan_x1)
max_xspan_x2 = max_xspan_x1;
}
}
}
#if 0
g_print ("xspan: %d -> %d, yspan: %d -> %d\n",
max_xspan_x1, max_xspan_x2,
max_yspan_y1, max_yspan_y2);
#endif
shape->top = max_yspan_y1 - extents.y;
shape->right = extents.x + extents.width - max_xspan_x2;
shape->bottom = extents.y + extents.height - max_yspan_y2;
shape->left = max_xspan_x1 - extents.x;
shape->rectangles = g_new (cairo_rectangle_int_t, shape->n_rectangles);
hash = 0;
for (meta_region_iterator_init (&iter, region);
!meta_region_iterator_at_end (&iter);
meta_region_iterator_next (&iter))
{
int x1, x2, y1, y2;
x1 = iter.rectangle.x;
x2 = iter.rectangle.x + iter.rectangle.width;
y1 = iter.rectangle.y;
y2 = iter.rectangle.y + iter.rectangle.height;
if (x1 > max_xspan_x1)
x1 -= MIN (x1, max_xspan_x2 - 1) - max_xspan_x1;
if (x2 > max_xspan_x1)
x2 -= MIN (x2, max_xspan_x2 - 1) - max_xspan_x1;
if (y1 > max_yspan_y1)
y1 -= MIN (y1, max_yspan_y2 - 1) - max_yspan_y1;
if (y2 > max_yspan_y1)
y2 -= MIN (y2, max_yspan_y2 - 1) - max_yspan_y1;
shape->rectangles[iter.i].x = x1 - extents.x;
shape->rectangles[iter.i].y = y1 - extents.y;
shape->rectangles[iter.i].width = x2 - x1;
shape->rectangles[iter.i].height = y2 - y1;
#if 0
g_print ("%d: +%d+%dx%dx%d => +%d+%dx%dx%d\n",
iter.i, iter.rectangle.x, iter.rectangle.y, iter.rectangle.width, iter.rectangle.height,
shape->rectangles[iter.i].x, shape->rectangles[iter.i].y,
hape->rectangles[iter.i].width, shape->rectangles[iter.i].height);
#endif
hash = hash * 31 + x1 * 17 + x2 * 27 + y1 * 37 + y2 * 43;
}
shape->hash = hash;
#if 0
g_print ("%d %d %d %d: %#x\n\n", shape->top, shape->right, shape->bottom, shape->left, shape->hash);
#endif
return shape;
}
MetaWindowShape *
meta_window_shape_ref (MetaWindowShape *shape)
{
shape->ref_count++;
return shape;
}
void
meta_window_shape_unref (MetaWindowShape *shape)
{
shape->ref_count--;
if (shape->ref_count == 0)
{
g_free (shape->rectangles);
g_slice_free (MetaWindowShape, shape);
}
}
guint
meta_window_shape_hash (MetaWindowShape *shape)
{
return shape->hash;
}
gboolean
meta_window_shape_equal (MetaWindowShape *shape_a,
MetaWindowShape *shape_b)
{
if (shape_a->n_rectangles != shape_b->n_rectangles)
return FALSE;
return memcmp (shape_a->rectangles, shape_b->rectangles,
sizeof (cairo_rectangle_int_t) * shape_a->n_rectangles) == 0;
}
void
meta_window_shape_get_borders (MetaWindowShape *shape,
int *border_top,
int *border_right,
int *border_bottom,
int *border_left)
{
if (border_top)
*border_top = shape->top;
if (border_right)
*border_right = shape->right;
if (border_bottom)
*border_bottom = shape->bottom;
if (border_left)
*border_left = shape->left;
}
/**
* meta_window_shape_to_region:
* @shape: a #MetaWindowShape
* @center_width: size of the central region horizontally
* @center_height: size of the central region vertically
*
* Converts the shape to to a cairo_region_t using the given width
* and height for the central scaled region.
*
* Return value: a newly created region
*/
cairo_region_t *
meta_window_shape_to_region (MetaWindowShape *shape,
int center_width,
int center_height)
{
cairo_region_t *region;
int i;
region = cairo_region_create ();
for (i = 0; i < shape->n_rectangles; i++)
{
cairo_rectangle_int_t rect = shape->rectangles[i];
if (rect.x <= shape->left && rect.x + rect.width >= shape->left + 1)
rect.width += center_width;
else if (rect.x >= shape->left + 1)
rect.x += center_width;
if (rect.y <= shape->top && rect.y + rect.height >= shape->top + 1)
rect.height += center_height;
else if (rect.y >= shape->top + 1)
rect.y += center_height;
cairo_region_union_rectangle (region, &rect);
}
return region;
}

View File

@@ -1,60 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* MetaWindowShape
*
* Extracted invariant window shape
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef __META_WINDOW_SHAPE_H__
#define __META_WINDOW_SHAPE_H__
#include <cairo.h>
#include <glib.h>
/**
* MetaWindowShape:
* #MetaWindowShape represents a 9-sliced region with borders on all sides that
* are unscaled, and a constant central region that is scaled. For example,
* the regions representing two windows that are rounded rectangles,
* with the same corner radius but different sizes, have the
* same MetaWindowShape.
*
* #MetaWindowShape is designed to be used as part of a hash table key, so has
* efficient hash and equal functions.
*/
typedef struct _MetaWindowShape MetaWindowShape;
MetaWindowShape * meta_window_shape_new (cairo_region_t *region);
MetaWindowShape * meta_window_shape_ref (MetaWindowShape *shape);
void meta_window_shape_unref (MetaWindowShape *shape);
guint meta_window_shape_hash (MetaWindowShape *shape);
gboolean meta_window_shape_equal (MetaWindowShape *shape_a,
MetaWindowShape *shape_b);
void meta_window_shape_get_borders (MetaWindowShape *shape,
int *border_top,
int *border_right,
int *border_bottom,
int *border_left);
cairo_region_t *meta_window_shape_to_region (MetaWindowShape *shape,
int center_width,
int center_height);
#endif /* __META_WINDOW_SHAPE_H __*/

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