Compare commits
19 Commits
3.6.0
...
override-r
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8a0de6dfd3 | ||
![]() |
2bf0b2b6de | ||
![]() |
eed2a2d324 | ||
![]() |
9828007a02 | ||
![]() |
1f890672bb | ||
![]() |
ef966854d5 | ||
![]() |
7309b6cfe3 | ||
![]() |
3705a224f0 | ||
![]() |
2ebedb822d | ||
![]() |
d6576d9b70 | ||
![]() |
6516c19ec5 | ||
![]() |
5518fee61c | ||
![]() |
ace0521cba | ||
![]() |
0091a3aab5 | ||
![]() |
268b92a4ec | ||
![]() |
29bb4c27e3 | ||
![]() |
bd3bdc51b9 | ||
![]() |
0123dab87a | ||
![]() |
413acc9574 |
39
.gitignore
vendored
39
.gitignore
vendored
@@ -13,23 +13,17 @@ config.sub
|
|||||||
configure
|
configure
|
||||||
depcomp
|
depcomp
|
||||||
install-sh
|
install-sh
|
||||||
intltool-extract.in
|
|
||||||
intltool-merge.in
|
|
||||||
libtool
|
libtool
|
||||||
ltmain.sh
|
ltmain.sh
|
||||||
missing
|
missing
|
||||||
.deps
|
.deps
|
||||||
src/50-mutter-windows.xml
|
src/metacity-wm.desktop
|
||||||
src/mutter-wm.desktop
|
|
||||||
src/mutter.desktop
|
|
||||||
*.o
|
*.o
|
||||||
*.a
|
*.a
|
||||||
*.lo
|
*.lo
|
||||||
*.la
|
*.la
|
||||||
.libs
|
.libs
|
||||||
*.swp
|
*.swp
|
||||||
*.gir
|
|
||||||
*.typelib
|
|
||||||
tidy-enum-types.[ch]
|
tidy-enum-types.[ch]
|
||||||
tidy-marshal.[ch]
|
tidy-marshal.[ch]
|
||||||
stamp-tidy-enum-types.h
|
stamp-tidy-enum-types.h
|
||||||
@@ -41,35 +35,26 @@ stamp-h1
|
|||||||
stamp-it
|
stamp-it
|
||||||
.intltool-merge-cache
|
.intltool-merge-cache
|
||||||
POTFILES
|
POTFILES
|
||||||
po/*.pot
|
|
||||||
50-metacity-desktop-key.xml
|
50-metacity-desktop-key.xml
|
||||||
50-metacity-key.xml
|
50-metacity-key.xml
|
||||||
inlinepixbufs.h
|
inlinepixbufs.h
|
||||||
libmutter.pc
|
libmetacity-private.pc
|
||||||
mutter
|
metacity
|
||||||
mutter-theme-viewer
|
metacity-dialog
|
||||||
mutter.desktop
|
metacity-theme-viewer
|
||||||
org.gnome.mutter.gschema.valid
|
metacity.desktop
|
||||||
org.gnome.mutter.gschema.xml
|
metacity.schemas
|
||||||
testasyncgetprop
|
testasyncgetprop
|
||||||
testboxes
|
testboxes
|
||||||
testgradient
|
testgradient
|
||||||
mutter-grayscale
|
metacity-grayscale
|
||||||
mutter-mag
|
metacity-mag
|
||||||
mutter-message
|
metacity-message
|
||||||
mutter-window-demo
|
metacity-window-demo
|
||||||
focus-window
|
focus-window
|
||||||
test-attached
|
|
||||||
test-gravity
|
test-gravity
|
||||||
test-resizing
|
test-resizing
|
||||||
test-size-hints
|
test-size-hints
|
||||||
# We can't say just "wm-tester" here or it will ignore the directory
|
wm-tester
|
||||||
# rather than the binary
|
|
||||||
src/wm-tester/wm-tester
|
|
||||||
INSTALL
|
INSTALL
|
||||||
mkinstalldirs
|
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
|
|
||||||
|
8
HACKING
8
HACKING
@@ -42,10 +42,10 @@ Minimal Building/Testing Environment
|
|||||||
build a development version of Metacity -- odds are, you may be able
|
build a development version of Metacity -- odds are, you may be able
|
||||||
to build metacity from CVS without building any other modules.
|
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
|
As long as you have gtk+ >= 2.10 and GConf with your distro (gtk+ >=
|
||||||
(gtk+ >= 2.6 if you manually revert the change from bug 348633), you
|
2.6 if you manually revert the change from bug 348633), you should
|
||||||
should be able to install your distro's development packages
|
be able to install your distro's development packages
|
||||||
(e.g. gtk2-devel, glib-devel, startup-notification-devel on
|
(e.g. gtk2-devel, GConf2-devel, startup-notification-devel on
|
||||||
Fedora; also, remember to install the gnome-common package which is
|
Fedora; also, remember to install the gnome-common package which is
|
||||||
needed for building cvs versions of Gnome modules like Metacity) as
|
needed for building cvs versions of Gnome modules like Metacity) as
|
||||||
well as the standard development tools (gcc, autoconf, automake,
|
well as the standard development tools (gcc, autoconf, automake,
|
||||||
|
31
README
31
README
@@ -18,8 +18,9 @@ COMPILING MUTTER
|
|||||||
You need GTK+ 2.2. For startup notification to work you need
|
You need GTK+ 2.2. For startup notification to work you need
|
||||||
libstartup-notification at
|
libstartup-notification at
|
||||||
http://www.freedesktop.org/software/startup-notification/ or on the
|
http://www.freedesktop.org/software/startup-notification/ or on the
|
||||||
GNOME ftp site.
|
GNOME ftp site. You also need GConf 1.2 (unless building a funky
|
||||||
You need Clutter 1.0. You need gobject-introspection 0.6.3.
|
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
|
REPORTING BUGS AND SUBMITTING PATCHES
|
||||||
===
|
===
|
||||||
@@ -58,24 +59,25 @@ MUTTER FEATURES
|
|||||||
and should work with KWin, fvwm2, and other EWMH-compliant WMs.)
|
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.
|
- Has a simple theme system and a couple of extra themes come with it.
|
||||||
Change themes via gsettings:
|
Change themes via gconf-editor or gconftool or GNOME themes control
|
||||||
gsettings set org.gnome.desktop.wm.preferences theme Crux
|
panel:
|
||||||
gsettings set org.gnome.desktop.wm.preferences theme Gorilla
|
gconftool-2 --type=string --set /apps/metacity/general/theme Crux
|
||||||
gsettings set org.gnome.desktop.wm.preferences theme Atlanta
|
gconftool-2 --type=string --set /apps/metacity/general/theme Gorilla
|
||||||
gsettings set org.gnome.desktop.wm.preferences theme Bright
|
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
|
See theme-format.txt for docs on the theme format. Use
|
||||||
metacity-theme-viewer to preview themes.
|
metacity-theme-viewer to preview themes.
|
||||||
|
|
||||||
- Change number of workspaces via gsettings:
|
- Change number of workspaces via gconf-editor or gconftool:
|
||||||
gsettings set org.gnome.desktop.wm.preferences num-workspaces 5
|
gconftool-2 --type=int --set /apps/metacity/general/num_workspaces 5
|
||||||
|
|
||||||
Can also change workspaces from GNOME 2 pager.
|
Can also change workspaces from GNOME 2 pager.
|
||||||
|
|
||||||
- Change focus mode:
|
- Change focus mode:
|
||||||
gsettings set org.gnome.desktop.wm.preferences focus-mode mouse
|
gconftool-2 --type=string --set /apps/metacity/general/focus_mode mouse
|
||||||
gsettings set org.gnome.desktop.wm.preferences focus-mode sloppy
|
gconftool-2 --type=string --set /apps/metacity/general/focus_mode sloppy
|
||||||
gsettings set org.gnome.desktop.wm.preferences focus-mode click
|
gconftool-2 --type=string --set /apps/metacity/general/focus_mode click
|
||||||
|
|
||||||
- Global keybinding defaults include:
|
- Global keybinding defaults include:
|
||||||
|
|
||||||
@@ -90,9 +92,10 @@ MUTTER FEATURES
|
|||||||
|
|
||||||
Change keybindings for example:
|
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:
|
- Window keybindings:
|
||||||
|
|
||||||
|
469
configure.in
469
configure.in
@@ -1,13 +1,15 @@
|
|||||||
AC_PREREQ(2.50)
|
AC_PREREQ(2.50)
|
||||||
|
|
||||||
m4_define([mutter_major_version], [3])
|
m4_define([mutter_major_version], [2])
|
||||||
m4_define([mutter_minor_version], [6])
|
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_micro_version], [0])
|
||||||
|
|
||||||
m4_define([mutter_version],
|
m4_define([mutter_version],
|
||||||
[mutter_major_version.mutter_minor_version.mutter_micro_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],
|
AC_INIT([mutter], [mutter_version],
|
||||||
[http://bugzilla.gnome.org/enter_bug.cgi?product=mutter])
|
[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_SRCDIR(src/core/display.c)
|
||||||
AC_CONFIG_HEADERS(config.h)
|
AC_CONFIG_HEADERS(config.h)
|
||||||
|
|
||||||
AM_INIT_AUTOMAKE([1.11 no-dist-gzip dist-xz tar-ustar])
|
AM_INIT_AUTOMAKE
|
||||||
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],)
|
AM_MAINTAINER_MODE
|
||||||
AM_MAINTAINER_MODE([enable])
|
|
||||||
|
|
||||||
MUTTER_MAJOR_VERSION=mutter_major_version
|
MUTTER_MAJOR_VERSION=mutter_major_version
|
||||||
MUTTER_MINOR_VERSION=mutter_minor_version
|
MUTTER_MINOR_VERSION=mutter_minor_version
|
||||||
@@ -45,9 +46,6 @@ AC_HEADER_STDC
|
|||||||
AC_LIBTOOL_WIN32_DLL
|
AC_LIBTOOL_WIN32_DLL
|
||||||
AM_PROG_LIBTOOL
|
AM_PROG_LIBTOOL
|
||||||
|
|
||||||
# Sets GLIB_GENMARSHAL and GLIB_MKENUMS
|
|
||||||
AM_PATH_GLIB_2_0()
|
|
||||||
|
|
||||||
#### Integer sizes
|
#### Integer sizes
|
||||||
|
|
||||||
AC_CHECK_SIZEOF(char)
|
AC_CHECK_SIZEOF(char)
|
||||||
@@ -61,23 +59,80 @@ AC_CHECK_SIZEOF(__int64)
|
|||||||
## byte order
|
## byte order
|
||||||
AC_C_BIGENDIAN
|
AC_C_BIGENDIAN
|
||||||
|
|
||||||
CANBERRA_GTK=libcanberra-gtk3
|
#### Warnings
|
||||||
CANBERRA_GTK_VERSION=0.26
|
|
||||||
|
|
||||||
CLUTTER_PACKAGE=clutter-1.0
|
changequote(,)dnl
|
||||||
|
if test "x$GCC" = "xyes"; then
|
||||||
|
case " $CFLAGS " in
|
||||||
|
*[\ \ ]-Wall[\ \ ]*) ;;
|
||||||
|
*) CFLAGS="$CFLAGS -Wall" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
MUTTER_PC_MODULES="
|
# case " $CFLAGS " in
|
||||||
gtk+-3.0 >= 3.3.7
|
# *[\ \ ]-Wshadow[\ \ ]*) ;;
|
||||||
gio-2.0 >= 2.25.10
|
# *) CFLAGS="$CFLAGS -Wshadow" ;;
|
||||||
pango >= 1.2.0
|
# esac
|
||||||
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
|
|
||||||
"
|
|
||||||
|
|
||||||
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_ARG_ENABLE(verbose-mode,
|
||||||
AC_HELP_STRING([--disable-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]),,
|
[disable mutter's startup notification support, for embedded/size-sensitive custom non-GNOME builds]),,
|
||||||
enable_startup_notification=auto)
|
enable_startup_notification=auto)
|
||||||
|
|
||||||
AC_ARG_WITH(libcanberra,
|
AC_ARG_ENABLE(compositor,
|
||||||
AC_HELP_STRING([--without-libcanberra],
|
AC_HELP_STRING([--disable-compositor],
|
||||||
[disable the use of libcanberra for playing sounds]),,
|
[disable mutter's compositing manager]),,
|
||||||
with_libcanberra=auto)
|
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_ARG_ENABLE(xsync,
|
||||||
AC_HELP_STRING([--disable-xsync],
|
AC_HELP_STRING([--disable-xsync],
|
||||||
[disable mutter's use of the XSync extension]),,
|
[disable mutter's use of the XSync extension]),,
|
||||||
enable_xsync=auto)
|
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_ARG_ENABLE(shape,
|
||||||
AC_HELP_STRING([--disable-shape],
|
AC_HELP_STRING([--disable-shape],
|
||||||
[disable mutter's use of the shaped window extension]),,
|
[disable mutter's use of the shaped window extension]),,
|
||||||
enable_shape=auto)
|
enable_shape=auto)
|
||||||
|
|
||||||
|
## try definining HAVE_BACKTRACE
|
||||||
|
AC_CHECK_HEADERS(execinfo.h, [AC_CHECK_FUNCS(backtrace)])
|
||||||
|
|
||||||
AM_GLIB_GNU_GETTEXT
|
AM_GLIB_GNU_GETTEXT
|
||||||
|
|
||||||
## here we get the flags we'll actually use
|
## here we get the flags we'll actually use
|
||||||
# GRegex requires Glib-2.14.0
|
# GOptionEntry requires glib-2.6.0
|
||||||
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.14.0)
|
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.6.0)
|
||||||
# gtk_window_set_icon_name requires gtk2+-2.6.0
|
# gtk_window_set_icon_name requires gtk2+-2.60
|
||||||
PKG_CHECK_MODULES(MUTTER_MESSAGE, gtk+-3.0)
|
PKG_CHECK_MODULES(MUTTER_MESSAGE, gtk+-2.0 >= 2.6.0)
|
||||||
PKG_CHECK_MODULES(MUTTER_WINDOW_DEMO, gtk+-3.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
|
# Unconditionally use this dir to avoid a circular dep with gnomecc
|
||||||
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
|
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
|
||||||
@@ -152,38 +231,122 @@ else
|
|||||||
echo "Building without libstartup-notification"
|
echo "Building without libstartup-notification"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
have_libcanberra=no
|
## init this, it gets set either in the compositor check below
|
||||||
AC_MSG_CHECKING([libcanberra-gtk])
|
## or the render-specific check later
|
||||||
if test x$with_libcanberra = xno ; then
|
have_xrender=no
|
||||||
AC_MSG_RESULT([disabled])
|
|
||||||
|
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
|
else
|
||||||
if $PKG_CONFIG --exists $CANBERRA_GTK '>=' $CANBERRA_GTK_VERSION; then
|
have_xcomposite=no
|
||||||
have_libcanberra=yes
|
fi
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES $CANBERRA_GTK"
|
if test x$with_clutter = xyes; then
|
||||||
AC_DEFINE([HAVE_LIBCANBERRA], 1, [Building with libcanberra for playing sounds])
|
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
|
else
|
||||||
AC_MSG_RESULT(no)
|
have_xrender=no
|
||||||
if test x$with_libcanberra = xyes ; then
|
fi
|
||||||
AC_MSG_ERROR([libcanberra forced and libcanberra-gtk was not found])
|
AC_MSG_RESULT($have_xrender)
|
||||||
fi
|
|
||||||
|
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
|
||||||
fi
|
fi
|
||||||
|
|
||||||
INTROSPECTION_VERSION=0.9.5
|
if test x$with_introspection != xno; then
|
||||||
GOBJECT_INTROSPECTION_CHECK([$INTROSPECTION_VERSION])
|
PKG_CHECK_MODULES(INTROSPECTION, gobject-introspection-1.0, have_introspection=yes, have_introspection=no)
|
||||||
|
if test x$have_introspection=xyes; then
|
||||||
if test x$found_introspection != xno; then
|
MUTTER_PC_MODULES="$MUTTER_PC_MODULES gobject-introspection-1.0"
|
||||||
AC_DEFINE(HAVE_INTROSPECTION, 1, [Define if GObject introspection is available])
|
AC_DEFINE(HAVE_INTROSPECTION, 1, [Define if GObject introspection is available])
|
||||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES gobject-introspection-1.0"
|
G_IR_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0`
|
||||||
# Since we don't make any guarantees about stability and we don't support
|
AC_SUBST(G_IR_SCANNER)
|
||||||
# parallel install, there's no real reason to change directories, filenames,
|
G_IR_COMPILER=`$PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0`
|
||||||
# etc. as we change the Mutter tarball version. Note that this must match
|
AC_SUBST(G_IR_COMPILER)
|
||||||
# api_version in src/Makefile.am
|
G_IR_GENERATE=`$PKG_CONFIG --variable=g_ir_generate gobject-introspection-1.0`
|
||||||
META_GIR=Meta_3_0_gir
|
AC_SUBST(G_IR_GENERATE)
|
||||||
# META_GIR=[Meta_]mutter_major_version[_]mutter_minor_version[_gir]
|
GIRDIR=`$PKG_CONFIG --variable=girdir gobject-introspection-1.0`
|
||||||
AC_SUBST(META_GIR)
|
AC_SUBST(GIRDIR)
|
||||||
|
TYPELIBDIR="$($PKG_CONFIG --variable=typelibdir gobject-introspection-1.0)"
|
||||||
|
AC_SUBST(TYPELIBDIR)
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
AM_CONDITIONAL(WITH_INTROSPECTION, test "$have_introspection" = "yes")
|
||||||
|
|
||||||
AC_MSG_CHECKING([Xcursor])
|
AC_MSG_CHECKING([Xcursor])
|
||||||
if $PKG_CONFIG xcursor; then
|
if $PKG_CONFIG xcursor; then
|
||||||
@@ -201,39 +364,64 @@ fi
|
|||||||
|
|
||||||
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
|
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
|
AC_PATH_XTRA
|
||||||
|
|
||||||
ALL_X_LIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
|
ALL_X_LIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
|
||||||
|
|
||||||
# Check for Xinerama extension - we only support the "XFree86" style,
|
# Check for Xinerama extension (Solaris impl or Xfree impl)
|
||||||
# and not the older Solaris-only version; recent Solaris supports the
|
|
||||||
# XFree86 style.
|
|
||||||
mutter_save_cppflags="$CPPFLAGS"
|
mutter_save_cppflags="$CPPFLAGS"
|
||||||
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
|
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
|
||||||
|
|
||||||
have_xinerama=yes
|
AC_ARG_ENABLE(xinerama,
|
||||||
AC_CHECK_LIB(Xinerama, XineramaQueryExtension,
|
AC_HELP_STRING([--disable-xinerama],
|
||||||
[AC_CHECK_HEADER(X11/extensions/Xinerama.h,
|
[disable mutter's use of the Xinerama extension]),
|
||||||
[X_EXTRA_LIBS="-lXinerama $X_EXTRA_LIBS"
|
try_xinerama=$enable_xinerama,try_xinerama=yes)
|
||||||
if test -z "`echo $ALL_X_LIBS | grep "\-lXext" 2> /dev/null`"; then
|
|
||||||
X_EXTRA_LIBS="-lXext $X_EXTRA_LIBS"
|
use_solaris_xinerama=no
|
||||||
fi],
|
use_xfree_xinerama=no
|
||||||
have_xinerama=no,
|
if test "${try_xinerama}" != no; then
|
||||||
[#include <X11/Xlib.h>])],
|
case "$host" in
|
||||||
have_xinerama=no, -lXext $ALL_X_LIBS)
|
*-*-solaris*)
|
||||||
AC_MSG_CHECKING(for Xinerama support)
|
# Check for solaris
|
||||||
AC_MSG_RESULT($have_xinerama)
|
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"
|
CPPFLAGS="$mutter_save_cppflags"
|
||||||
|
|
||||||
if test x$have_xinerama = xno; then
|
|
||||||
AC_MSG_ERROR([Xinerama extension was not found])
|
|
||||||
fi
|
|
||||||
|
|
||||||
SHAPE_LIBS=
|
SHAPE_LIBS=
|
||||||
found_shape=no
|
found_shape=no
|
||||||
AC_CHECK_LIB(Xext, XShapeQueryExtension,
|
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_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_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"
|
MUTTER_PROPS_LIBS="$MUTTER_PROPS_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
|
||||||
|
|
||||||
found_sm=no
|
found_sm=no
|
||||||
@@ -349,6 +537,18 @@ fi
|
|||||||
|
|
||||||
AC_SUBST(GDK_PIXBUF_CSOURCE)
|
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)
|
AC_PATH_PROG(ZENITY, zenity, no)
|
||||||
if test x"$ZENITY" = xno; then
|
if test x"$ZENITY" = xno; then
|
||||||
AC_MSG_ERROR([zenity not found in your path - needed for dialogs])
|
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"
|
CFLAGS="$CFLAGS -g -O"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# For fix-meta-rectangle.py
|
# Warnings are there for a reason
|
||||||
AM_PATH_PYTHON([2.5])
|
if test "x$GCC" = "xyes"; then
|
||||||
|
CFLAGS="$CFLAGS -Wall -Werror -ansi"
|
||||||
#### 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
|
|
||||||
fi
|
fi
|
||||||
changequote([,])dnl
|
|
||||||
|
# Use gnome-doc-utils:
|
||||||
|
GNOME_DOC_INIT([0.8.0])
|
||||||
|
|
||||||
AC_CONFIG_FILES([
|
AC_CONFIG_FILES([
|
||||||
Makefile
|
Makefile
|
||||||
@@ -436,15 +575,22 @@ doc/Makefile
|
|||||||
doc/man/Makefile
|
doc/man/Makefile
|
||||||
src/Makefile
|
src/Makefile
|
||||||
src/wm-tester/Makefile
|
src/wm-tester/Makefile
|
||||||
src/libmutter.pc
|
src/libmutter-private.pc
|
||||||
src/mutter-plugins.pc
|
src/mutter-plugins.pc
|
||||||
src/tools/Makefile
|
src/tools/Makefile
|
||||||
src/compositor/plugins/Makefile
|
src/compositor/mutter/plugins/Makefile
|
||||||
po/Makefile.in
|
po/Makefile.in
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_OUTPUT
|
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
|
if test x$enable_verbose_mode = xno; then
|
||||||
echo "*** WARNING WARNING WARNING WARNING WARNING"
|
echo "*** WARNING WARNING WARNING WARNING WARNING"
|
||||||
echo "*** Building without verbose mode"
|
echo "*** Building without verbose mode"
|
||||||
@@ -455,28 +601,33 @@ fi
|
|||||||
|
|
||||||
dnl ==========================================================================
|
dnl ==========================================================================
|
||||||
echo "
|
echo "
|
||||||
mutter-$VERSION
|
mutter-$VERSION:
|
||||||
|
|
||||||
prefix: ${prefix}
|
prefix: ${prefix}
|
||||||
source code location: ${srcdir}
|
source code location: ${srcdir}
|
||||||
compiler: ${CC}
|
compiler: ${CC}
|
||||||
|
|
||||||
|
GConf: ${enable_gconf}
|
||||||
|
XFree86 Xinerama: ${use_xfree_xinerama}
|
||||||
|
Solaris Xinerama: ${use_solaris_xinerama}
|
||||||
Startup notification: ${have_startup_notification}
|
Startup notification: ${have_startup_notification}
|
||||||
libcanberra: ${have_libcanberra}
|
Compositing manager: ${have_xcomposite}
|
||||||
Introspection: ${found_introspection}
|
Introspection: ${have_introspection}
|
||||||
Session management: ${found_sm}
|
Session management: ${found_sm}
|
||||||
Shape extension: ${found_shape}
|
Shape extension: ${found_shape}
|
||||||
|
Resize-and-rotate: ${found_randr}
|
||||||
Xsync: ${found_xsync}
|
Xsync: ${found_xsync}
|
||||||
|
Render: ${have_xrender}
|
||||||
Xcursor: ${have_xcursor}
|
Xcursor: ${have_xcursor}
|
||||||
|
Clutter: ${have_clutter}
|
||||||
"
|
"
|
||||||
|
|
||||||
|
|
||||||
MUTTER_MINOR_VERSION=mutter_minor_version
|
MUTTER_MINOR_VERSION=mutter_minor_version
|
||||||
if expr $MUTTER_MINOR_VERSION % 2 > /dev/null ; then
|
if test $(( $(echo $MUTTER_MINOR_VERSION) %2)) == "1"; then
|
||||||
stable_version=`expr $MUTTER_MINOR_VERSION - 1`
|
stable_version=$(( ($MUTTER_MINOR_VERSION / 2) * 2))
|
||||||
echo "This is the UNSTABLE branch of mutter"
|
echo "This is the UNSTABLE branch of mutter"
|
||||||
echo -n "Use 3.$stable_version.x for stable "
|
echo -n "Use 2.$stable_version.x for stable "
|
||||||
echo "(gnome-3-$stable_version branch in git)"
|
echo "(gnome-2-$stable_version branch in Subversion)"
|
||||||
else
|
else
|
||||||
echo "This is the stable branch of mutter"
|
echo "This is the stable branch of mutter"
|
||||||
fi
|
fi
|
||||||
|
@@ -31,7 +31,8 @@ workspaces. In these cases, there needs to be a rule consistent with
|
|||||||
the above about the new window to choose.
|
the above about the new window to choose.
|
||||||
|
|
||||||
Focus method Behavior
|
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
|
sloppy Focus the window containing the pointer if there is such
|
||||||
a window, otherwise focus the most recently used window.
|
a window, otherwise focus the most recently used window.
|
||||||
mouse Focus the non-DESKTOP window containing the pointer if
|
mouse Focus the non-DESKTOP window containing the pointer if
|
||||||
|
@@ -46,13 +46,13 @@ because the original program does not have a manual page.
|
|||||||
Restart \fBmutter\fP(1) which is running.
|
Restart \fBmutter\fP(1) which is running.
|
||||||
.TP
|
.TP
|
||||||
.B reload-theme
|
.B reload-theme
|
||||||
Reload a theme which is specified on gsettings database.
|
Reload a theme which is specified on gconf database.
|
||||||
.TP
|
.TP
|
||||||
.B enable-keybindings
|
.B enable-keybindings
|
||||||
Enable all of keybindings which is specified on gsettings database.
|
Enable all of keybindings which is specified on gconf database.
|
||||||
.TP
|
.TP
|
||||||
.B disable-keybindings
|
.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
|
.SH SEE ALSO
|
||||||
.BR mutter (1)
|
.BR mutter (1)
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
|
@@ -51,7 +51,7 @@ Print the version number.
|
|||||||
.B \-?, \-\-help
|
.B \-?, \-\-help
|
||||||
Show summary of options.
|
Show summary of options.
|
||||||
.SH CONFIGURATION
|
.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
|
.SH SEE ALSO
|
||||||
.BR mutter-message (1)
|
.BR mutter-message (1)
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
|
@@ -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
|
Version 1: THEMEDIR/metacity-1/metacity-theme-1.xml
|
||||||
(original metacity format)
|
(original metacity format)
|
||||||
Version 2: THEMEDIR/metacity-1/metacity-theme-2.xml
|
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.
|
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
|
want to read the document in reverse order, since the base features
|
||||||
are discussed under version 1.
|
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 < and >). 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
|
New Features in Theme Format Version 2
|
||||||
======================================
|
======================================
|
||||||
|
|
||||||
|
17
mutter.doap
17
mutter.doap
@@ -6,16 +6,6 @@
|
|||||||
|
|
||||||
<name xml:lang="en">mutter</name>
|
<name xml:lang="en">mutter</name>
|
||||||
<shortdesc xml:lang="en">Window and compositing manager based on Clutter</shortdesc>
|
<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/" />
|
<homepage rdf:resource="http://www.gnome.org/" />
|
||||||
-->
|
-->
|
||||||
@@ -39,11 +29,4 @@ environment.</description>
|
|||||||
<gnome:userid>otaylor</gnome:userid>
|
<gnome:userid>otaylor</gnome:userid>
|
||||||
</foaf:Person>
|
</foaf:Person>
|
||||||
</maintainer>
|
</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>
|
</Project>
|
||||||
|
@@ -10,7 +10,6 @@ be@latin
|
|||||||
bg
|
bg
|
||||||
bn
|
bn
|
||||||
bn_IN
|
bn_IN
|
||||||
br
|
|
||||||
bs
|
bs
|
||||||
ca
|
ca
|
||||||
ca@valencia
|
ca@valencia
|
||||||
@@ -22,7 +21,6 @@ dz
|
|||||||
el
|
el
|
||||||
en_CA
|
en_CA
|
||||||
en_GB
|
en_GB
|
||||||
eo
|
|
||||||
es
|
es
|
||||||
et
|
et
|
||||||
eu
|
eu
|
||||||
@@ -58,7 +56,6 @@ mn
|
|||||||
mr
|
mr
|
||||||
ms
|
ms
|
||||||
nb
|
nb
|
||||||
nds
|
|
||||||
ne
|
ne
|
||||||
nl
|
nl
|
||||||
nn
|
nn
|
||||||
@@ -83,7 +80,6 @@ te
|
|||||||
th
|
th
|
||||||
tk
|
tk
|
||||||
tr
|
tr
|
||||||
ug
|
|
||||||
uk
|
uk
|
||||||
vi
|
vi
|
||||||
wa
|
wa
|
||||||
|
@@ -1,15 +1,11 @@
|
|||||||
# List of source files containing translatable strings.
|
# List of source files containing translatable strings.
|
||||||
# Please keep this file sorted alphabetically.
|
# Please keep this file sorted alphabetically.
|
||||||
src/50-mutter-windows.xml.in
|
|
||||||
src/compositor/compositor.c
|
|
||||||
src/core/bell.c
|
|
||||||
src/core/core.c
|
src/core/core.c
|
||||||
src/core/delete.c
|
src/core/delete.c
|
||||||
src/core/display.c
|
src/core/display.c
|
||||||
src/core/errors.c
|
src/core/errors.c
|
||||||
src/core/keybindings.c
|
src/core/keybindings.c
|
||||||
src/core/main.c
|
src/core/main.c
|
||||||
src/core/mutter.c
|
|
||||||
src/core/prefs.c
|
src/core/prefs.c
|
||||||
src/core/screen.c
|
src/core/screen.c
|
||||||
src/core/session.c
|
src/core/session.c
|
||||||
@@ -17,9 +13,10 @@ src/core/util.c
|
|||||||
src/core/window.c
|
src/core/window.c
|
||||||
src/core/window-props.c
|
src/core/window-props.c
|
||||||
src/core/xprops.c
|
src/core/xprops.c
|
||||||
|
src/include/all-keybindings.h
|
||||||
src/mutter.desktop.in
|
src/mutter.desktop.in
|
||||||
src/mutter-wm.desktop.in
|
src/mutter-wm.desktop.in
|
||||||
src/org.gnome.mutter.gschema.xml.in
|
src/mutter.schemas.in
|
||||||
src/tools/mutter-message.c
|
src/tools/mutter-message.c
|
||||||
src/ui/frames.c
|
src/ui/frames.c
|
||||||
src/ui/menu.c
|
src/ui/menu.c
|
||||||
|
5768
po/ca@valencia.po
5768
po/ca@valencia.po
File diff suppressed because it is too large
Load Diff
2776
po/en_GB.po
2776
po/en_GB.po
File diff suppressed because it is too large
Load Diff
2809
po/pt_BR.po
2809
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
3550
po/sr@latin.po
3550
po/sr@latin.po
File diff suppressed because it is too large
Load Diff
2738
po/zh_CN.po
2738
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
1730
po/zh_HK.po
1730
po/zh_HK.po
File diff suppressed because it is too large
Load Diff
1834
po/zh_TW.po
1834
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@@ -1,15 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<KeyListEntries schema="org.gnome.mutter.keybindings"
|
|
||||||
group="system"
|
|
||||||
_name="Windows"
|
|
||||||
wm_name="Mutter"
|
|
||||||
package="mutter">
|
|
||||||
|
|
||||||
<KeyListEntry name="toggle-tiled-left"
|
|
||||||
_description="View split on left"/>
|
|
||||||
|
|
||||||
<KeyListEntry name="toggle-tiled-right"
|
|
||||||
_description="View split on right"/>
|
|
||||||
|
|
||||||
</KeyListEntries>
|
|
||||||
|
|
344
src/Makefile.am
344
src/Makefile.am
@@ -1,114 +1,71 @@
|
|||||||
# Flag build for parallelism; see https://savannah.gnu.org/patch/?6905
|
lib_LTLIBRARIES = libmutter-private.la
|
||||||
.AUTOPARALLEL:
|
|
||||||
|
|
||||||
lib_LTLIBRARIES = libmutter.la
|
SUBDIRS=wm-tester tools
|
||||||
|
|
||||||
SUBDIRS=wm-tester tools compositor/plugins
|
if WITH_CLUTTER
|
||||||
|
SUBDIRS += compositor/mutter/plugins
|
||||||
|
endif
|
||||||
|
|
||||||
INCLUDES= \
|
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_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)\"
|
|
||||||
|
|
||||||
mutter_built_sources = \
|
mutter_SOURCES= \
|
||||||
mutter-enum-types.h \
|
|
||||||
mutter-enum-types.c
|
|
||||||
|
|
||||||
libmutter_la_SOURCES = \
|
|
||||||
core/async-getprop.c \
|
core/async-getprop.c \
|
||||||
core/async-getprop.h \
|
core/async-getprop.h \
|
||||||
|
core/alttabhandler.c \
|
||||||
|
include/alttabhandler.h \
|
||||||
|
core/alttabhandlerdefault.c \
|
||||||
|
include/alttabhandlerdefault.h \
|
||||||
core/bell.c \
|
core/bell.c \
|
||||||
core/bell.h \
|
core/bell.h \
|
||||||
core/boxes.c \
|
core/boxes.c \
|
||||||
core/boxes-private.h \
|
include/boxes.h \
|
||||||
meta/boxes.h \
|
|
||||||
compositor/cogl-utils.c \
|
|
||||||
compositor/cogl-utils.h \
|
|
||||||
compositor/compositor.c \
|
compositor/compositor.c \
|
||||||
compositor/compositor-private.h \
|
compositor/compositor-private.h \
|
||||||
compositor/meta-background-actor.c \
|
compositor/compositor-xrender.c \
|
||||||
compositor/meta-background-actor-private.h \
|
compositor/compositor-xrender.h \
|
||||||
compositor/meta-module.c \
|
include/compositor.h \
|
||||||
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 \
|
|
||||||
core/constraints.c \
|
core/constraints.c \
|
||||||
core/constraints.h \
|
core/constraints.h \
|
||||||
core/core.c \
|
core/core.c \
|
||||||
core/delete.c \
|
core/delete.c \
|
||||||
core/display.c \
|
core/display.c \
|
||||||
core/display-private.h \
|
core/display-private.h \
|
||||||
meta/display.h \
|
include/display.h \
|
||||||
ui/draw-workspace.c \
|
ui/draw-workspace.c \
|
||||||
ui/draw-workspace.h \
|
ui/draw-workspace.h \
|
||||||
core/edge-resistance.c \
|
core/edge-resistance.c \
|
||||||
core/edge-resistance.h \
|
core/edge-resistance.h \
|
||||||
|
core/effects.c \
|
||||||
|
core/effects.h \
|
||||||
core/errors.c \
|
core/errors.c \
|
||||||
meta/errors.h \
|
include/errors.h \
|
||||||
core/eventqueue.c \
|
core/eventqueue.c \
|
||||||
core/eventqueue.h \
|
core/eventqueue.h \
|
||||||
core/frame.c \
|
core/frame.c \
|
||||||
core/frame.h \
|
core/frame-private.h \
|
||||||
|
include/frame.h \
|
||||||
ui/gradient.c \
|
ui/gradient.c \
|
||||||
meta/gradient.h \
|
ui/gradient.h \
|
||||||
core/group-private.h \
|
core/group-private.h \
|
||||||
core/group-props.c \
|
core/group-props.c \
|
||||||
core/group-props.h \
|
core/group-props.h \
|
||||||
core/group.c \
|
core/group.c \
|
||||||
meta/group.h \
|
include/group.h \
|
||||||
core/iconcache.c \
|
core/iconcache.c \
|
||||||
core/iconcache.h \
|
core/iconcache.h \
|
||||||
core/keybindings.c \
|
core/keybindings.c \
|
||||||
core/keybindings-private.h \
|
core/keybindings-private.h \
|
||||||
core/main.c \
|
core/main.c \
|
||||||
core/mutter-Xatomtype.h \
|
include/main.h \
|
||||||
|
core/mutter-Xatomtype.h \
|
||||||
core/place.c \
|
core/place.c \
|
||||||
core/place.h \
|
core/place.h \
|
||||||
core/prefs.c \
|
core/prefs.c \
|
||||||
meta/prefs.h \
|
include/prefs.h \
|
||||||
core/screen.c \
|
core/screen.c \
|
||||||
core/screen-private.h \
|
core/screen-private.h \
|
||||||
meta/screen.h \
|
include/screen.h \
|
||||||
meta/types.h \
|
include/types.h \
|
||||||
core/session.c \
|
core/session.c \
|
||||||
core/session.h \
|
core/session.h \
|
||||||
core/stack.c \
|
core/stack.c \
|
||||||
@@ -116,20 +73,22 @@ libmutter_la_SOURCES = \
|
|||||||
core/stack-tracker.c \
|
core/stack-tracker.c \
|
||||||
core/stack-tracker.h \
|
core/stack-tracker.h \
|
||||||
core/util.c \
|
core/util.c \
|
||||||
meta/util.h \
|
include/util.h \
|
||||||
core/window-props.c \
|
core/window-props.c \
|
||||||
core/window-props.h \
|
core/window-props.h \
|
||||||
core/window.c \
|
core/window.c \
|
||||||
core/window-private.h \
|
core/window-private.h \
|
||||||
meta/window.h \
|
include/window.h \
|
||||||
core/workspace.c \
|
core/workspace.c \
|
||||||
core/workspace-private.h \
|
core/workspace-private.h \
|
||||||
core/xprops.c \
|
core/xprops.c \
|
||||||
core/xprops.h \
|
include/xprops.h \
|
||||||
meta/common.h \
|
include/common.h \
|
||||||
core/core.h \
|
include/core.h \
|
||||||
ui/ui.h \
|
include/ui.h \
|
||||||
inlinepixbufs.h \
|
inlinepixbufs.h \
|
||||||
|
ui/fixedtip.c \
|
||||||
|
ui/fixedtip.h \
|
||||||
ui/frames.c \
|
ui/frames.c \
|
||||||
ui/frames.h \
|
ui/frames.h \
|
||||||
ui/menu.c \
|
ui/menu.c \
|
||||||
@@ -137,56 +96,81 @@ libmutter_la_SOURCES = \
|
|||||||
ui/metaaccellabel.c \
|
ui/metaaccellabel.c \
|
||||||
ui/metaaccellabel.h \
|
ui/metaaccellabel.h \
|
||||||
ui/resizepopup.c \
|
ui/resizepopup.c \
|
||||||
ui/resizepopup.h \
|
include/resizepopup.h \
|
||||||
ui/tabpopup.c \
|
ui/tabpopup.c \
|
||||||
ui/tabpopup.h \
|
include/tabpopup.h \
|
||||||
ui/tile-preview.c \
|
|
||||||
ui/tile-preview.h \
|
|
||||||
ui/theme-parser.c \
|
ui/theme-parser.c \
|
||||||
|
ui/theme-parser.h \
|
||||||
ui/theme.c \
|
ui/theme.c \
|
||||||
meta/theme.h \
|
ui/theme.h \
|
||||||
ui/theme-private.h \
|
ui/themewidget.c \
|
||||||
|
ui/themewidget.h \
|
||||||
ui/ui.c \
|
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 \
|
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_private_la_LDFLAGS = -no-undefined
|
||||||
libmutter_la_LIBADD = $(MUTTER_LIBS)
|
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 = \
|
libmutterinclude_base_headers = \
|
||||||
meta/boxes.h \
|
include/alttabhandler.h \
|
||||||
meta/common.h \
|
include/boxes.h \
|
||||||
meta/compositor-mutter.h \
|
ui/gradient.h \
|
||||||
meta/compositor.h \
|
include/util.h \
|
||||||
meta/display.h \
|
include/common.h \
|
||||||
meta/errors.h \
|
ui/preview-widget.h \
|
||||||
meta/gradient.h \
|
ui/theme-parser.h \
|
||||||
meta/group.h \
|
ui/theme.h \
|
||||||
meta/keybindings.h \
|
include/prefs.h \
|
||||||
meta/main.h \
|
include/window.h \
|
||||||
meta/meta-background-actor.h \
|
include/workspace.h \
|
||||||
meta/meta-plugin.h \
|
include/compositor.h \
|
||||||
meta/meta-shaped-texture.h \
|
include/compositor-mutter.h \
|
||||||
meta/meta-shadow-factory.h \
|
include/types.h \
|
||||||
meta/meta-window-actor.h \
|
include/screen.h \
|
||||||
meta/prefs.h \
|
include/display.h \
|
||||||
meta/screen.h \
|
include/group.h \
|
||||||
meta/theme.h \
|
include/keybindings.h \
|
||||||
meta/types.h \
|
include/mutter-plugin.h
|
||||||
meta/util.h \
|
|
||||||
meta/window.h \
|
|
||||||
meta/workspace.h
|
|
||||||
|
|
||||||
# Excluded from scanning for introspection but installed
|
# Excluded from scanning for introspection but installed
|
||||||
# atomnames.h: macros cause problems for scanning process
|
|
||||||
libmutterinclude_extra_headers = \
|
libmutterinclude_extra_headers = \
|
||||||
meta/preview-widget.h \
|
include/atomnames.h
|
||||||
meta/atomnames.h
|
|
||||||
|
|
||||||
libmutterincludedir = $(includedir)/mutter/meta
|
|
||||||
|
|
||||||
libmutterinclude_HEADERS = \
|
libmutterinclude_HEADERS = \
|
||||||
$(libmutterinclude_base_headers) \
|
$(libmutterinclude_base_headers) \
|
||||||
@@ -197,18 +181,9 @@ mutter_theme_viewer_SOURCES= \
|
|||||||
|
|
||||||
bin_PROGRAMS=mutter mutter-theme-viewer
|
bin_PROGRAMS=mutter mutter-theme-viewer
|
||||||
|
|
||||||
mutter_SOURCES = core/mutter.c
|
api_version = $(MUTTER_MAJOR_VERSION).$(MUTTER_MINOR_VERSION)
|
||||||
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
|
|
||||||
|
|
||||||
|
if WITH_INTROSPECTION
|
||||||
# These files are in package-private directories, even though they may be used
|
# 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
|
# by plugins. If you're writing a plugin, use g-ir-compiler --add-include-path
|
||||||
# and g-ir-compiler --includedir.
|
# and g-ir-compiler --includedir.
|
||||||
@@ -218,32 +193,44 @@ gir_DATA = Meta-$(api_version).gir
|
|||||||
typelibdir = $(pkglibdir)
|
typelibdir = $(pkglibdir)
|
||||||
typelib_DATA = Meta-$(api_version).typelib
|
typelib_DATA = Meta-$(api_version).typelib
|
||||||
|
|
||||||
INTROSPECTION_GIRS = Meta-$(api_version).gir
|
# 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: libmutter.la
|
Meta-$(api_version).gir: $(G_IR_SCANNER) mutter $(libmutterinclude_HEADERS) $(mutter_SOURCES)
|
||||||
@META_GIR@_INCLUDES = GObject-2.0 GDesktopEnums-3.0 Gdk-3.0 Gtk-3.0 Clutter-1.0 xlib-2.0 xfixes-4.0
|
$(G_IR_SCANNER) \
|
||||||
@META_GIR@_EXPORT_PACKAGES = libmutter
|
--namespace=Meta \
|
||||||
@META_GIR@_CFLAGS = $(INCLUDES)
|
--nsversion=$(api_version) \
|
||||||
@META_GIR@_LIBS = libmutter.la
|
--include=GObject-2.0 \
|
||||||
@META_GIR@_FILES = \
|
--include=Gdk-2.0 \
|
||||||
mutter-enum-types.h \
|
--include=Gtk-2.0 \
|
||||||
$(libmutterinclude_base_headers) \
|
--include=Clutter-0.9 \
|
||||||
$(filter %.c,$(libmutter_la_SOURCES))
|
--pkg=clutter-0.9 \
|
||||||
@META_GIR@_SCANNERFLAGS = --warn-all --warn-error
|
--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
|
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
|
mutter_theme_viewer_LDADD= @MUTTER_LIBS@ libmutter-private.la
|
||||||
testgradient_SOURCES = ui/testgradient.c
|
|
||||||
testasyncgetprop_SOURCES = core/testasyncgetprop.c
|
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
|
noinst_PROGRAMS=testboxes testgradient testasyncgetprop
|
||||||
|
|
||||||
testboxes_LDADD = $(MUTTER_LIBS) libmutter.la
|
testboxes_LDADD= @MUTTER_LIBS@ libmutter-private.la
|
||||||
testgradient_LDADD = $(MUTTER_LIBS) libmutter.la
|
testgradient_LDADD= @MUTTER_LIBS@ libmutter-private.la
|
||||||
testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter.la
|
testasyncgetprop_LDADD= @MUTTER_LIBS@ libmutter-private.la
|
||||||
|
|
||||||
@INTLTOOL_DESKTOP_RULE@
|
@INTLTOOL_DESKTOP_RULE@
|
||||||
|
|
||||||
@@ -257,17 +244,20 @@ wmproperties_in_files=mutter-wm.desktop.in
|
|||||||
wmproperties_files=$(wmproperties_in_files:.desktop.in=.desktop)
|
wmproperties_files=$(wmproperties_in_files:.desktop.in=.desktop)
|
||||||
wmproperties_DATA = $(wmproperties_files)
|
wmproperties_DATA = $(wmproperties_files)
|
||||||
|
|
||||||
xmldir = @GNOME_KEYBINDINGS_KEYSDIR@
|
schemadir = @GCONF_SCHEMA_FILE_DIR@
|
||||||
xml_in_files = \
|
schema_in_files = mutter.schemas.in
|
||||||
50-mutter-windows.xml.in
|
schema_DATA = $(schema_in_files:.schemas.in=.schemas)
|
||||||
xml_DATA = $(xml_in_files:.xml.in=.xml)
|
|
||||||
|
|
||||||
gsettings_SCHEMAS = org.gnome.mutter.gschema.xml
|
|
||||||
@INTLTOOL_XML_NOMERGE_RULE@
|
@INTLTOOL_XML_NOMERGE_RULE@
|
||||||
@GSETTINGS_RULES@
|
|
||||||
|
|
||||||
convertdir = $(datadir)/GConf/gsettings
|
@INTLTOOL_SCHEMAS_RULE@
|
||||||
convert_DATA = mutter-schemas.convert
|
|
||||||
|
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
|
IMAGES=stock_maximize.png stock_minimize.png stock_delete.png
|
||||||
VARIABLES=stock_maximize_data $(srcdir)/stock_maximize.png \
|
VARIABLES=stock_maximize_data $(srcdir)/stock_maximize.png \
|
||||||
@@ -275,55 +265,21 @@ VARIABLES=stock_maximize_data $(srcdir)/stock_maximize.png \
|
|||||||
stock_delete_data $(srcdir)/stock_delete.png
|
stock_delete_data $(srcdir)/stock_delete.png
|
||||||
|
|
||||||
BUILT_SOURCES = inlinepixbufs.h
|
BUILT_SOURCES = inlinepixbufs.h
|
||||||
CLEANFILES = \
|
CLEANFILES = inlinepixbufs.h mutter.desktop mutter-wm.desktop mutter.schemas
|
||||||
inlinepixbufs.h \
|
|
||||||
mutter.desktop \
|
|
||||||
mutter-wm.desktop \
|
|
||||||
org.gnome.mutter.gschema.xml \
|
|
||||||
$(xml_DATA) \
|
|
||||||
$(mutter_built_sources) \
|
|
||||||
$(typelib_DATA) \
|
|
||||||
$(gir_DATA)
|
|
||||||
|
|
||||||
inlinepixbufs.h: $(IMAGES)
|
inlinepixbufs.h: $(IMAGES)
|
||||||
$(GDK_PIXBUF_CSOURCE) --raw --build-list $(VARIABLES) >$(srcdir)/inlinepixbufs.h
|
$(GDK_PIXBUF_CSOURCE) --raw --build-list $(VARIABLES) >$(srcdir)/inlinepixbufs.h
|
||||||
|
|
||||||
pkgconfigdir = $(libdir)/pkgconfig
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
|
|
||||||
pkgconfig_DATA = libmutter.pc mutter-plugins.pc
|
pkgconfig_DATA = libmutter-private.pc mutter-plugins.pc
|
||||||
|
|
||||||
EXTRA_DIST=$(desktopfiles_files) \
|
EXTRA_DIST=$(desktopfiles_files) \
|
||||||
$(wmproperties_files) \
|
$(wmproperties_files) \
|
||||||
$(IMAGES) \
|
$(IMAGES) $(schema_DATA) \
|
||||||
$(desktopfiles_in_files) \
|
$(desktopfiles_in_files) \
|
||||||
$(wmproperties_in_files) \
|
$(wmproperties_in_files) \
|
||||||
$(xml_in_files) \
|
$(schema_in_files) \
|
||||||
org.gnome.mutter.gschema.xml.in \
|
libmutter-private.pc.in \
|
||||||
mutter-schemas.convert \
|
mutter-plugins.pc.in
|
||||||
libmutter.pc.in \
|
|
||||||
mutter-plugins.pc.in \
|
|
||||||
mutter-enum-types.h.in \
|
|
||||||
mutter-enum-types.c.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
|
|
||||||
|
@@ -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;
|
|
||||||
}
|
|
@@ -1,71 +1,90 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
/* -*- 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
|
#ifndef META_COMPOSITOR_PRIVATE_H
|
||||||
#define META_COMPOSITOR_PRIVATE_H
|
#define META_COMPOSITOR_PRIVATE_H
|
||||||
|
|
||||||
#include <X11/extensions/Xfixes.h>
|
#include "compositor.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;
|
|
||||||
|
|
||||||
struct _MetaCompositor
|
struct _MetaCompositor
|
||||||
{
|
{
|
||||||
MetaDisplay *display;
|
void (* destroy) (MetaCompositor *compositor);
|
||||||
|
|
||||||
Atom atom_x_root_pixmap;
|
void (*manage_screen) (MetaCompositor *compositor,
|
||||||
Atom atom_x_set_root;
|
MetaScreen *screen);
|
||||||
Atom atom_net_wm_window_opacity;
|
void (*unmanage_screen) (MetaCompositor *compositor,
|
||||||
guint repaint_func_id;
|
MetaScreen *screen);
|
||||||
|
void (*add_window) (MetaCompositor *compositor,
|
||||||
ClutterActor *shadow_src;
|
MetaWindow *window);
|
||||||
|
void (*remove_window) (MetaCompositor *compositor,
|
||||||
MetaPlugin *modal_plugin;
|
MetaWindow *window);
|
||||||
|
void (*set_updates) (MetaCompositor *compositor,
|
||||||
gboolean show_redraw : 1;
|
MetaWindow *window,
|
||||||
gboolean debug : 1;
|
gboolean update);
|
||||||
gboolean no_mipmaps : 1;
|
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
|
#endif
|
||||||
{
|
|
||||||
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 */
|
|
||||||
|
3067
src/compositor/compositor-xrender.c
Normal file
3067
src/compositor/compositor-xrender.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,10 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||||
|
|
||||||
/* Meta tile preview */
|
/*
|
||||||
|
* Copyright (C) 2007 Iain Holmes
|
||||||
/*
|
* Based on xcompmgr - (c) 2003 Keith Packard
|
||||||
* Copyright (C) 2010 Florian Müllner
|
* xfwm4 - (c) 2005-2007 Olivier Fourdan
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License as
|
* modify it under the terms of the GNU General Public License as
|
||||||
* published by the Free Software Foundation; either version 2 of the
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
@@ -14,25 +14,18 @@
|
|||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* General Public License for more details.
|
* General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
* 02111-1307, USA.
|
* 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);
|
MetaCompositor *meta_compositor_xrender_new (MetaDisplay *display);
|
||||||
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);
|
|
||||||
|
|
||||||
#endif /* META_TILE_PREVIEW_H */
|
#endif
|
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
|
@@ -1,627 +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;
|
|
||||||
CoglHandle texture;
|
|
||||||
CoglMaterialWrapMode wrap_mode;
|
|
||||||
guint have_pixmap : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _MetaBackgroundActorPrivate
|
|
||||||
{
|
|
||||||
MetaScreenBackground *background;
|
|
||||||
CoglHandle material;
|
|
||||||
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_material_set_layer_wrap_mode (priv->material, 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_material_set_layer (priv->material, 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 material 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->material != COGL_INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
cogl_handle_unref (priv->material);
|
|
||||||
priv->material = COGL_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
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_material_set_color4ub (priv->material,
|
|
||||||
color_component,
|
|
||||||
color_component,
|
|
||||||
color_component,
|
|
||||||
opacity);
|
|
||||||
|
|
||||||
cogl_set_source (priv->material);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
priv->material = 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);
|
|
||||||
}
|
|
@@ -1,312 +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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 && klass->xevent_filter (plugin, xev))
|
|
||||||
return TRUE;
|
|
||||||
else
|
|
||||||
return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE;
|
|
||||||
}
|
|
@@ -1,73 +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_xevent_filter (MetaPluginManager *mgr,
|
|
||||||
XEvent *xev);
|
|
||||||
|
|
||||||
#endif
|
|
@@ -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;
|
|
||||||
}
|
|
@@ -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
@@ -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;
|
|
||||||
}
|
|
@@ -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;
|
|
||||||
}
|
|
@@ -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__ */
|
|
@@ -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];
|
|
||||||
}
|
|
@@ -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__ */
|
|
@@ -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
@@ -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);
|
|
||||||
}
|
|
@@ -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 */
|
|
@@ -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;
|
|
||||||
}
|
|
||||||
|
|
@@ -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 __*/
|
|
||||||
|
|
2975
src/compositor/mutter/compositor-mutter.c
Normal file
2975
src/compositor/mutter/compositor-mutter.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -21,8 +21,8 @@
|
|||||||
* 02111-1307, USA.
|
* 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <meta/meta-plugin.h>
|
#include "mutter-plugin.h"
|
||||||
#include "meta-module.h"
|
#include "mutter-module.h"
|
||||||
|
|
||||||
#include <gmodule.h>
|
#include <gmodule.h>
|
||||||
|
|
||||||
@@ -32,23 +32,23 @@ enum
|
|||||||
PROP_PATH,
|
PROP_PATH,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MetaModulePrivate
|
struct _MutterModulePrivate
|
||||||
{
|
{
|
||||||
GModule *lib;
|
GModule *lib;
|
||||||
gchar *path;
|
gchar *path;
|
||||||
GType plugin_type;
|
GType plugin_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define META_MODULE_GET_PRIVATE(obj) \
|
#define MUTTER_MODULE_GET_PRIVATE(obj) \
|
||||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), META_TYPE_MODULE, MetaModulePrivate))
|
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), MUTTER_TYPE_MODULE, MutterModulePrivate))
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaModule, meta_module, G_TYPE_TYPE_MODULE);
|
G_DEFINE_TYPE (MutterModule, mutter_module, G_TYPE_TYPE_MODULE);
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
meta_module_load (GTypeModule *gmodule)
|
mutter_module_load (GTypeModule *gmodule)
|
||||||
{
|
{
|
||||||
MetaModulePrivate *priv = META_MODULE (gmodule)->priv;
|
MutterModulePrivate *priv = MUTTER_MODULE (gmodule)->priv;
|
||||||
MetaPluginVersion *info = NULL;
|
MutterPluginVersion *info = NULL;
|
||||||
GType (*register_type) (GTypeModule *) = NULL;
|
GType (*register_type) (GTypeModule *) = NULL;
|
||||||
|
|
||||||
if (priv->lib && priv->plugin_type)
|
if (priv->lib && priv->plugin_type)
|
||||||
@@ -64,9 +64,9 @@ meta_module_load (GTypeModule *gmodule)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_module_symbol (priv->lib, "meta_plugin_version",
|
if (g_module_symbol (priv->lib, "mutter_plugin_version",
|
||||||
(gpointer *)(void *)&info) &&
|
(gpointer *)(void *)&info) &&
|
||||||
g_module_symbol (priv->lib, "meta_plugin_register_type",
|
g_module_symbol (priv->lib, "mutter_plugin_register_type",
|
||||||
(gpointer *)(void *)®ister_type) &&
|
(gpointer *)(void *)®ister_type) &&
|
||||||
info && register_type)
|
info && register_type)
|
||||||
{
|
{
|
||||||
@@ -97,9 +97,9 @@ meta_module_load (GTypeModule *gmodule)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_module_unload (GTypeModule *gmodule)
|
mutter_module_unload (GTypeModule *gmodule)
|
||||||
{
|
{
|
||||||
MetaModulePrivate *priv = META_MODULE (gmodule)->priv;
|
MutterModulePrivate *priv = MUTTER_MODULE (gmodule)->priv;
|
||||||
|
|
||||||
g_module_close (priv->lib);
|
g_module_close (priv->lib);
|
||||||
|
|
||||||
@@ -108,29 +108,29 @@ meta_module_unload (GTypeModule *gmodule)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_module_dispose (GObject *object)
|
mutter_module_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
G_OBJECT_CLASS (meta_module_parent_class)->dispose (object);
|
G_OBJECT_CLASS (mutter_module_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_module_finalize (GObject *object)
|
mutter_module_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
MetaModulePrivate *priv = META_MODULE (object)->priv;
|
MutterModulePrivate *priv = MUTTER_MODULE (object)->priv;
|
||||||
|
|
||||||
g_free (priv->path);
|
g_free (priv->path);
|
||||||
priv->path = NULL;
|
priv->path = NULL;
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_module_parent_class)->finalize (object);
|
G_OBJECT_CLASS (mutter_module_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_module_set_property (GObject *object,
|
mutter_module_set_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
const GValue *value,
|
const GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
MetaModulePrivate *priv = META_MODULE (object)->priv;
|
MutterModulePrivate *priv = MUTTER_MODULE (object)->priv;
|
||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
@@ -145,12 +145,12 @@ meta_module_set_property (GObject *object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_module_get_property (GObject *object,
|
mutter_module_get_property (GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
GValue *value,
|
GValue *value,
|
||||||
GParamSpec *pspec)
|
GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
MetaModulePrivate *priv = META_MODULE (object)->priv;
|
MutterModulePrivate *priv = MUTTER_MODULE (object)->priv;
|
||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
@@ -164,18 +164,18 @@ meta_module_get_property (GObject *object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_module_class_init (MetaModuleClass *klass)
|
mutter_module_class_init (MutterModuleClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
GTypeModuleClass *gmodule_class = G_TYPE_MODULE_CLASS (klass);
|
GTypeModuleClass *gmodule_class = G_TYPE_MODULE_CLASS (klass);
|
||||||
|
|
||||||
gobject_class->finalize = meta_module_finalize;
|
gobject_class->finalize = mutter_module_finalize;
|
||||||
gobject_class->dispose = meta_module_dispose;
|
gobject_class->dispose = mutter_module_dispose;
|
||||||
gobject_class->set_property = meta_module_set_property;
|
gobject_class->set_property = mutter_module_set_property;
|
||||||
gobject_class->get_property = meta_module_get_property;
|
gobject_class->get_property = mutter_module_get_property;
|
||||||
|
|
||||||
gmodule_class->load = meta_module_load;
|
gmodule_class->load = mutter_module_load;
|
||||||
gmodule_class->unload = meta_module_unload;
|
gmodule_class->unload = mutter_module_unload;
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class,
|
g_object_class_install_property (gobject_class,
|
||||||
PROP_PATH,
|
PROP_PATH,
|
||||||
@@ -186,22 +186,22 @@ meta_module_class_init (MetaModuleClass *klass)
|
|||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
G_PARAM_CONSTRUCT_ONLY));
|
G_PARAM_CONSTRUCT_ONLY));
|
||||||
|
|
||||||
g_type_class_add_private (gobject_class, sizeof (MetaModulePrivate));
|
g_type_class_add_private (gobject_class, sizeof (MutterModulePrivate));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_module_init (MetaModule *self)
|
mutter_module_init (MutterModule *self)
|
||||||
{
|
{
|
||||||
MetaModulePrivate *priv;
|
MutterModulePrivate *priv;
|
||||||
|
|
||||||
self->priv = priv = META_MODULE_GET_PRIVATE (self);
|
self->priv = priv = MUTTER_MODULE_GET_PRIVATE (self);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GType
|
GType
|
||||||
meta_module_get_plugin_type (MetaModule *module)
|
mutter_module_get_plugin_type (MutterModule *module)
|
||||||
{
|
{
|
||||||
MetaModulePrivate *priv = META_MODULE (module)->priv;
|
MutterModulePrivate *priv = MUTTER_MODULE (module)->priv;
|
||||||
|
|
||||||
return priv->plugin_type;
|
return priv->plugin_type;
|
||||||
}
|
}
|
@@ -21,37 +21,37 @@
|
|||||||
* 02111-1307, USA.
|
* 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef META_MODULE_H_
|
#ifndef MUTTER_MODULE_H_
|
||||||
#define META_MODULE_H_
|
#define MUTTER_MODULE_H_
|
||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
|
||||||
#define META_TYPE_MODULE (meta_module_get_type ())
|
#define MUTTER_TYPE_MODULE (mutter_module_get_type ())
|
||||||
#define META_MODULE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MODULE, MetaModule))
|
#define MUTTER_MODULE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MUTTER_TYPE_MODULE, MutterModule))
|
||||||
#define META_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_MODULE, MetaModuleClass))
|
#define MUTTER_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MUTTER_TYPE_MODULE, MutterModuleClass))
|
||||||
#define META_IS_MODULE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_MODULE_TYPE))
|
#define MUTTER_IS_MODULE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MUTTER_MODULE_TYPE))
|
||||||
#define META_IS_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_MODULE))
|
#define MUTTER_IS_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MUTTER_TYPE_MODULE))
|
||||||
#define META_MODULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_MODULE, MetaModuleClass))
|
#define MUTTER_MODULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MUTTER_TYPE_MODULE, MutterModuleClass))
|
||||||
|
|
||||||
typedef struct _MetaModule MetaModule;
|
typedef struct _MutterModule MutterModule;
|
||||||
typedef struct _MetaModuleClass MetaModuleClass;
|
typedef struct _MutterModuleClass MutterModuleClass;
|
||||||
typedef struct _MetaModulePrivate MetaModulePrivate;
|
typedef struct _MutterModulePrivate MutterModulePrivate;
|
||||||
|
|
||||||
struct _MetaModule
|
struct _MutterModule
|
||||||
{
|
{
|
||||||
GTypeModule parent;
|
GTypeModule parent;
|
||||||
|
|
||||||
MetaModulePrivate *priv;
|
MutterModulePrivate *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MetaModuleClass
|
struct _MutterModuleClass
|
||||||
{
|
{
|
||||||
GTypeModuleClass parent_class;
|
GTypeModuleClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
GType meta_module_get_type (void);
|
GType mutter_module_get_type (void);
|
||||||
|
|
||||||
GType meta_module_get_plugin_type (MetaModule *module);
|
GType mutter_module_get_plugin_type (MutterModule *module);
|
||||||
|
|
||||||
#endif
|
#endif
|
609
src/compositor/mutter/mutter-plugin-manager.c
Normal file
609
src/compositor/mutter/mutter-plugin-manager.c
Normal file
@@ -0,0 +1,609 @@
|
|||||||
|
/* -*- 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 "mutter-plugin-manager.h"
|
||||||
|
#include "prefs.h"
|
||||||
|
#include "errors.h"
|
||||||
|
#include "workspace.h"
|
||||||
|
#include "mutter-module.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There is only one instace of each module per the process.
|
||||||
|
*/
|
||||||
|
static GHashTable *plugin_modules = NULL;
|
||||||
|
|
||||||
|
static gboolean mutter_plugin_manager_reload (MutterPluginManager *plugin_mgr);
|
||||||
|
|
||||||
|
struct MutterPluginManager
|
||||||
|
{
|
||||||
|
MetaScreen *screen;
|
||||||
|
|
||||||
|
GList /* MutterPluginPending */ *pending_plugin_modules; /* Plugins not yet fully loaded */
|
||||||
|
GList /* MutterPlugin */ *plugins; /* TODO -- maybe use hash table */
|
||||||
|
GList *unload; /* Plugins that are disabled and pending unload */
|
||||||
|
|
||||||
|
guint idle_unload_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct MutterPluginPending
|
||||||
|
{
|
||||||
|
MutterModule *module;
|
||||||
|
char *path;
|
||||||
|
char *params;
|
||||||
|
} MutterPluginPending;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks that the plugin is compatible with the WM and sets up the plugin
|
||||||
|
* struct.
|
||||||
|
*/
|
||||||
|
static MutterPlugin *
|
||||||
|
mutter_plugin_load (MutterPluginManager *mgr,
|
||||||
|
MutterModule *module,
|
||||||
|
const gchar *params)
|
||||||
|
{
|
||||||
|
MutterPlugin *plugin = NULL;
|
||||||
|
GType plugin_type = mutter_module_get_plugin_type (module);
|
||||||
|
|
||||||
|
if (!plugin_type)
|
||||||
|
{
|
||||||
|
g_warning ("Plugin type not registered !!!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin = g_object_new (plugin_type,
|
||||||
|
"screen", mgr->screen,
|
||||||
|
"params", params,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attempst to unload a plugin; returns FALSE if plugin cannot be unloaded at
|
||||||
|
* present (e.g., and effect is in progress) and should be scheduled for
|
||||||
|
* removal later.
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
mutter_plugin_unload (MutterPlugin *plugin)
|
||||||
|
{
|
||||||
|
if (mutter_plugin_running (plugin))
|
||||||
|
{
|
||||||
|
g_object_set (plugin, "disabled", TRUE, NULL);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (plugin);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Iddle callback to remove plugins that could not be removed directly and are
|
||||||
|
* pending for removal.
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
mutter_plugin_manager_idle_unload (MutterPluginManager *plugin_mgr)
|
||||||
|
{
|
||||||
|
GList *l = plugin_mgr->unload;
|
||||||
|
gboolean dont_remove = TRUE;
|
||||||
|
|
||||||
|
while (l)
|
||||||
|
{
|
||||||
|
MutterPlugin *plugin = l->data;
|
||||||
|
|
||||||
|
if (mutter_plugin_unload (plugin))
|
||||||
|
{
|
||||||
|
/* Remove from list */
|
||||||
|
GList *p = l->prev;
|
||||||
|
GList *n = l->next;
|
||||||
|
|
||||||
|
if (!p)
|
||||||
|
plugin_mgr->unload = n;
|
||||||
|
else
|
||||||
|
p->next = n;
|
||||||
|
|
||||||
|
if (n)
|
||||||
|
n->prev = p;
|
||||||
|
|
||||||
|
g_list_free_1 (l);
|
||||||
|
|
||||||
|
l = n;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
l = l->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!plugin_mgr->unload)
|
||||||
|
{
|
||||||
|
/* If no more unloads are pending, remove the handler as well */
|
||||||
|
dont_remove = FALSE;
|
||||||
|
plugin_mgr->idle_unload_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dont_remove;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unloads all plugins
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
mutter_plugin_manager_unload (MutterPluginManager *plugin_mgr)
|
||||||
|
{
|
||||||
|
GList *plugins = plugin_mgr->plugins;
|
||||||
|
|
||||||
|
while (plugins)
|
||||||
|
{
|
||||||
|
MutterPlugin *plugin = plugins->data;
|
||||||
|
|
||||||
|
/* If the plugin could not be removed, move it to the unload list */
|
||||||
|
if (!mutter_plugin_unload (plugin))
|
||||||
|
{
|
||||||
|
plugin_mgr->unload = g_list_prepend (plugin_mgr->unload, plugin);
|
||||||
|
|
||||||
|
if (!plugin_mgr->idle_unload_id)
|
||||||
|
{
|
||||||
|
plugin_mgr->idle_unload_id = g_idle_add ((GSourceFunc)
|
||||||
|
mutter_plugin_manager_idle_unload,
|
||||||
|
plugin_mgr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins = plugins->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_free (plugin_mgr->plugins);
|
||||||
|
plugin_mgr->plugins = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
prefs_changed_callback (MetaPreference pref,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
MutterPluginManager *plugin_mgr = data;
|
||||||
|
|
||||||
|
if (pref == META_PREF_CLUTTER_PLUGINS)
|
||||||
|
{
|
||||||
|
mutter_plugin_manager_reload (plugin_mgr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static MutterModule *
|
||||||
|
mutter_plugin_manager_get_module (const gchar *path)
|
||||||
|
{
|
||||||
|
MutterModule *module = g_hash_table_lookup (plugin_modules, path);
|
||||||
|
|
||||||
|
if (!module &&
|
||||||
|
(module = g_object_new (MUTTER_TYPE_MODULE, "path", path, NULL)))
|
||||||
|
{
|
||||||
|
g_hash_table_insert (plugin_modules, g_strdup (path), module);
|
||||||
|
}
|
||||||
|
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Loads all plugins listed in gconf registry.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
mutter_plugin_manager_load (MutterPluginManager *plugin_mgr)
|
||||||
|
{
|
||||||
|
const gchar *dpath = MUTTER_PLUGIN_DIR "/";
|
||||||
|
GSList *plugins, *fallback = NULL;
|
||||||
|
|
||||||
|
plugins = meta_prefs_get_clutter_plugins ();
|
||||||
|
|
||||||
|
if (!plugins)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If no plugins are specified, try to load the default plugin.
|
||||||
|
*/
|
||||||
|
fallback = g_slist_append (fallback, "default");
|
||||||
|
plugins = fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (plugins)
|
||||||
|
{
|
||||||
|
gchar *plugin_string;
|
||||||
|
gchar *params;
|
||||||
|
|
||||||
|
plugin_string = g_strdup (plugins->data);
|
||||||
|
|
||||||
|
if (plugin_string)
|
||||||
|
{
|
||||||
|
MutterModule *module;
|
||||||
|
gchar *path;
|
||||||
|
|
||||||
|
params = strchr (plugin_string, ':');
|
||||||
|
|
||||||
|
if (params)
|
||||||
|
{
|
||||||
|
*params = 0;
|
||||||
|
++params;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_path_is_absolute (plugin_string))
|
||||||
|
path = g_strdup (plugin_string);
|
||||||
|
else
|
||||||
|
path = g_strconcat (dpath, plugin_string, ".so", NULL);
|
||||||
|
|
||||||
|
module = mutter_plugin_manager_get_module (path);
|
||||||
|
|
||||||
|
if (module)
|
||||||
|
{
|
||||||
|
gboolean use_succeeded;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This dlopens the module and registers the plugin type with the
|
||||||
|
* GType system, if the module is not already loaded. When we
|
||||||
|
* create a plugin, the type system also calls g_type_module_use()
|
||||||
|
* to guarantee the module will not be unloaded during the plugin
|
||||||
|
* life time. Consequently we can unuse() the module again.
|
||||||
|
*/
|
||||||
|
use_succeeded = g_type_module_use (G_TYPE_MODULE (module));
|
||||||
|
|
||||||
|
if (use_succeeded)
|
||||||
|
{
|
||||||
|
MutterPluginPending *pending = g_new0 (MutterPluginPending, 1);
|
||||||
|
pending->module = module;
|
||||||
|
pending->path = g_strdup (path);
|
||||||
|
pending->params = g_strdup (params);
|
||||||
|
plugin_mgr->pending_plugin_modules =
|
||||||
|
g_list_prepend (plugin_mgr->pending_plugin_modules, pending);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_warning ("Unable to load plugin module [%s]: %s",
|
||||||
|
path, g_module_error());
|
||||||
|
|
||||||
|
g_free (path);
|
||||||
|
g_free (plugin_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins = plugins->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (fallback)
|
||||||
|
g_slist_free (fallback);
|
||||||
|
|
||||||
|
if (plugin_mgr->pending_plugin_modules != NULL)
|
||||||
|
{
|
||||||
|
meta_prefs_add_listener (prefs_changed_callback, plugin_mgr);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
mutter_plugin_manager_initialize (MutterPluginManager *plugin_mgr)
|
||||||
|
{
|
||||||
|
GList *iter;
|
||||||
|
|
||||||
|
for (iter = plugin_mgr->pending_plugin_modules; iter; iter = iter->next)
|
||||||
|
{
|
||||||
|
MutterPluginPending *pending = (MutterPluginPending*) iter->data;
|
||||||
|
MutterPlugin *p;
|
||||||
|
|
||||||
|
if ((p = mutter_plugin_load (plugin_mgr, pending->module, pending->params)))
|
||||||
|
{
|
||||||
|
plugin_mgr->plugins = g_list_prepend (plugin_mgr->plugins, p);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_warning ("Plugin load for [%s] failed", pending->path);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_type_module_unuse (G_TYPE_MODULE (pending->module));
|
||||||
|
g_free (pending->path);
|
||||||
|
g_free (pending->params);
|
||||||
|
g_free (pending);
|
||||||
|
}
|
||||||
|
g_list_free (plugin_mgr->pending_plugin_modules);
|
||||||
|
plugin_mgr->pending_plugin_modules = NULL;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reloads all plugins
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
mutter_plugin_manager_reload (MutterPluginManager *plugin_mgr)
|
||||||
|
{
|
||||||
|
/* TODO -- brute force; should we build a list of plugins to load and list of
|
||||||
|
* plugins to unload? We are probably not going to have large numbers of
|
||||||
|
* plugins loaded at the same time, so it might not be worth it.
|
||||||
|
*/
|
||||||
|
mutter_plugin_manager_unload (plugin_mgr);
|
||||||
|
return mutter_plugin_manager_load (plugin_mgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
MutterPluginManager *
|
||||||
|
mutter_plugin_manager_new (MetaScreen *screen)
|
||||||
|
{
|
||||||
|
MutterPluginManager *plugin_mgr;
|
||||||
|
|
||||||
|
if (!plugin_modules)
|
||||||
|
{
|
||||||
|
plugin_modules = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin_mgr = g_new0 (MutterPluginManager, 1);
|
||||||
|
|
||||||
|
plugin_mgr->screen = screen;
|
||||||
|
|
||||||
|
return plugin_mgr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mutter_plugin_manager_kill_effect (MutterPluginManager *plugin_mgr,
|
||||||
|
MutterWindow *actor,
|
||||||
|
unsigned long events)
|
||||||
|
{
|
||||||
|
GList *l = plugin_mgr->plugins;
|
||||||
|
|
||||||
|
while (l)
|
||||||
|
{
|
||||||
|
MutterPlugin *plugin = l->data;
|
||||||
|
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||||
|
|
||||||
|
if (!mutter_plugin_disabled (plugin)
|
||||||
|
&& (mutter_plugin_features (plugin) & events)
|
||||||
|
&& klass->kill_effect)
|
||||||
|
klass->kill_effect (plugin, actor, events);
|
||||||
|
|
||||||
|
l = l->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ALL_BUT_SWITCH \
|
||||||
|
MUTTER_PLUGIN_ALL_EFFECTS & \
|
||||||
|
~MUTTER_PLUGIN_SWITCH_WORKSPACE
|
||||||
|
/*
|
||||||
|
* Public method that the compositor hooks into for events that require
|
||||||
|
* no additional parameters.
|
||||||
|
*
|
||||||
|
* Returns TRUE if at least one of the plugins 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
|
||||||
|
mutter_plugin_manager_event_simple (MutterPluginManager *plugin_mgr,
|
||||||
|
MutterWindow *actor,
|
||||||
|
unsigned long event)
|
||||||
|
{
|
||||||
|
GList *l = plugin_mgr->plugins;
|
||||||
|
gboolean retval = FALSE;
|
||||||
|
|
||||||
|
while (l)
|
||||||
|
{
|
||||||
|
MutterPlugin *plugin = l->data;
|
||||||
|
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||||
|
|
||||||
|
if (!mutter_plugin_disabled (plugin) &&
|
||||||
|
(mutter_plugin_features (plugin) & event))
|
||||||
|
{
|
||||||
|
retval = TRUE;
|
||||||
|
|
||||||
|
switch (event)
|
||||||
|
{
|
||||||
|
case MUTTER_PLUGIN_MINIMIZE:
|
||||||
|
if (klass->minimize)
|
||||||
|
{
|
||||||
|
mutter_plugin_manager_kill_effect (
|
||||||
|
plugin_mgr,
|
||||||
|
actor,
|
||||||
|
ALL_BUT_SWITCH);
|
||||||
|
|
||||||
|
_mutter_plugin_effect_started (plugin);
|
||||||
|
klass->minimize (plugin, actor);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MUTTER_PLUGIN_MAP:
|
||||||
|
if (klass->map)
|
||||||
|
{
|
||||||
|
mutter_plugin_manager_kill_effect (
|
||||||
|
plugin_mgr,
|
||||||
|
actor,
|
||||||
|
ALL_BUT_SWITCH);
|
||||||
|
|
||||||
|
_mutter_plugin_effect_started (plugin);
|
||||||
|
klass->map (plugin, actor);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MUTTER_PLUGIN_DESTROY:
|
||||||
|
if (klass->destroy)
|
||||||
|
{
|
||||||
|
_mutter_plugin_effect_started (plugin);
|
||||||
|
klass->destroy (plugin, actor);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_warning ("Incorrect handler called for event %lu", event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
l = l->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The public method that the compositor hooks into for maximize and unmaximize
|
||||||
|
* events.
|
||||||
|
*
|
||||||
|
* Returns TRUE if at least one of the plugins 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
|
||||||
|
mutter_plugin_manager_event_maximize (MutterPluginManager *plugin_mgr,
|
||||||
|
MutterWindow *actor,
|
||||||
|
unsigned long event,
|
||||||
|
gint target_x,
|
||||||
|
gint target_y,
|
||||||
|
gint target_width,
|
||||||
|
gint target_height)
|
||||||
|
{
|
||||||
|
GList *l = plugin_mgr->plugins;
|
||||||
|
gboolean retval = FALSE;
|
||||||
|
|
||||||
|
while (l)
|
||||||
|
{
|
||||||
|
MutterPlugin *plugin = l->data;
|
||||||
|
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||||
|
|
||||||
|
if (!mutter_plugin_disabled (plugin) &&
|
||||||
|
(mutter_plugin_features (plugin) & event))
|
||||||
|
{
|
||||||
|
retval = TRUE;
|
||||||
|
|
||||||
|
switch (event)
|
||||||
|
{
|
||||||
|
case MUTTER_PLUGIN_MAXIMIZE:
|
||||||
|
if (klass->maximize)
|
||||||
|
{
|
||||||
|
mutter_plugin_manager_kill_effect (
|
||||||
|
plugin_mgr,
|
||||||
|
actor,
|
||||||
|
ALL_BUT_SWITCH);
|
||||||
|
|
||||||
|
_mutter_plugin_effect_started (plugin);
|
||||||
|
klass->maximize (plugin, actor,
|
||||||
|
target_x, target_y,
|
||||||
|
target_width, target_height);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MUTTER_PLUGIN_UNMAXIMIZE:
|
||||||
|
if (klass->unmaximize)
|
||||||
|
{
|
||||||
|
mutter_plugin_manager_kill_effect (
|
||||||
|
plugin_mgr,
|
||||||
|
actor,
|
||||||
|
ALL_BUT_SWITCH);
|
||||||
|
|
||||||
|
_mutter_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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
l = l->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The public method that the compositor hooks into for desktop switching.
|
||||||
|
*
|
||||||
|
* Returns TRUE if at least one of the plugins 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
|
||||||
|
mutter_plugin_manager_switch_workspace (MutterPluginManager *plugin_mgr,
|
||||||
|
const GList **actors,
|
||||||
|
gint from,
|
||||||
|
gint to,
|
||||||
|
MetaMotionDirection direction)
|
||||||
|
{
|
||||||
|
GList *l = plugin_mgr->plugins;
|
||||||
|
gboolean retval = FALSE;
|
||||||
|
|
||||||
|
while (l)
|
||||||
|
{
|
||||||
|
MutterPlugin *plugin = l->data;
|
||||||
|
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||||
|
|
||||||
|
if (!mutter_plugin_disabled (plugin) &&
|
||||||
|
(mutter_plugin_features (plugin) & MUTTER_PLUGIN_SWITCH_WORKSPACE) &&
|
||||||
|
(actors && *actors))
|
||||||
|
{
|
||||||
|
if (klass->switch_workspace)
|
||||||
|
{
|
||||||
|
retval = TRUE;
|
||||||
|
mutter_plugin_manager_kill_effect (
|
||||||
|
plugin_mgr,
|
||||||
|
MUTTER_WINDOW ((*actors)->data),
|
||||||
|
MUTTER_PLUGIN_SWITCH_WORKSPACE);
|
||||||
|
|
||||||
|
_mutter_plugin_effect_started (plugin);
|
||||||
|
klass->switch_workspace (plugin, actors, from, to, direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
l = l->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The public method that the compositor hooks into for desktop switching.
|
||||||
|
*
|
||||||
|
* Returns TRUE if at least one of the plugins 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
|
||||||
|
mutter_plugin_manager_xevent_filter (MutterPluginManager *plugin_mgr,
|
||||||
|
XEvent *xev)
|
||||||
|
{
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
if (!plugin_mgr)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
l = plugin_mgr->plugins;
|
||||||
|
|
||||||
|
while (l)
|
||||||
|
{
|
||||||
|
MutterPlugin *plugin = l->data;
|
||||||
|
MutterPluginClass *klass = MUTTER_PLUGIN_GET_CLASS (plugin);
|
||||||
|
|
||||||
|
if (klass->xevent_filter)
|
||||||
|
{
|
||||||
|
if (klass->xevent_filter (plugin, xev) == TRUE)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
l = l->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user