From 505cabbd3036081f26586cabc64c26e7769c0ec9 Mon Sep 17 00:00:00 2001 From: Perberos Date: Thu, 1 Dec 2011 23:53:21 -0300 Subject: moving from https://github.com/perberos/mate-desktop-environment --- plugins/media-keys/Makefile.am | 207 ++ plugins/media-keys/Makefile.in | 1159 +++++++++++ plugins/media-keys/acme.h | 78 + plugins/media-keys/acme.ui | 33 + plugins/media-keys/cut-n-paste/Makefile.am | 39 + plugins/media-keys/cut-n-paste/Makefile.in | 586 ++++++ plugins/media-keys/cut-n-paste/gvc-channel-map.c | 292 +++ plugins/media-keys/cut-n-paste/gvc-channel-map.h | 83 + plugins/media-keys/cut-n-paste/gvc-mixer-card.c | 493 +++++ plugins/media-keys/cut-n-paste/gvc-mixer-card.h | 90 + plugins/media-keys/cut-n-paste/gvc-mixer-control.c | 2123 ++++++++++++++++++++ plugins/media-keys/cut-n-paste/gvc-mixer-control.h | 102 + .../media-keys/cut-n-paste/gvc-mixer-event-role.c | 239 +++ .../media-keys/cut-n-paste/gvc-mixer-event-role.h | 61 + .../media-keys/cut-n-paste/gvc-mixer-sink-input.c | 188 ++ .../media-keys/cut-n-paste/gvc-mixer-sink-input.h | 61 + plugins/media-keys/cut-n-paste/gvc-mixer-sink.c | 220 ++ plugins/media-keys/cut-n-paste/gvc-mixer-sink.h | 61 + .../cut-n-paste/gvc-mixer-source-output.c | 128 ++ .../cut-n-paste/gvc-mixer-source-output.h | 61 + plugins/media-keys/cut-n-paste/gvc-mixer-source.c | 220 ++ plugins/media-keys/cut-n-paste/gvc-mixer-source.h | 61 + plugins/media-keys/cut-n-paste/gvc-mixer-stream.c | 875 ++++++++ plugins/media-keys/cut-n-paste/gvc-mixer-stream.h | 128 ++ plugins/media-keys/gsd-marshal.list | 1 + plugins/media-keys/gsd-media-keys-manager.c | 1373 +++++++++++++ plugins/media-keys/gsd-media-keys-manager.h | 72 + plugins/media-keys/gsd-media-keys-manager.xml | 14 + plugins/media-keys/gsd-media-keys-plugin.c | 104 + plugins/media-keys/gsd-media-keys-plugin.h | 63 + plugins/media-keys/gsd-media-keys-window.c | 714 +++++++ plugins/media-keys/gsd-media-keys-window.h | 78 + plugins/media-keys/libmedia-keys.la | 41 + plugins/media-keys/media-keys.mate-settings-plugin | 136 ++ .../media-keys/media-keys.mate-settings-plugin.in | 8 + plugins/media-keys/test-media-keys.c | 64 + plugins/media-keys/test-media-window.c | 152 ++ plugins/media-keys/touchpad-disabled-16.png | Bin 0 -> 610 bytes plugins/media-keys/touchpad-disabled-22.png | Bin 0 -> 957 bytes plugins/media-keys/touchpad-disabled-24.png | Bin 0 -> 985 bytes plugins/media-keys/touchpad-disabled-32.png | Bin 0 -> 1610 bytes plugins/media-keys/touchpad-disabled-48.png | Bin 0 -> 2208 bytes plugins/media-keys/touchpad-disabled-template.svg | 1172 +++++++++++ plugins/media-keys/touchpad-disabled.svg | 833 ++++++++ plugins/media-keys/touchpad-enabled-16.png | Bin 0 -> 626 bytes plugins/media-keys/touchpad-enabled-22.png | Bin 0 -> 938 bytes plugins/media-keys/touchpad-enabled-24.png | Bin 0 -> 949 bytes plugins/media-keys/touchpad-enabled-32.png | Bin 0 -> 1494 bytes plugins/media-keys/touchpad-enabled-48.png | Bin 0 -> 2041 bytes plugins/media-keys/touchpad-enabled-template.svg | 936 +++++++++ plugins/media-keys/touchpad-enabled.svg | 581 ++++++ 51 files changed, 13930 insertions(+) create mode 100644 plugins/media-keys/Makefile.am create mode 100644 plugins/media-keys/Makefile.in create mode 100644 plugins/media-keys/acme.h create mode 100644 plugins/media-keys/acme.ui create mode 100644 plugins/media-keys/cut-n-paste/Makefile.am create mode 100644 plugins/media-keys/cut-n-paste/Makefile.in create mode 100644 plugins/media-keys/cut-n-paste/gvc-channel-map.c create mode 100644 plugins/media-keys/cut-n-paste/gvc-channel-map.h create mode 100644 plugins/media-keys/cut-n-paste/gvc-mixer-card.c create mode 100644 plugins/media-keys/cut-n-paste/gvc-mixer-card.h create mode 100644 plugins/media-keys/cut-n-paste/gvc-mixer-control.c create mode 100644 plugins/media-keys/cut-n-paste/gvc-mixer-control.h create mode 100644 plugins/media-keys/cut-n-paste/gvc-mixer-event-role.c create mode 100644 plugins/media-keys/cut-n-paste/gvc-mixer-event-role.h create mode 100644 plugins/media-keys/cut-n-paste/gvc-mixer-sink-input.c create mode 100644 plugins/media-keys/cut-n-paste/gvc-mixer-sink-input.h create mode 100644 plugins/media-keys/cut-n-paste/gvc-mixer-sink.c create mode 100644 plugins/media-keys/cut-n-paste/gvc-mixer-sink.h create mode 100644 plugins/media-keys/cut-n-paste/gvc-mixer-source-output.c create mode 100644 plugins/media-keys/cut-n-paste/gvc-mixer-source-output.h create mode 100644 plugins/media-keys/cut-n-paste/gvc-mixer-source.c create mode 100644 plugins/media-keys/cut-n-paste/gvc-mixer-source.h create mode 100644 plugins/media-keys/cut-n-paste/gvc-mixer-stream.c create mode 100644 plugins/media-keys/cut-n-paste/gvc-mixer-stream.h create mode 100644 plugins/media-keys/gsd-marshal.list create mode 100644 plugins/media-keys/gsd-media-keys-manager.c create mode 100644 plugins/media-keys/gsd-media-keys-manager.h create mode 100644 plugins/media-keys/gsd-media-keys-manager.xml create mode 100644 plugins/media-keys/gsd-media-keys-plugin.c create mode 100644 plugins/media-keys/gsd-media-keys-plugin.h create mode 100644 plugins/media-keys/gsd-media-keys-window.c create mode 100644 plugins/media-keys/gsd-media-keys-window.h create mode 100644 plugins/media-keys/libmedia-keys.la create mode 100644 plugins/media-keys/media-keys.mate-settings-plugin create mode 100644 plugins/media-keys/media-keys.mate-settings-plugin.in create mode 100644 plugins/media-keys/test-media-keys.c create mode 100644 plugins/media-keys/test-media-window.c create mode 100644 plugins/media-keys/touchpad-disabled-16.png create mode 100644 plugins/media-keys/touchpad-disabled-22.png create mode 100644 plugins/media-keys/touchpad-disabled-24.png create mode 100644 plugins/media-keys/touchpad-disabled-32.png create mode 100644 plugins/media-keys/touchpad-disabled-48.png create mode 100644 plugins/media-keys/touchpad-disabled-template.svg create mode 100644 plugins/media-keys/touchpad-disabled.svg create mode 100644 plugins/media-keys/touchpad-enabled-16.png create mode 100644 plugins/media-keys/touchpad-enabled-22.png create mode 100644 plugins/media-keys/touchpad-enabled-24.png create mode 100644 plugins/media-keys/touchpad-enabled-32.png create mode 100644 plugins/media-keys/touchpad-enabled-48.png create mode 100644 plugins/media-keys/touchpad-enabled-template.svg create mode 100644 plugins/media-keys/touchpad-enabled.svg (limited to 'plugins/media-keys') diff --git a/plugins/media-keys/Makefile.am b/plugins/media-keys/Makefile.am new file mode 100644 index 0000000..d8bff08 --- /dev/null +++ b/plugins/media-keys/Makefile.am @@ -0,0 +1,207 @@ +icondir = $(datadir)/icons/mate +context = actions + +NULL = + +SUBDIRS = +plugin_LTLIBRARIES = + +if HAVE_PULSE +SUBDIRS += cut-n-paste +plugin_LTLIBRARIES += libmedia-keys.la +endif + +BUILT_SOURCES = \ + gsd-media-keys-manager-glue.h \ + gsd-marshal.h \ + gsd-marshal.c \ + $(NULL) + +ICON_FILES = \ + touchpad-disabled-16.png \ + touchpad-enabled-16.png \ + touchpad-disabled-22.png \ + touchpad-enabled-22.png \ + touchpad-disabled-24.png \ + touchpad-enabled-24.png \ + touchpad-disabled-32.png \ + touchpad-enabled-32.png \ + touchpad-disabled-48.png \ + touchpad-enabled-48.png \ + touchpad-disabled.svg \ + touchpad-enabled.svg + +install-data-local: + $(mkinstalldirs) $(DESTDIR)$(icondir)/16x16/$(context) + $(mkinstalldirs) $(DESTDIR)$(icondir)/22x22/$(context) + $(mkinstalldirs) $(DESTDIR)$(icondir)/24x24/$(context) + $(mkinstalldirs) $(DESTDIR)$(icondir)/32x32/$(context) + $(mkinstalldirs) $(DESTDIR)$(icondir)/scalable/$(context) + $(INSTALL_DATA) $(srcdir)/touchpad-enabled-16.png $(DESTDIR)$(icondir)/16x16/$(context)/touchpad-enabled.png + $(INSTALL_DATA) $(srcdir)/touchpad-enabled-22.png $(DESTDIR)$(icondir)/22x22/$(context)/touchpad-enabled.png + $(INSTALL_DATA) $(srcdir)/touchpad-enabled-24.png $(DESTDIR)$(icondir)/24x24/$(context)/touchpad-enabled.png + $(INSTALL_DATA) $(srcdir)/touchpad-enabled-32.png $(DESTDIR)$(icondir)/32x32/$(context)/touchpad-enabled.png + $(INSTALL_DATA) $(srcdir)/touchpad-enabled.svg $(DESTDIR)$(icondir)/scalable/$(context)/touchpad-enabled.svg + $(INSTALL_DATA) $(srcdir)/touchpad-disabled-16.png $(DESTDIR)$(icondir)/16x16/$(context)/touchpad-disabled.png + $(INSTALL_DATA) $(srcdir)/touchpad-disabled-22.png $(DESTDIR)$(icondir)/22x22/$(context)/touchpad-disabled.png + $(INSTALL_DATA) $(srcdir)/touchpad-disabled-24.png $(DESTDIR)$(icondir)/24x24/$(context)/touchpad-disabled.png + $(INSTALL_DATA) $(srcdir)/touchpad-disabled-32.png $(DESTDIR)$(icondir)/32x32/$(context)/touchpad-disabled.png + $(INSTALL_DATA) $(srcdir)/touchpad-disabled.svg $(DESTDIR)$(icondir)/scalable/$(context)/touchpad-disabled.svg + +uninstall-local: + rm -f $(DESTDIR)$(icondir)/16x16/$(context)/touchpad-enabled.png + rm -f $(DESTDIR)$(icondir)/22x22/$(context)/touchpad-enabled.png + rm -f $(DESTDIR)$(icondir)/24x24/$(context)/touchpad-enabled.png + rm -f $(DESTDIR)$(icondir)/32x32/$(context)/touchpad-enabled.png + rm -f $(DESTDIR)$(icondir)/scalable/$(context)/touchpad-enabled.svg + rm -f $(DESTDIR)$(icondir)/16x16/$(context)/touchpad-disabled.png + rm -f $(DESTDIR)$(icondir)/22x22/$(context)/touchpad-disabled.png + rm -f $(DESTDIR)$(icondir)/24x24/$(context)/touchpad-disabled.png + rm -f $(DESTDIR)$(icondir)/32x32/$(context)/touchpad-disabled.png + rm -f $(DESTDIR)$(icondir)/scalable/$(context)/touchpad-disabled.svg + +gsd-media-keys-manager-glue.h: gsd-media-keys-manager.xml Makefile + dbus-binding-tool --prefix=gsd_media_keys_manager --mode=glib-server $< > xgen-$(@F) \ + && ( cmp -s xgen-$(@F) $@ || cp xgen-$(@F) $@ ) \ + && rm -f xgen-$(@F) + +gsd-marshal.c: gsd-marshal.list + $(GLIB_GENMARSHAL) --prefix=gsd_marshal $< --header --body --internal > $@ + +gsd-marshal.h: gsd-marshal.list + $(GLIB_GENMARSHAL) --prefix=gsd_marshal $< --header --internal > $@ + +libmedia_keys_la_SOURCES = \ + gsd-media-keys-plugin.h \ + gsd-media-keys-plugin.c \ + gsd-media-keys-manager.h \ + gsd-media-keys-manager.c \ + gsd-media-keys-window.h \ + gsd-media-keys-window.c \ + acme.h \ + $(BUILT_SOURCES) \ + $(NULL) + +libmedia_keys_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -I$(top_srcdir)/plugins/common \ + -I$(top_srcdir)/plugins/media-keys/cut-n-paste \ + -DPIXMAPDIR=\""$(pkgdatadir)"\" \ + -DGTKBUILDERDIR=\""$(pkgdatadir)"\" \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libmedia_keys_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libmedia_keys_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) + +libmedia_keys_la_LIBADD = \ + $(top_builddir)/plugins/common/libcommon.la \ + $(top_builddir)/plugins/media-keys/cut-n-paste/libgvc.la \ + $(SETTINGS_PLUGIN_LIBS) \ + $(XF86MISC_LIBS) \ + -lm + +plugin_in_files = \ + media-keys.mate-settings-plugin.in + +if HAVE_PULSE +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) +endif + +noinst_PROGRAMS = \ + test-media-keys \ + test-media-window \ + $(NULL) + +test_media_window_SOURCES = \ + gsd-media-keys-window.c \ + gsd-media-keys-window.h \ + test-media-window.c \ + $(NULL) + +test_media_window_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -I$(top_srcdir)/plugins/common \ + -I$(top_srcdir)/plugins/media-keys/cut-n-paste \ + -DDATADIR=\""$(datadir)"\" \ + -DPIXMAPDIR=\""$(pkgdatadir)"\" \ + -DGTKBUILDERDIR=\""$(pkgdatadir)"\" \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +test_media_window_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +test_media_window_LDADD = \ + $(top_builddir)/plugins/common/libcommon.la \ + $(SETTINGS_DAEMON_LIBS) \ + $(SETTINGS_PLUGIN_LIBS) \ + $(XF86MISC_LIBS) \ + $(GST_LIBS) \ + -lm + +test_media_keys_SOURCES = \ + gsd-media-keys-manager.c \ + gsd-media-keys-manager.h \ + gsd-media-keys-window.h \ + gsd-media-keys-window.c \ + test-media-keys.c \ + $(BUILT_SOURCES) \ + $(NULL) + +test_media_keys_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -I$(top_srcdir)/plugins/common \ + -I$(top_srcdir)/plugins/media-keys/cut-n-paste \ + -DPIXMAPDIR=\""$(pkgdatadir)"\" \ + -DGTKBUILDERDIR=\""$(pkgdatadir)"\" \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +test_media_keys_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +test_media_keys_LDADD = \ + $(top_builddir)/mate-settings-daemon/libgsd-profile.la \ + $(top_builddir)/plugins/common/libcommon.la \ + $(SETTINGS_DAEMON_LIBS) \ + $(SETTINGS_PLUGIN_LIBS) \ + $(XF86MISC_LIBS) \ + $(GST_LIBS) \ + -lm + +if HAVE_PULSE +test_media_keys_LDADD += $(top_builddir)/plugins/media-keys/cut-n-paste/libgvc.la +endif + +gtkbuilderdir = $(pkgdatadir) +gtkbuilder_DATA = \ + acme.ui \ + $(NULL) + +DIST_SUBDIRS = cut-n-paste + +EXTRA_DIST = \ + gsd-media-keys-manager.xml \ + gsd-marshal.list \ + $(plugin_in_files) \ + $(gtkbuilder_DATA) \ + $(pixmaps_DATA) \ + touchpad-enabled-template.svg \ + touchpad-disabled-template.svg \ + $(ICON_FILES) + +CLEANFILES = \ + $(BUILT_SOURCES) \ + $(plugin_DATA) + +DISTCLEANFILES = \ + $(plugin_DATA) + +@GSD_INTLTOOL_PLUGIN_RULE@ diff --git a/plugins/media-keys/Makefile.in b/plugins/media-keys/Makefile.in new file mode 100644 index 0000000..3a0cec7 --- /dev/null +++ b/plugins/media-keys/Makefile.in @@ -0,0 +1,1159 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@HAVE_PULSE_TRUE@am__append_1 = cut-n-paste +@HAVE_PULSE_TRUE@am__append_2 = libmedia-keys.la +noinst_PROGRAMS = test-media-keys$(EXEEXT) test-media-window$(EXEEXT) \ + $(am__EXEEXT_1) +@HAVE_PULSE_TRUE@am__append_3 = $(top_builddir)/plugins/media-keys/cut-n-paste/libgvc.la +subdir = plugins/media-keys +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(plugindir)" \ + "$(DESTDIR)$(gtkbuilderdir)" "$(DESTDIR)$(plugindir)" +LTLIBRARIES = $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +libmedia_keys_la_DEPENDENCIES = \ + $(top_builddir)/plugins/common/libcommon.la \ + $(top_builddir)/plugins/media-keys/cut-n-paste/libgvc.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am__objects_1 = +am__objects_2 = libmedia_keys_la-gsd-marshal.lo $(am__objects_1) +am_libmedia_keys_la_OBJECTS = \ + libmedia_keys_la-gsd-media-keys-plugin.lo \ + libmedia_keys_la-gsd-media-keys-manager.lo \ + libmedia_keys_la-gsd-media-keys-window.lo $(am__objects_2) \ + $(am__objects_1) +libmedia_keys_la_OBJECTS = $(am_libmedia_keys_la_OBJECTS) +libmedia_keys_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libmedia_keys_la_CFLAGS) \ + $(CFLAGS) $(libmedia_keys_la_LDFLAGS) $(LDFLAGS) -o $@ +@HAVE_PULSE_TRUE@am_libmedia_keys_la_rpath = -rpath $(plugindir) +am__EXEEXT_1 = +PROGRAMS = $(noinst_PROGRAMS) +am__objects_3 = test_media_keys-gsd-marshal.$(OBJEXT) $(am__objects_1) +am_test_media_keys_OBJECTS = \ + test_media_keys-gsd-media-keys-manager.$(OBJEXT) \ + test_media_keys-gsd-media-keys-window.$(OBJEXT) \ + test_media_keys-test-media-keys.$(OBJEXT) $(am__objects_3) \ + $(am__objects_1) +test_media_keys_OBJECTS = $(am_test_media_keys_OBJECTS) +test_media_keys_DEPENDENCIES = \ + $(top_builddir)/mate-settings-daemon/libgsd-profile.la \ + $(top_builddir)/plugins/common/libcommon.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__append_3) +test_media_keys_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_media_keys_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am_test_media_window_OBJECTS = \ + test_media_window-gsd-media-keys-window.$(OBJEXT) \ + test_media_window-test-media-window.$(OBJEXT) $(am__objects_1) +test_media_window_OBJECTS = $(am_test_media_window_OBJECTS) +test_media_window_DEPENDENCIES = \ + $(top_builddir)/plugins/common/libcommon.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +test_media_window_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(test_media_window_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libmedia_keys_la_SOURCES) $(test_media_keys_SOURCES) \ + $(test_media_window_SOURCES) +DIST_SOURCES = $(libmedia_keys_la_SOURCES) $(test_media_keys_SOURCES) \ + $(test_media_window_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +DATA = $(gtkbuilder_DATA) $(plugin_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEBUG_CFLAGS = @DEBUG_CFLAGS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FONTCONFIG_CFLAGS = @FONTCONFIG_CFLAGS@ +FONTCONFIG_LIBS = @FONTCONFIG_LIBS@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIOUNIX_CFLAGS = @GIOUNIX_CFLAGS@ +GIOUNIX_LIBS = @GIOUNIX_LIBS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GREP = @GREP@ +GSD_INTLTOOL_PLUGIN_RULE = @GSD_INTLTOOL_PLUGIN_RULE@ +GSD_PLUGIN_LDFLAGS = @GSD_PLUGIN_LDFLAGS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBEXECDIR = @LIBEXECDIR@ +LIBMATEKBDUI_CFLAGS = @LIBMATEKBDUI_CFLAGS@ +LIBMATEKBDUI_LIBS = @LIBMATEKBDUI_LIBS@ +LIBMATENOTIFY_CFLAGS = @LIBMATENOTIFY_CFLAGS@ +LIBMATENOTIFY_LIBS = @LIBMATENOTIFY_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MATECONFTOOL = @MATECONFTOOL@ +MATECONF_SCHEMA_CONFIG_SOURCE = @MATECONF_SCHEMA_CONFIG_SOURCE@ +MATECONF_SCHEMA_FILE_DIR = @MATECONF_SCHEMA_FILE_DIR@ +MATE_KEYBINDINGS_KEYSDIR = @MATE_KEYBINDINGS_KEYSDIR@ +MKDIR_P = @MKDIR_P@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +MSGFMT_OPTS = @MSGFMT_OPTS@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_DATABASE = @NSS_DATABASE@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POFILES = @POFILES@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +PULSE_CFLAGS = @PULSE_CFLAGS@ +PULSE_LIBS = @PULSE_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SETTINGS_DAEMON_CFLAGS = @SETTINGS_DAEMON_CFLAGS@ +SETTINGS_DAEMON_LIBS = @SETTINGS_DAEMON_LIBS@ +SETTINGS_PLUGIN_CFLAGS = @SETTINGS_PLUGIN_CFLAGS@ +SETTINGS_PLUGIN_LIBS = @SETTINGS_PLUGIN_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +X11_LIBS = @X11_LIBS@ +XF86MISC_LIBS = @XF86MISC_LIBS@ +XGETTEXT = @XGETTEXT@ +XINPUT_LIBS = @XINPUT_LIBS@ +XMKMF = @XMKMF@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +plugindir = @plugindir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +icondir = $(datadir)/icons/mate +context = actions +NULL = +SUBDIRS = $(am__append_1) +plugin_LTLIBRARIES = $(am__append_2) +BUILT_SOURCES = \ + gsd-media-keys-manager-glue.h \ + gsd-marshal.h \ + gsd-marshal.c \ + $(NULL) + +ICON_FILES = \ + touchpad-disabled-16.png \ + touchpad-enabled-16.png \ + touchpad-disabled-22.png \ + touchpad-enabled-22.png \ + touchpad-disabled-24.png \ + touchpad-enabled-24.png \ + touchpad-disabled-32.png \ + touchpad-enabled-32.png \ + touchpad-disabled-48.png \ + touchpad-enabled-48.png \ + touchpad-disabled.svg \ + touchpad-enabled.svg + +libmedia_keys_la_SOURCES = \ + gsd-media-keys-plugin.h \ + gsd-media-keys-plugin.c \ + gsd-media-keys-manager.h \ + gsd-media-keys-manager.c \ + gsd-media-keys-window.h \ + gsd-media-keys-window.c \ + acme.h \ + $(BUILT_SOURCES) \ + $(NULL) + +libmedia_keys_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -I$(top_srcdir)/plugins/common \ + -I$(top_srcdir)/plugins/media-keys/cut-n-paste \ + -DPIXMAPDIR=\""$(pkgdatadir)"\" \ + -DGTKBUILDERDIR=\""$(pkgdatadir)"\" \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libmedia_keys_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libmedia_keys_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) + +libmedia_keys_la_LIBADD = \ + $(top_builddir)/plugins/common/libcommon.la \ + $(top_builddir)/plugins/media-keys/cut-n-paste/libgvc.la \ + $(SETTINGS_PLUGIN_LIBS) \ + $(XF86MISC_LIBS) \ + -lm + +plugin_in_files = \ + media-keys.mate-settings-plugin.in + +@HAVE_PULSE_TRUE@plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) +test_media_window_SOURCES = \ + gsd-media-keys-window.c \ + gsd-media-keys-window.h \ + test-media-window.c \ + $(NULL) + +test_media_window_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -I$(top_srcdir)/plugins/common \ + -I$(top_srcdir)/plugins/media-keys/cut-n-paste \ + -DDATADIR=\""$(datadir)"\" \ + -DPIXMAPDIR=\""$(pkgdatadir)"\" \ + -DGTKBUILDERDIR=\""$(pkgdatadir)"\" \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +test_media_window_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +test_media_window_LDADD = \ + $(top_builddir)/plugins/common/libcommon.la \ + $(SETTINGS_DAEMON_LIBS) \ + $(SETTINGS_PLUGIN_LIBS) \ + $(XF86MISC_LIBS) \ + $(GST_LIBS) \ + -lm + +test_media_keys_SOURCES = \ + gsd-media-keys-manager.c \ + gsd-media-keys-manager.h \ + gsd-media-keys-window.h \ + gsd-media-keys-window.c \ + test-media-keys.c \ + $(BUILT_SOURCES) \ + $(NULL) + +test_media_keys_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -I$(top_srcdir)/plugins/common \ + -I$(top_srcdir)/plugins/media-keys/cut-n-paste \ + -DPIXMAPDIR=\""$(pkgdatadir)"\" \ + -DGTKBUILDERDIR=\""$(pkgdatadir)"\" \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +test_media_keys_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +test_media_keys_LDADD = \ + $(top_builddir)/mate-settings-daemon/libgsd-profile.la \ + $(top_builddir)/plugins/common/libcommon.la \ + $(SETTINGS_DAEMON_LIBS) $(SETTINGS_PLUGIN_LIBS) \ + $(XF86MISC_LIBS) $(GST_LIBS) -lm $(am__append_3) +gtkbuilderdir = $(pkgdatadir) +gtkbuilder_DATA = \ + acme.ui \ + $(NULL) + +DIST_SUBDIRS = cut-n-paste +EXTRA_DIST = \ + gsd-media-keys-manager.xml \ + gsd-marshal.list \ + $(plugin_in_files) \ + $(gtkbuilder_DATA) \ + $(pixmaps_DATA) \ + touchpad-enabled-template.svg \ + touchpad-disabled-template.svg \ + $(ICON_FILES) + +CLEANFILES = \ + $(BUILT_SOURCES) \ + $(plugin_DATA) + +DISTCLEANFILES = \ + $(plugin_DATA) + +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu plugins/media-keys/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plugins/media-keys/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ + } + +uninstall-pluginLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ + done + +clean-pluginLTLIBRARIES: + -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libmedia-keys.la: $(libmedia_keys_la_OBJECTS) $(libmedia_keys_la_DEPENDENCIES) + $(libmedia_keys_la_LINK) $(am_libmedia_keys_la_rpath) $(libmedia_keys_la_OBJECTS) $(libmedia_keys_la_LIBADD) $(LIBS) + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +test-media-keys$(EXEEXT): $(test_media_keys_OBJECTS) $(test_media_keys_DEPENDENCIES) + @rm -f test-media-keys$(EXEEXT) + $(test_media_keys_LINK) $(test_media_keys_OBJECTS) $(test_media_keys_LDADD) $(LIBS) +test-media-window$(EXEEXT): $(test_media_window_OBJECTS) $(test_media_window_DEPENDENCIES) + @rm -f test-media-window$(EXEEXT) + $(test_media_window_LINK) $(test_media_window_OBJECTS) $(test_media_window_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmedia_keys_la-gsd-marshal.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmedia_keys_la-gsd-media-keys-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmedia_keys_la-gsd-media-keys-plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmedia_keys_la-gsd-media-keys-window.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_media_keys-gsd-marshal.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_media_keys-gsd-media-keys-manager.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_media_keys-gsd-media-keys-window.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_media_keys-test-media-keys.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_media_window-gsd-media-keys-window.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_media_window-test-media-window.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +libmedia_keys_la-gsd-media-keys-plugin.lo: gsd-media-keys-plugin.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmedia_keys_la_CPPFLAGS) $(CPPFLAGS) $(libmedia_keys_la_CFLAGS) $(CFLAGS) -MT libmedia_keys_la-gsd-media-keys-plugin.lo -MD -MP -MF $(DEPDIR)/libmedia_keys_la-gsd-media-keys-plugin.Tpo -c -o libmedia_keys_la-gsd-media-keys-plugin.lo `test -f 'gsd-media-keys-plugin.c' || echo '$(srcdir)/'`gsd-media-keys-plugin.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libmedia_keys_la-gsd-media-keys-plugin.Tpo $(DEPDIR)/libmedia_keys_la-gsd-media-keys-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-media-keys-plugin.c' object='libmedia_keys_la-gsd-media-keys-plugin.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmedia_keys_la_CPPFLAGS) $(CPPFLAGS) $(libmedia_keys_la_CFLAGS) $(CFLAGS) -c -o libmedia_keys_la-gsd-media-keys-plugin.lo `test -f 'gsd-media-keys-plugin.c' || echo '$(srcdir)/'`gsd-media-keys-plugin.c + +libmedia_keys_la-gsd-media-keys-manager.lo: gsd-media-keys-manager.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmedia_keys_la_CPPFLAGS) $(CPPFLAGS) $(libmedia_keys_la_CFLAGS) $(CFLAGS) -MT libmedia_keys_la-gsd-media-keys-manager.lo -MD -MP -MF $(DEPDIR)/libmedia_keys_la-gsd-media-keys-manager.Tpo -c -o libmedia_keys_la-gsd-media-keys-manager.lo `test -f 'gsd-media-keys-manager.c' || echo '$(srcdir)/'`gsd-media-keys-manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libmedia_keys_la-gsd-media-keys-manager.Tpo $(DEPDIR)/libmedia_keys_la-gsd-media-keys-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-media-keys-manager.c' object='libmedia_keys_la-gsd-media-keys-manager.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmedia_keys_la_CPPFLAGS) $(CPPFLAGS) $(libmedia_keys_la_CFLAGS) $(CFLAGS) -c -o libmedia_keys_la-gsd-media-keys-manager.lo `test -f 'gsd-media-keys-manager.c' || echo '$(srcdir)/'`gsd-media-keys-manager.c + +libmedia_keys_la-gsd-media-keys-window.lo: gsd-media-keys-window.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmedia_keys_la_CPPFLAGS) $(CPPFLAGS) $(libmedia_keys_la_CFLAGS) $(CFLAGS) -MT libmedia_keys_la-gsd-media-keys-window.lo -MD -MP -MF $(DEPDIR)/libmedia_keys_la-gsd-media-keys-window.Tpo -c -o libmedia_keys_la-gsd-media-keys-window.lo `test -f 'gsd-media-keys-window.c' || echo '$(srcdir)/'`gsd-media-keys-window.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libmedia_keys_la-gsd-media-keys-window.Tpo $(DEPDIR)/libmedia_keys_la-gsd-media-keys-window.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-media-keys-window.c' object='libmedia_keys_la-gsd-media-keys-window.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmedia_keys_la_CPPFLAGS) $(CPPFLAGS) $(libmedia_keys_la_CFLAGS) $(CFLAGS) -c -o libmedia_keys_la-gsd-media-keys-window.lo `test -f 'gsd-media-keys-window.c' || echo '$(srcdir)/'`gsd-media-keys-window.c + +libmedia_keys_la-gsd-marshal.lo: gsd-marshal.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmedia_keys_la_CPPFLAGS) $(CPPFLAGS) $(libmedia_keys_la_CFLAGS) $(CFLAGS) -MT libmedia_keys_la-gsd-marshal.lo -MD -MP -MF $(DEPDIR)/libmedia_keys_la-gsd-marshal.Tpo -c -o libmedia_keys_la-gsd-marshal.lo `test -f 'gsd-marshal.c' || echo '$(srcdir)/'`gsd-marshal.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libmedia_keys_la-gsd-marshal.Tpo $(DEPDIR)/libmedia_keys_la-gsd-marshal.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-marshal.c' object='libmedia_keys_la-gsd-marshal.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmedia_keys_la_CPPFLAGS) $(CPPFLAGS) $(libmedia_keys_la_CFLAGS) $(CFLAGS) -c -o libmedia_keys_la-gsd-marshal.lo `test -f 'gsd-marshal.c' || echo '$(srcdir)/'`gsd-marshal.c + +test_media_keys-gsd-media-keys-manager.o: gsd-media-keys-manager.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_keys_CPPFLAGS) $(CPPFLAGS) $(test_media_keys_CFLAGS) $(CFLAGS) -MT test_media_keys-gsd-media-keys-manager.o -MD -MP -MF $(DEPDIR)/test_media_keys-gsd-media-keys-manager.Tpo -c -o test_media_keys-gsd-media-keys-manager.o `test -f 'gsd-media-keys-manager.c' || echo '$(srcdir)/'`gsd-media-keys-manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_media_keys-gsd-media-keys-manager.Tpo $(DEPDIR)/test_media_keys-gsd-media-keys-manager.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-media-keys-manager.c' object='test_media_keys-gsd-media-keys-manager.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_keys_CPPFLAGS) $(CPPFLAGS) $(test_media_keys_CFLAGS) $(CFLAGS) -c -o test_media_keys-gsd-media-keys-manager.o `test -f 'gsd-media-keys-manager.c' || echo '$(srcdir)/'`gsd-media-keys-manager.c + +test_media_keys-gsd-media-keys-manager.obj: gsd-media-keys-manager.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_keys_CPPFLAGS) $(CPPFLAGS) $(test_media_keys_CFLAGS) $(CFLAGS) -MT test_media_keys-gsd-media-keys-manager.obj -MD -MP -MF $(DEPDIR)/test_media_keys-gsd-media-keys-manager.Tpo -c -o test_media_keys-gsd-media-keys-manager.obj `if test -f 'gsd-media-keys-manager.c'; then $(CYGPATH_W) 'gsd-media-keys-manager.c'; else $(CYGPATH_W) '$(srcdir)/gsd-media-keys-manager.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_media_keys-gsd-media-keys-manager.Tpo $(DEPDIR)/test_media_keys-gsd-media-keys-manager.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-media-keys-manager.c' object='test_media_keys-gsd-media-keys-manager.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_keys_CPPFLAGS) $(CPPFLAGS) $(test_media_keys_CFLAGS) $(CFLAGS) -c -o test_media_keys-gsd-media-keys-manager.obj `if test -f 'gsd-media-keys-manager.c'; then $(CYGPATH_W) 'gsd-media-keys-manager.c'; else $(CYGPATH_W) '$(srcdir)/gsd-media-keys-manager.c'; fi` + +test_media_keys-gsd-media-keys-window.o: gsd-media-keys-window.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_keys_CPPFLAGS) $(CPPFLAGS) $(test_media_keys_CFLAGS) $(CFLAGS) -MT test_media_keys-gsd-media-keys-window.o -MD -MP -MF $(DEPDIR)/test_media_keys-gsd-media-keys-window.Tpo -c -o test_media_keys-gsd-media-keys-window.o `test -f 'gsd-media-keys-window.c' || echo '$(srcdir)/'`gsd-media-keys-window.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_media_keys-gsd-media-keys-window.Tpo $(DEPDIR)/test_media_keys-gsd-media-keys-window.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-media-keys-window.c' object='test_media_keys-gsd-media-keys-window.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_keys_CPPFLAGS) $(CPPFLAGS) $(test_media_keys_CFLAGS) $(CFLAGS) -c -o test_media_keys-gsd-media-keys-window.o `test -f 'gsd-media-keys-window.c' || echo '$(srcdir)/'`gsd-media-keys-window.c + +test_media_keys-gsd-media-keys-window.obj: gsd-media-keys-window.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_keys_CPPFLAGS) $(CPPFLAGS) $(test_media_keys_CFLAGS) $(CFLAGS) -MT test_media_keys-gsd-media-keys-window.obj -MD -MP -MF $(DEPDIR)/test_media_keys-gsd-media-keys-window.Tpo -c -o test_media_keys-gsd-media-keys-window.obj `if test -f 'gsd-media-keys-window.c'; then $(CYGPATH_W) 'gsd-media-keys-window.c'; else $(CYGPATH_W) '$(srcdir)/gsd-media-keys-window.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_media_keys-gsd-media-keys-window.Tpo $(DEPDIR)/test_media_keys-gsd-media-keys-window.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-media-keys-window.c' object='test_media_keys-gsd-media-keys-window.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_keys_CPPFLAGS) $(CPPFLAGS) $(test_media_keys_CFLAGS) $(CFLAGS) -c -o test_media_keys-gsd-media-keys-window.obj `if test -f 'gsd-media-keys-window.c'; then $(CYGPATH_W) 'gsd-media-keys-window.c'; else $(CYGPATH_W) '$(srcdir)/gsd-media-keys-window.c'; fi` + +test_media_keys-test-media-keys.o: test-media-keys.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_keys_CPPFLAGS) $(CPPFLAGS) $(test_media_keys_CFLAGS) $(CFLAGS) -MT test_media_keys-test-media-keys.o -MD -MP -MF $(DEPDIR)/test_media_keys-test-media-keys.Tpo -c -o test_media_keys-test-media-keys.o `test -f 'test-media-keys.c' || echo '$(srcdir)/'`test-media-keys.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_media_keys-test-media-keys.Tpo $(DEPDIR)/test_media_keys-test-media-keys.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-media-keys.c' object='test_media_keys-test-media-keys.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_keys_CPPFLAGS) $(CPPFLAGS) $(test_media_keys_CFLAGS) $(CFLAGS) -c -o test_media_keys-test-media-keys.o `test -f 'test-media-keys.c' || echo '$(srcdir)/'`test-media-keys.c + +test_media_keys-test-media-keys.obj: test-media-keys.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_keys_CPPFLAGS) $(CPPFLAGS) $(test_media_keys_CFLAGS) $(CFLAGS) -MT test_media_keys-test-media-keys.obj -MD -MP -MF $(DEPDIR)/test_media_keys-test-media-keys.Tpo -c -o test_media_keys-test-media-keys.obj `if test -f 'test-media-keys.c'; then $(CYGPATH_W) 'test-media-keys.c'; else $(CYGPATH_W) '$(srcdir)/test-media-keys.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_media_keys-test-media-keys.Tpo $(DEPDIR)/test_media_keys-test-media-keys.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-media-keys.c' object='test_media_keys-test-media-keys.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_keys_CPPFLAGS) $(CPPFLAGS) $(test_media_keys_CFLAGS) $(CFLAGS) -c -o test_media_keys-test-media-keys.obj `if test -f 'test-media-keys.c'; then $(CYGPATH_W) 'test-media-keys.c'; else $(CYGPATH_W) '$(srcdir)/test-media-keys.c'; fi` + +test_media_keys-gsd-marshal.o: gsd-marshal.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_keys_CPPFLAGS) $(CPPFLAGS) $(test_media_keys_CFLAGS) $(CFLAGS) -MT test_media_keys-gsd-marshal.o -MD -MP -MF $(DEPDIR)/test_media_keys-gsd-marshal.Tpo -c -o test_media_keys-gsd-marshal.o `test -f 'gsd-marshal.c' || echo '$(srcdir)/'`gsd-marshal.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_media_keys-gsd-marshal.Tpo $(DEPDIR)/test_media_keys-gsd-marshal.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-marshal.c' object='test_media_keys-gsd-marshal.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_keys_CPPFLAGS) $(CPPFLAGS) $(test_media_keys_CFLAGS) $(CFLAGS) -c -o test_media_keys-gsd-marshal.o `test -f 'gsd-marshal.c' || echo '$(srcdir)/'`gsd-marshal.c + +test_media_keys-gsd-marshal.obj: gsd-marshal.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_keys_CPPFLAGS) $(CPPFLAGS) $(test_media_keys_CFLAGS) $(CFLAGS) -MT test_media_keys-gsd-marshal.obj -MD -MP -MF $(DEPDIR)/test_media_keys-gsd-marshal.Tpo -c -o test_media_keys-gsd-marshal.obj `if test -f 'gsd-marshal.c'; then $(CYGPATH_W) 'gsd-marshal.c'; else $(CYGPATH_W) '$(srcdir)/gsd-marshal.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_media_keys-gsd-marshal.Tpo $(DEPDIR)/test_media_keys-gsd-marshal.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-marshal.c' object='test_media_keys-gsd-marshal.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_keys_CPPFLAGS) $(CPPFLAGS) $(test_media_keys_CFLAGS) $(CFLAGS) -c -o test_media_keys-gsd-marshal.obj `if test -f 'gsd-marshal.c'; then $(CYGPATH_W) 'gsd-marshal.c'; else $(CYGPATH_W) '$(srcdir)/gsd-marshal.c'; fi` + +test_media_window-gsd-media-keys-window.o: gsd-media-keys-window.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_window_CPPFLAGS) $(CPPFLAGS) $(test_media_window_CFLAGS) $(CFLAGS) -MT test_media_window-gsd-media-keys-window.o -MD -MP -MF $(DEPDIR)/test_media_window-gsd-media-keys-window.Tpo -c -o test_media_window-gsd-media-keys-window.o `test -f 'gsd-media-keys-window.c' || echo '$(srcdir)/'`gsd-media-keys-window.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_media_window-gsd-media-keys-window.Tpo $(DEPDIR)/test_media_window-gsd-media-keys-window.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-media-keys-window.c' object='test_media_window-gsd-media-keys-window.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_window_CPPFLAGS) $(CPPFLAGS) $(test_media_window_CFLAGS) $(CFLAGS) -c -o test_media_window-gsd-media-keys-window.o `test -f 'gsd-media-keys-window.c' || echo '$(srcdir)/'`gsd-media-keys-window.c + +test_media_window-gsd-media-keys-window.obj: gsd-media-keys-window.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_window_CPPFLAGS) $(CPPFLAGS) $(test_media_window_CFLAGS) $(CFLAGS) -MT test_media_window-gsd-media-keys-window.obj -MD -MP -MF $(DEPDIR)/test_media_window-gsd-media-keys-window.Tpo -c -o test_media_window-gsd-media-keys-window.obj `if test -f 'gsd-media-keys-window.c'; then $(CYGPATH_W) 'gsd-media-keys-window.c'; else $(CYGPATH_W) '$(srcdir)/gsd-media-keys-window.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_media_window-gsd-media-keys-window.Tpo $(DEPDIR)/test_media_window-gsd-media-keys-window.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-media-keys-window.c' object='test_media_window-gsd-media-keys-window.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_window_CPPFLAGS) $(CPPFLAGS) $(test_media_window_CFLAGS) $(CFLAGS) -c -o test_media_window-gsd-media-keys-window.obj `if test -f 'gsd-media-keys-window.c'; then $(CYGPATH_W) 'gsd-media-keys-window.c'; else $(CYGPATH_W) '$(srcdir)/gsd-media-keys-window.c'; fi` + +test_media_window-test-media-window.o: test-media-window.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_window_CPPFLAGS) $(CPPFLAGS) $(test_media_window_CFLAGS) $(CFLAGS) -MT test_media_window-test-media-window.o -MD -MP -MF $(DEPDIR)/test_media_window-test-media-window.Tpo -c -o test_media_window-test-media-window.o `test -f 'test-media-window.c' || echo '$(srcdir)/'`test-media-window.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_media_window-test-media-window.Tpo $(DEPDIR)/test_media_window-test-media-window.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-media-window.c' object='test_media_window-test-media-window.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_window_CPPFLAGS) $(CPPFLAGS) $(test_media_window_CFLAGS) $(CFLAGS) -c -o test_media_window-test-media-window.o `test -f 'test-media-window.c' || echo '$(srcdir)/'`test-media-window.c + +test_media_window-test-media-window.obj: test-media-window.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_window_CPPFLAGS) $(CPPFLAGS) $(test_media_window_CFLAGS) $(CFLAGS) -MT test_media_window-test-media-window.obj -MD -MP -MF $(DEPDIR)/test_media_window-test-media-window.Tpo -c -o test_media_window-test-media-window.obj `if test -f 'test-media-window.c'; then $(CYGPATH_W) 'test-media-window.c'; else $(CYGPATH_W) '$(srcdir)/test-media-window.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_media_window-test-media-window.Tpo $(DEPDIR)/test_media_window-test-media-window.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-media-window.c' object='test_media_window-test-media-window.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_media_window_CPPFLAGS) $(CPPFLAGS) $(test_media_window_CFLAGS) $(CFLAGS) -c -o test_media_window-test-media-window.obj `if test -f 'test-media-window.c'; then $(CYGPATH_W) 'test-media-window.c'; else $(CYGPATH_W) '$(srcdir)/test-media-window.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-gtkbuilderDATA: $(gtkbuilder_DATA) + @$(NORMAL_INSTALL) + test -z "$(gtkbuilderdir)" || $(MKDIR_P) "$(DESTDIR)$(gtkbuilderdir)" + @list='$(gtkbuilder_DATA)'; test -n "$(gtkbuilderdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(gtkbuilderdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(gtkbuilderdir)" || exit $$?; \ + done + +uninstall-gtkbuilderDATA: + @$(NORMAL_UNINSTALL) + @list='$(gtkbuilder_DATA)'; test -n "$(gtkbuilderdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(gtkbuilderdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(gtkbuilderdir)" && rm -f $$files +install-pluginDATA: $(plugin_DATA) + @$(NORMAL_INSTALL) + test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" + @list='$(plugin_DATA)'; test -n "$(plugindir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(plugindir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(plugindir)" || exit $$?; \ + done + +uninstall-pluginDATA: + @$(NORMAL_UNINSTALL) + @list='$(plugin_DATA)'; test -n "$(plugindir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(plugindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(plugindir)" && rm -f $$files + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(gtkbuilderdir)" "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-recursive + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + clean-pluginLTLIBRARIES mostlyclean-am + +distclean: distclean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-data-local install-gtkbuilderDATA \ + install-pluginDATA install-pluginLTLIBRARIES + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-gtkbuilderDATA uninstall-local \ + uninstall-pluginDATA uninstall-pluginLTLIBRARIES + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \ + ctags-recursive install install-am install-strip \ + tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + clean-noinstPROGRAMS clean-pluginLTLIBRARIES ctags \ + ctags-recursive distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-data-local install-dvi install-dvi-am \ + install-exec install-exec-am install-gtkbuilderDATA \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am install-pluginDATA \ + install-pluginLTLIBRARIES install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-gtkbuilderDATA \ + uninstall-local uninstall-pluginDATA \ + uninstall-pluginLTLIBRARIES + + +install-data-local: + $(mkinstalldirs) $(DESTDIR)$(icondir)/16x16/$(context) + $(mkinstalldirs) $(DESTDIR)$(icondir)/22x22/$(context) + $(mkinstalldirs) $(DESTDIR)$(icondir)/24x24/$(context) + $(mkinstalldirs) $(DESTDIR)$(icondir)/32x32/$(context) + $(mkinstalldirs) $(DESTDIR)$(icondir)/scalable/$(context) + $(INSTALL_DATA) $(srcdir)/touchpad-enabled-16.png $(DESTDIR)$(icondir)/16x16/$(context)/touchpad-enabled.png + $(INSTALL_DATA) $(srcdir)/touchpad-enabled-22.png $(DESTDIR)$(icondir)/22x22/$(context)/touchpad-enabled.png + $(INSTALL_DATA) $(srcdir)/touchpad-enabled-24.png $(DESTDIR)$(icondir)/24x24/$(context)/touchpad-enabled.png + $(INSTALL_DATA) $(srcdir)/touchpad-enabled-32.png $(DESTDIR)$(icondir)/32x32/$(context)/touchpad-enabled.png + $(INSTALL_DATA) $(srcdir)/touchpad-enabled.svg $(DESTDIR)$(icondir)/scalable/$(context)/touchpad-enabled.svg + $(INSTALL_DATA) $(srcdir)/touchpad-disabled-16.png $(DESTDIR)$(icondir)/16x16/$(context)/touchpad-disabled.png + $(INSTALL_DATA) $(srcdir)/touchpad-disabled-22.png $(DESTDIR)$(icondir)/22x22/$(context)/touchpad-disabled.png + $(INSTALL_DATA) $(srcdir)/touchpad-disabled-24.png $(DESTDIR)$(icondir)/24x24/$(context)/touchpad-disabled.png + $(INSTALL_DATA) $(srcdir)/touchpad-disabled-32.png $(DESTDIR)$(icondir)/32x32/$(context)/touchpad-disabled.png + $(INSTALL_DATA) $(srcdir)/touchpad-disabled.svg $(DESTDIR)$(icondir)/scalable/$(context)/touchpad-disabled.svg + +uninstall-local: + rm -f $(DESTDIR)$(icondir)/16x16/$(context)/touchpad-enabled.png + rm -f $(DESTDIR)$(icondir)/22x22/$(context)/touchpad-enabled.png + rm -f $(DESTDIR)$(icondir)/24x24/$(context)/touchpad-enabled.png + rm -f $(DESTDIR)$(icondir)/32x32/$(context)/touchpad-enabled.png + rm -f $(DESTDIR)$(icondir)/scalable/$(context)/touchpad-enabled.svg + rm -f $(DESTDIR)$(icondir)/16x16/$(context)/touchpad-disabled.png + rm -f $(DESTDIR)$(icondir)/22x22/$(context)/touchpad-disabled.png + rm -f $(DESTDIR)$(icondir)/24x24/$(context)/touchpad-disabled.png + rm -f $(DESTDIR)$(icondir)/32x32/$(context)/touchpad-disabled.png + rm -f $(DESTDIR)$(icondir)/scalable/$(context)/touchpad-disabled.svg + +gsd-media-keys-manager-glue.h: gsd-media-keys-manager.xml Makefile + dbus-binding-tool --prefix=gsd_media_keys_manager --mode=glib-server $< > xgen-$(@F) \ + && ( cmp -s xgen-$(@F) $@ || cp xgen-$(@F) $@ ) \ + && rm -f xgen-$(@F) + +gsd-marshal.c: gsd-marshal.list + $(GLIB_GENMARSHAL) --prefix=gsd_marshal $< --header --body --internal > $@ + +gsd-marshal.h: gsd-marshal.list + $(GLIB_GENMARSHAL) --prefix=gsd_marshal $< --header --internal > $@ + +@GSD_INTLTOOL_PLUGIN_RULE@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/plugins/media-keys/acme.h b/plugins/media-keys/acme.h new file mode 100644 index 0000000..66e13bc --- /dev/null +++ b/plugins/media-keys/acme.h @@ -0,0 +1,78 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2001 Bastien Nocera + * + * 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 __ACME_H__ +#define __ACME_H__ + +#include "gsd-keygrab.h" + +#define MATECONF_BINDING_DIR "/apps/mate_settings_daemon/keybindings" +#define MATECONF_MISC_DIR "/apps/mate_settings_daemon" + +enum { + TOUCHPAD_KEY, + MUTE_KEY, + VOLUME_DOWN_KEY, + VOLUME_UP_KEY, + POWER_KEY, + EJECT_KEY, + HOME_KEY, + MEDIA_KEY, + CALCULATOR_KEY, + SEARCH_KEY, + EMAIL_KEY, + SCREENSAVER_KEY, + HELP_KEY, + WWW_KEY, + PLAY_KEY, + PAUSE_KEY, + STOP_KEY, + PREVIOUS_KEY, + NEXT_KEY, + HANDLED_KEYS +}; + +static struct { + int key_type; + const char *mateconf_key; + Key *key; +} keys[HANDLED_KEYS] = { + { TOUCHPAD_KEY, MATECONF_BINDING_DIR "/touchpad", NULL }, + { MUTE_KEY, MATECONF_BINDING_DIR "/volume_mute",NULL }, + { VOLUME_DOWN_KEY, MATECONF_BINDING_DIR "/volume_down", NULL }, + { VOLUME_UP_KEY, MATECONF_BINDING_DIR "/volume_up", NULL }, + { POWER_KEY, MATECONF_BINDING_DIR "/power", NULL }, + { EJECT_KEY, MATECONF_BINDING_DIR "/eject", NULL }, + { HOME_KEY, MATECONF_BINDING_DIR "/home", NULL }, + { MEDIA_KEY, MATECONF_BINDING_DIR "/media", NULL }, + { CALCULATOR_KEY, MATECONF_BINDING_DIR "/calculator", NULL }, + { SEARCH_KEY, MATECONF_BINDING_DIR "/search", NULL }, + { EMAIL_KEY, MATECONF_BINDING_DIR "/email", NULL }, + { SCREENSAVER_KEY, MATECONF_BINDING_DIR "/screensaver", NULL }, + { HELP_KEY, MATECONF_BINDING_DIR "/help", NULL }, + { WWW_KEY, MATECONF_BINDING_DIR "/www", NULL }, + { PLAY_KEY, MATECONF_BINDING_DIR "/play", NULL }, + { PAUSE_KEY, MATECONF_BINDING_DIR "/pause", NULL }, + { STOP_KEY, MATECONF_BINDING_DIR "/stop", NULL }, + { PREVIOUS_KEY, MATECONF_BINDING_DIR "/previous", NULL }, + { NEXT_KEY, MATECONF_BINDING_DIR "/next", NULL }, +}; + +#endif /* __ACME_H__ */ diff --git a/plugins/media-keys/acme.ui b/plugins/media-keys/acme.ui new file mode 100644 index 0000000..e0457ed --- /dev/null +++ b/plugins/media-keys/acme.ui @@ -0,0 +1,33 @@ + + + + + + + + True + 6 + + + True + audio-volume-high + 6 + + + 0 + + + + + True + + + False + False + 1 + + + + + + diff --git a/plugins/media-keys/cut-n-paste/Makefile.am b/plugins/media-keys/cut-n-paste/Makefile.am new file mode 100644 index 0000000..bc59a10 --- /dev/null +++ b/plugins/media-keys/cut-n-paste/Makefile.am @@ -0,0 +1,39 @@ +NULL = + +noinst_LTLIBRARIES = libgvc.la + +INCLUDES = \ + $(WARN_CFLAGS) \ + $(VOLUME_CONTROL_CFLAGS) \ + $(PULSE_CFLAGS) \ + $(NULL) + +libgvc_la_LIBADD = \ + $(VOLUME_CONTROL_LIBS) \ + $(PULSE_LIBS) \ + $(NULL) + +libgvc_la_SOURCES = \ + gvc-mixer-stream.h \ + gvc-mixer-stream.c \ + gvc-channel-map.h \ + gvc-channel-map.c \ + gvc-mixer-card.c \ + gvc-mixer-card.h \ + gvc-mixer-sink.h \ + gvc-mixer-sink.c \ + gvc-mixer-source.h \ + gvc-mixer-source.c \ + gvc-mixer-sink-input.h \ + gvc-mixer-sink-input.c \ + gvc-mixer-source-output.h \ + gvc-mixer-source-output.c \ + gvc-mixer-event-role.h \ + gvc-mixer-event-role.c \ + gvc-mixer-control.h \ + gvc-mixer-control.c \ + $(NULL) + +MAINTAINERCLEANFILES = \ + *~ \ + Makefile.in diff --git a/plugins/media-keys/cut-n-paste/Makefile.in b/plugins/media-keys/cut-n-paste/Makefile.in new file mode 100644 index 0000000..9fbfa1c --- /dev/null +++ b/plugins/media-keys/cut-n-paste/Makefile.in @@ -0,0 +1,586 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = plugins/media-keys/cut-n-paste +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +am__DEPENDENCIES_1 = +libgvc_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am__objects_1 = +am_libgvc_la_OBJECTS = gvc-mixer-stream.lo gvc-channel-map.lo \ + gvc-mixer-card.lo gvc-mixer-sink.lo gvc-mixer-source.lo \ + gvc-mixer-sink-input.lo gvc-mixer-source-output.lo \ + gvc-mixer-event-role.lo gvc-mixer-control.lo $(am__objects_1) +libgvc_la_OBJECTS = $(am_libgvc_la_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libgvc_la_SOURCES) +DIST_SOURCES = $(libgvc_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DBUS_SYS_DIR = @DBUS_SYS_DIR@ +DEBUG_CFLAGS = @DEBUG_CFLAGS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FONTCONFIG_CFLAGS = @FONTCONFIG_CFLAGS@ +FONTCONFIG_LIBS = @FONTCONFIG_LIBS@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIOUNIX_CFLAGS = @GIOUNIX_CFLAGS@ +GIOUNIX_LIBS = @GIOUNIX_LIBS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GREP = @GREP@ +GSD_INTLTOOL_PLUGIN_RULE = @GSD_INTLTOOL_PLUGIN_RULE@ +GSD_PLUGIN_LDFLAGS = @GSD_PLUGIN_LDFLAGS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBEXECDIR = @LIBEXECDIR@ +LIBMATEKBDUI_CFLAGS = @LIBMATEKBDUI_CFLAGS@ +LIBMATEKBDUI_LIBS = @LIBMATEKBDUI_LIBS@ +LIBMATENOTIFY_CFLAGS = @LIBMATENOTIFY_CFLAGS@ +LIBMATENOTIFY_LIBS = @LIBMATENOTIFY_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MATECONFTOOL = @MATECONFTOOL@ +MATECONF_SCHEMA_CONFIG_SOURCE = @MATECONF_SCHEMA_CONFIG_SOURCE@ +MATECONF_SCHEMA_FILE_DIR = @MATECONF_SCHEMA_FILE_DIR@ +MATE_KEYBINDINGS_KEYSDIR = @MATE_KEYBINDINGS_KEYSDIR@ +MKDIR_P = @MKDIR_P@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +MSGFMT_OPTS = @MSGFMT_OPTS@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NSS_CFLAGS = @NSS_CFLAGS@ +NSS_DATABASE = @NSS_DATABASE@ +NSS_LIBS = @NSS_LIBS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POFILES = @POFILES@ +POLKIT_CFLAGS = @POLKIT_CFLAGS@ +POLKIT_LIBS = @POLKIT_LIBS@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +PULSE_CFLAGS = @PULSE_CFLAGS@ +PULSE_LIBS = @PULSE_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SETTINGS_DAEMON_CFLAGS = @SETTINGS_DAEMON_CFLAGS@ +SETTINGS_DAEMON_LIBS = @SETTINGS_DAEMON_LIBS@ +SETTINGS_PLUGIN_CFLAGS = @SETTINGS_PLUGIN_CFLAGS@ +SETTINGS_PLUGIN_LIBS = @SETTINGS_PLUGIN_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +X11_LIBS = @X11_LIBS@ +XF86MISC_LIBS = @XF86MISC_LIBS@ +XGETTEXT = @XGETTEXT@ +XINPUT_LIBS = @XINPUT_LIBS@ +XMKMF = @XMKMF@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +plugindir = @plugindir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +NULL = +noinst_LTLIBRARIES = libgvc.la +INCLUDES = \ + $(WARN_CFLAGS) \ + $(VOLUME_CONTROL_CFLAGS) \ + $(PULSE_CFLAGS) \ + $(NULL) + +libgvc_la_LIBADD = \ + $(VOLUME_CONTROL_LIBS) \ + $(PULSE_LIBS) \ + $(NULL) + +libgvc_la_SOURCES = \ + gvc-mixer-stream.h \ + gvc-mixer-stream.c \ + gvc-channel-map.h \ + gvc-channel-map.c \ + gvc-mixer-card.c \ + gvc-mixer-card.h \ + gvc-mixer-sink.h \ + gvc-mixer-sink.c \ + gvc-mixer-source.h \ + gvc-mixer-source.c \ + gvc-mixer-sink-input.h \ + gvc-mixer-sink-input.c \ + gvc-mixer-source-output.h \ + gvc-mixer-source-output.c \ + gvc-mixer-event-role.h \ + gvc-mixer-event-role.c \ + gvc-mixer-control.h \ + gvc-mixer-control.c \ + $(NULL) + +MAINTAINERCLEANFILES = \ + *~ \ + Makefile.in + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu plugins/media-keys/cut-n-paste/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plugins/media-keys/cut-n-paste/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libgvc.la: $(libgvc_la_OBJECTS) $(libgvc_la_DEPENDENCIES) + $(LINK) $(libgvc_la_OBJECTS) $(libgvc_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gvc-channel-map.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gvc-mixer-card.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gvc-mixer-control.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gvc-mixer-event-role.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gvc-mixer-sink-input.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gvc-mixer-sink.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gvc-mixer-source-output.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gvc-mixer-source.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gvc-mixer-stream.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/plugins/media-keys/cut-n-paste/gvc-channel-map.c b/plugins/media-keys/cut-n-paste/gvc-channel-map.c new file mode 100644 index 0000000..ea3e5af --- /dev/null +++ b/plugins/media-keys/cut-n-paste/gvc-channel-map.c @@ -0,0 +1,292 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 William Jon McCann + * + * 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 +#include +#include + +#include +#include + +#include + +#include "gvc-channel-map.h" + +#define GVC_CHANNEL_MAP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_CHANNEL_MAP, GvcChannelMapPrivate)) + +#ifndef PA_CHECK_VERSION +#define PA_CHECK_VERSION(major,minor,micro) \ + ((PA_MAJOR > (major)) || \ + (PA_MAJOR == (major) && PA_MINOR > (minor)) || \ + (PA_MAJOR == (major) && PA_MINOR == (minor) && PA_MICRO >= (micro))) +#endif + + +struct GvcChannelMapPrivate +{ + pa_channel_map pa_map; + gboolean pa_volume_is_set; + pa_cvolume pa_volume; + gdouble extern_volume[NUM_TYPES]; /* volume, balance, fade, lfe */ + gboolean can_balance; + gboolean can_fade; + gboolean has_lfe; +}; + +enum { + VOLUME_CHANGED, + LAST_SIGNAL +}; + +static guint signals [LAST_SIGNAL] = { 0, }; + +static void gvc_channel_map_class_init (GvcChannelMapClass *klass); +static void gvc_channel_map_init (GvcChannelMap *channel_map); +static void gvc_channel_map_finalize (GObject *object); + +G_DEFINE_TYPE (GvcChannelMap, gvc_channel_map, G_TYPE_OBJECT) + +/* FIXME remove when we depend on a newer PA */ +static int +gvc_pa_channel_map_has_position (const pa_channel_map *map, pa_channel_position_t p) { + unsigned c; + + g_return_val_if_fail(pa_channel_map_valid(map), 0); + g_return_val_if_fail(p < PA_CHANNEL_POSITION_MAX, 0); + + for (c = 0; c < map->channels; c++) + if (map->map[c] == p) + return 1; + + return 0; +} + +#if !PA_CHECK_VERSION(0,9,16) +/* The PulseAudio master increase version only when tagged, so let's avoid clashing with pa_ namespace */ +#define pa_cvolume_get_position gvc_cvolume_get_position +static pa_volume_t +gvc_cvolume_get_position (pa_cvolume *cv, const pa_channel_map *map, pa_channel_position_t t) { + unsigned c; + pa_volume_t v = PA_VOLUME_MUTED; + + g_assert(cv); + g_assert(map); + + g_return_val_if_fail(pa_cvolume_compatible_with_channel_map(cv, map), PA_VOLUME_MUTED); + g_return_val_if_fail(t < PA_CHANNEL_POSITION_MAX, PA_VOLUME_MUTED); + + for (c = 0; c < map->channels; c++) + if (map->map[c] == t) + if (cv->values[c] > v) + v = cv->values[c]; + + return v; +} +#endif + +guint +gvc_channel_map_get_num_channels (GvcChannelMap *map) +{ + g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), 0); + + if (!pa_channel_map_valid(&map->priv->pa_map)) + return 0; + + return map->priv->pa_map.channels; +} + +const gdouble * +gvc_channel_map_get_volume (GvcChannelMap *map) +{ + g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), NULL); + + if (!pa_channel_map_valid(&map->priv->pa_map)) + return NULL; + + map->priv->extern_volume[VOLUME] = (gdouble) pa_cvolume_max (&map->priv->pa_volume); + if (gvc_channel_map_can_balance (map)) + map->priv->extern_volume[BALANCE] = (gdouble) pa_cvolume_get_balance (&map->priv->pa_volume, &map->priv->pa_map); + else + map->priv->extern_volume[BALANCE] = 0; + if (gvc_channel_map_can_fade (map)) + map->priv->extern_volume[FADE] = (gdouble) pa_cvolume_get_fade (&map->priv->pa_volume, &map->priv->pa_map); + else + map->priv->extern_volume[FADE] = 0; + if (gvc_channel_map_has_lfe (map)) + map->priv->extern_volume[LFE] = (gdouble) pa_cvolume_get_position (&map->priv->pa_volume, &map->priv->pa_map, PA_CHANNEL_POSITION_LFE); + else + map->priv->extern_volume[LFE] = 0; + + return map->priv->extern_volume; +} + +gboolean +gvc_channel_map_can_balance (GvcChannelMap *map) +{ + g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), FALSE); + + return map->priv->can_balance; +} + +gboolean +gvc_channel_map_can_fade (GvcChannelMap *map) +{ + g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), FALSE); + + return map->priv->can_fade; +} + +const char * +gvc_channel_map_get_mapping (GvcChannelMap *map) +{ + g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), NULL); + + if (!pa_channel_map_valid(&map->priv->pa_map)) + return NULL; + + return pa_channel_map_to_pretty_name (&map->priv->pa_map); +} + +gboolean +gvc_channel_map_has_lfe (GvcChannelMap *map) +{ + g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), FALSE); + + return map->priv->has_lfe; +} + +const pa_channel_map * +gvc_channel_map_get_pa_channel_map (GvcChannelMap *map) +{ + g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), NULL); + + if (!pa_channel_map_valid(&map->priv->pa_map)) + return NULL; + + return &map->priv->pa_map; +} + +const pa_cvolume * +gvc_channel_map_get_cvolume (GvcChannelMap *map) +{ + g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), NULL); + + if (!pa_channel_map_valid(&map->priv->pa_map)) + return NULL; + + return &map->priv->pa_volume; +} + +static void +gvc_channel_map_class_init (GvcChannelMapClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = gvc_channel_map_finalize; + + signals [VOLUME_CHANGED] = + g_signal_new ("volume-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GvcChannelMapClass, volume_changed), + NULL, NULL, + g_cclosure_marshal_VOID__BOOLEAN, + G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + + g_type_class_add_private (klass, sizeof (GvcChannelMapPrivate)); +} + +void +gvc_channel_map_volume_changed (GvcChannelMap *map, + const pa_cvolume *cv, + gboolean set) +{ + g_return_if_fail (GVC_IS_CHANNEL_MAP (map)); + g_return_if_fail (cv != NULL); + g_return_if_fail (pa_cvolume_compatible_with_channel_map(cv, &map->priv->pa_map)); + + if (pa_cvolume_equal(cv, &map->priv->pa_volume)) + return; + + map->priv->pa_volume = *cv; + + if (map->priv->pa_volume_is_set == FALSE) { + map->priv->pa_volume_is_set = TRUE; + return; + } + g_signal_emit (map, signals[VOLUME_CHANGED], 0, set); +} + +static void +gvc_channel_map_init (GvcChannelMap *map) +{ + map->priv = GVC_CHANNEL_MAP_GET_PRIVATE (map); + map->priv->pa_volume_is_set = FALSE; +} + +static void +gvc_channel_map_finalize (GObject *object) +{ + GvcChannelMap *channel_map; + + g_return_if_fail (object != NULL); + g_return_if_fail (GVC_IS_CHANNEL_MAP (object)); + + channel_map = GVC_CHANNEL_MAP (object); + + g_return_if_fail (channel_map->priv != NULL); + + G_OBJECT_CLASS (gvc_channel_map_parent_class)->finalize (object); +} + +GvcChannelMap * +gvc_channel_map_new (void) +{ + GObject *map; + map = g_object_new (GVC_TYPE_CHANNEL_MAP, NULL); + return GVC_CHANNEL_MAP (map); +} + +static void +set_from_pa_map (GvcChannelMap *map, + const pa_channel_map *pa_map) +{ + g_assert (pa_channel_map_valid(pa_map)); + + map->priv->can_balance = pa_channel_map_can_balance (pa_map); + map->priv->can_fade = pa_channel_map_can_fade (pa_map); + map->priv->has_lfe = gvc_pa_channel_map_has_position (pa_map, PA_CHANNEL_POSITION_LFE); + + map->priv->pa_map = *pa_map; + pa_cvolume_set(&map->priv->pa_volume, pa_map->channels, PA_VOLUME_NORM); +} + +GvcChannelMap * +gvc_channel_map_new_from_pa_channel_map (const pa_channel_map *pa_map) +{ + GObject *map; + map = g_object_new (GVC_TYPE_CHANNEL_MAP, NULL); + + set_from_pa_map (GVC_CHANNEL_MAP (map), pa_map); + + return GVC_CHANNEL_MAP (map); +} diff --git a/plugins/media-keys/cut-n-paste/gvc-channel-map.h b/plugins/media-keys/cut-n-paste/gvc-channel-map.h new file mode 100644 index 0000000..8a9fa93 --- /dev/null +++ b/plugins/media-keys/cut-n-paste/gvc-channel-map.h @@ -0,0 +1,83 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 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 __GVC_CHANNEL_MAP_H +#define __GVC_CHANNEL_MAP_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define GVC_TYPE_CHANNEL_MAP (gvc_channel_map_get_type ()) +#define GVC_CHANNEL_MAP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_CHANNEL_MAP, GvcChannelMap)) +#define GVC_CHANNEL_MAP_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_CHANNEL_MAP, GvcChannelMapClass)) +#define GVC_IS_CHANNEL_MAP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_CHANNEL_MAP)) +#define GVC_IS_CHANNEL_MAP_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_CHANNEL_MAP)) +#define GVC_CHANNEL_MAP_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_CHANNEL_MAP, GvcChannelMapClass)) + +typedef struct GvcChannelMapPrivate GvcChannelMapPrivate; + +typedef struct +{ + GObject parent; + GvcChannelMapPrivate *priv; +} GvcChannelMap; + +typedef struct +{ + GObjectClass parent_class; + void (*volume_changed) (GvcChannelMap *channel_map, gboolean set); +} GvcChannelMapClass; + +enum { + VOLUME, + BALANCE, + FADE, + LFE, +}; + +#define NUM_TYPES LFE + 1 + +GType gvc_channel_map_get_type (void); + +GvcChannelMap * gvc_channel_map_new (void); +GvcChannelMap * gvc_channel_map_new_from_pa_channel_map (const pa_channel_map *map); +guint gvc_channel_map_get_num_channels (GvcChannelMap *map); +const gdouble * gvc_channel_map_get_volume (GvcChannelMap *map); +gboolean gvc_channel_map_can_balance (GvcChannelMap *map); +gboolean gvc_channel_map_can_fade (GvcChannelMap *map); +gboolean gvc_channel_map_has_lfe (GvcChannelMap *map); + +void gvc_channel_map_volume_changed (GvcChannelMap *map, + const pa_cvolume *cv, + gboolean set); +const char * gvc_channel_map_get_mapping (GvcChannelMap *map); + +/* private */ +const pa_cvolume * gvc_channel_map_get_cvolume (GvcChannelMap *map); +const pa_channel_map * gvc_channel_map_get_pa_channel_map (GvcChannelMap *map); +#ifdef __cplusplus +} +#endif + +#endif /* __GVC_CHANNEL_MAP_H */ diff --git a/plugins/media-keys/cut-n-paste/gvc-mixer-card.c b/plugins/media-keys/cut-n-paste/gvc-mixer-card.c new file mode 100644 index 0000000..9037ff2 --- /dev/null +++ b/plugins/media-keys/cut-n-paste/gvc-mixer-card.c @@ -0,0 +1,493 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 William Jon McCann + * Copyright (C) 2009 Bastien Nocera + * + * 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 +#include +#include + +#include +#include + +#include + +#include "gvc-mixer-card.h" + +#define GVC_MIXER_CARD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_MIXER_CARD, GvcMixerCardPrivate)) + +static guint32 card_serial = 1; + +struct GvcMixerCardPrivate +{ + pa_context *pa_context; + guint id; + guint index; + char *name; + char *icon_name; + char *profile; + char *target_profile; + char *human_profile; + GList *profiles; +}; + +enum +{ + PROP_0, + PROP_ID, + PROP_PA_CONTEXT, + PROP_INDEX, + PROP_NAME, + PROP_ICON_NAME, + PROP_PROFILE, + PROP_HUMAN_PROFILE, +}; + +static void gvc_mixer_card_class_init (GvcMixerCardClass *klass); +static void gvc_mixer_card_init (GvcMixerCard *mixer_card); +static void gvc_mixer_card_finalize (GObject *object); + +G_DEFINE_TYPE (GvcMixerCard, gvc_mixer_card, G_TYPE_OBJECT) + +static guint32 +get_next_card_serial (void) +{ + guint32 serial; + + serial = card_serial++; + + if ((gint32)card_serial < 0) { + card_serial = 1; + } + + return serial; +} + +pa_context * +gvc_mixer_card_get_pa_context (GvcMixerCard *card) +{ + g_return_val_if_fail (GVC_IS_MIXER_CARD (card), 0); + return card->priv->pa_context; +} + +guint +gvc_mixer_card_get_index (GvcMixerCard *card) +{ + g_return_val_if_fail (GVC_IS_MIXER_CARD (card), 0); + return card->priv->index; +} + +guint +gvc_mixer_card_get_id (GvcMixerCard *card) +{ + g_return_val_if_fail (GVC_IS_MIXER_CARD (card), 0); + return card->priv->id; +} + +const char * +gvc_mixer_card_get_name (GvcMixerCard *card) +{ + g_return_val_if_fail (GVC_IS_MIXER_CARD (card), NULL); + return card->priv->name; +} + +gboolean +gvc_mixer_card_set_name (GvcMixerCard *card, + const char *name) +{ + g_return_val_if_fail (GVC_IS_MIXER_CARD (card), FALSE); + + g_free (card->priv->name); + card->priv->name = g_strdup (name); + g_object_notify (G_OBJECT (card), "name"); + + return TRUE; +} + +const char * +gvc_mixer_card_get_icon_name (GvcMixerCard *card) +{ + g_return_val_if_fail (GVC_IS_MIXER_CARD (card), NULL); + return card->priv->icon_name; +} + +gboolean +gvc_mixer_card_set_icon_name (GvcMixerCard *card, + const char *icon_name) +{ + g_return_val_if_fail (GVC_IS_MIXER_CARD (card), FALSE); + + g_free (card->priv->icon_name); + card->priv->icon_name = g_strdup (icon_name); + g_object_notify (G_OBJECT (card), "icon-name"); + + return TRUE; +} + +GvcMixerCardProfile * +gvc_mixer_card_get_profile (GvcMixerCard *card) +{ + GList *l; + + g_return_val_if_fail (GVC_IS_MIXER_CARD (card), NULL); + g_return_val_if_fail (card->priv->profiles != NULL, FALSE); + + for (l = card->priv->profiles; l != NULL; l = l->next) { + GvcMixerCardProfile *p = l->data; + if (g_str_equal (card->priv->profile, p->profile)) { + return p; + } + } + + g_assert_not_reached (); + + return NULL; +} + +gboolean +gvc_mixer_card_set_profile (GvcMixerCard *card, + const char *profile) +{ + GList *l; + + g_return_val_if_fail (GVC_IS_MIXER_CARD (card), FALSE); + g_return_val_if_fail (card->priv->profiles != NULL, FALSE); + + g_free (card->priv->profile); + card->priv->profile = g_strdup (profile); + + g_free (card->priv->human_profile); + card->priv->human_profile = NULL; + + for (l = card->priv->profiles; l != NULL; l = l->next) { + GvcMixerCardProfile *p = l->data; + if (g_str_equal (card->priv->profile, p->profile)) { + card->priv->human_profile = g_strdup (p->human_profile); + break; + } + } + + g_object_notify (G_OBJECT (card), "profile"); + + return TRUE; +} + +static void +_pa_context_set_card_profile_by_index_cb (pa_context *context, + int success, + void *userdata) +{ + GvcMixerCard *card = GVC_MIXER_CARD (userdata); + + g_assert (card->priv->target_profile); + + if (success > 0) { + gvc_mixer_card_set_profile (card, card->priv->target_profile); + } else { + g_debug ("Failed to switch profile on '%s' from '%s' to '%s'", + card->priv->name, + card->priv->profile, + card->priv->target_profile); + } + g_free (card->priv->target_profile); + card->priv->target_profile = NULL; +} + +gboolean +gvc_mixer_card_change_profile (GvcMixerCard *card, + const char *profile) +{ + g_return_val_if_fail (GVC_IS_MIXER_CARD (card), FALSE); + g_return_val_if_fail (card->priv->profiles != NULL, FALSE); + + /* Same profile, or already requested? */ + if (g_strcmp0 (card->priv->profile, profile) == 0) + return TRUE; + if (g_strcmp0 (profile, card->priv->target_profile) == 0) + return TRUE; + + if (card->priv->profile != NULL) { + pa_operation *o; + + g_free (card->priv->target_profile); + card->priv->target_profile = g_strdup (profile); + + o = pa_context_set_card_profile_by_index (card->priv->pa_context, + card->priv->index, + card->priv->target_profile, + _pa_context_set_card_profile_by_index_cb, + card); + + if (o == NULL) { + g_warning ("pa_context_set_card_profile_by_index() failed"); + return FALSE; + } + + pa_operation_unref (o); + } else { + g_assert (card->priv->human_profile == NULL); + card->priv->profile = g_strdup (profile); + } + + return TRUE; +} + +const GList * +gvc_mixer_card_get_profiles (GvcMixerCard *card) +{ + g_return_val_if_fail (GVC_IS_MIXER_CARD (card), FALSE); + return card->priv->profiles; +} + +static int +sort_profiles (GvcMixerCardProfile *a, + GvcMixerCardProfile *b) +{ + if (a->priority == b->priority) + return 0; + if (a->priority > b->priority) + return 1; + return -1; +} + +gboolean +gvc_mixer_card_set_profiles (GvcMixerCard *card, + GList *profiles) +{ + g_return_val_if_fail (GVC_IS_MIXER_CARD (card), FALSE); + g_return_val_if_fail (card->priv->profiles == NULL, FALSE); + + card->priv->profiles = g_list_sort (profiles, (GCompareFunc) sort_profiles); + + return TRUE; +} + +static void +gvc_mixer_card_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GvcMixerCard *self = GVC_MIXER_CARD (object); + + switch (prop_id) { + case PROP_PA_CONTEXT: + self->priv->pa_context = g_value_get_pointer (value); + break; + case PROP_INDEX: + self->priv->index = g_value_get_ulong (value); + break; + case PROP_ID: + self->priv->id = g_value_get_ulong (value); + break; + case PROP_NAME: + gvc_mixer_card_set_name (self, g_value_get_string (value)); + break; + case PROP_ICON_NAME: + gvc_mixer_card_set_icon_name (self, g_value_get_string (value)); + break; + case PROP_PROFILE: + gvc_mixer_card_set_profile (self, g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gvc_mixer_card_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GvcMixerCard *self = GVC_MIXER_CARD (object); + + switch (prop_id) { + case PROP_PA_CONTEXT: + g_value_set_pointer (value, self->priv->pa_context); + break; + case PROP_INDEX: + g_value_set_ulong (value, self->priv->index); + break; + case PROP_ID: + g_value_set_ulong (value, self->priv->id); + break; + case PROP_NAME: + g_value_set_string (value, self->priv->name); + break; + case PROP_ICON_NAME: + g_value_set_string (value, self->priv->icon_name); + break; + case PROP_PROFILE: + g_value_set_string (value, self->priv->profile); + break; + case PROP_HUMAN_PROFILE: + g_value_set_string (value, self->priv->human_profile); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +gvc_mixer_card_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_params) +{ + GObject *object; + GvcMixerCard *self; + + object = G_OBJECT_CLASS (gvc_mixer_card_parent_class)->constructor (type, n_construct_properties, construct_params); + + self = GVC_MIXER_CARD (object); + + self->priv->id = get_next_card_serial (); + + return object; +} + +static void +gvc_mixer_card_class_init (GvcMixerCardClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->constructor = gvc_mixer_card_constructor; + gobject_class->finalize = gvc_mixer_card_finalize; + + gobject_class->set_property = gvc_mixer_card_set_property; + gobject_class->get_property = gvc_mixer_card_get_property; + + g_object_class_install_property (gobject_class, + PROP_INDEX, + g_param_spec_ulong ("index", + "Index", + "The index for this card", + 0, G_MAXULONG, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (gobject_class, + PROP_ID, + g_param_spec_ulong ("id", + "id", + "The id for this card", + 0, G_MAXULONG, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (gobject_class, + PROP_PA_CONTEXT, + g_param_spec_pointer ("pa-context", + "PulseAudio context", + "The PulseAudio context for this card", + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (gobject_class, + PROP_NAME, + g_param_spec_string ("name", + "Name", + "Name to display for this card", + NULL, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); + g_object_class_install_property (gobject_class, + PROP_ICON_NAME, + g_param_spec_string ("icon-name", + "Icon Name", + "Name of icon to display for this card", + NULL, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); + g_object_class_install_property (gobject_class, + PROP_PROFILE, + g_param_spec_string ("profile", + "Profile", + "Name of current profile for this card", + NULL, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_HUMAN_PROFILE, + g_param_spec_string ("human-profile", + "Profile (Human readable)", + "Name of current profile for this card in human readable form", + NULL, + G_PARAM_READABLE)); + + g_type_class_add_private (klass, sizeof (GvcMixerCardPrivate)); +} + +static void +gvc_mixer_card_init (GvcMixerCard *card) +{ + card->priv = GVC_MIXER_CARD_GET_PRIVATE (card); +} + +GvcMixerCard * +gvc_mixer_card_new (pa_context *context, + guint index) +{ + GObject *object; + + object = g_object_new (GVC_TYPE_MIXER_CARD, + "index", index, + "pa-context", context, + NULL); + return GVC_MIXER_CARD (object); +} + +static void +free_profile (GvcMixerCardProfile *p) +{ + g_free (p->profile); + g_free (p->human_profile); + g_free (p->status); + g_free (p); +} + +static void +gvc_mixer_card_finalize (GObject *object) +{ + GvcMixerCard *mixer_card; + + g_return_if_fail (object != NULL); + g_return_if_fail (GVC_IS_MIXER_CARD (object)); + + mixer_card = GVC_MIXER_CARD (object); + + g_return_if_fail (mixer_card->priv != NULL); + + g_free (mixer_card->priv->name); + mixer_card->priv->name = NULL; + + g_free (mixer_card->priv->icon_name); + mixer_card->priv->icon_name = NULL; + + g_free (mixer_card->priv->target_profile); + mixer_card->priv->target_profile = NULL; + + g_free (mixer_card->priv->profile); + mixer_card->priv->profile = NULL; + + g_free (mixer_card->priv->human_profile); + mixer_card->priv->human_profile = NULL; + + g_list_foreach (mixer_card->priv->profiles, (GFunc) free_profile, NULL); + g_list_free (mixer_card->priv->profiles); + mixer_card->priv->profiles = NULL; + + G_OBJECT_CLASS (gvc_mixer_card_parent_class)->finalize (object); +} + diff --git a/plugins/media-keys/cut-n-paste/gvc-mixer-card.h b/plugins/media-keys/cut-n-paste/gvc-mixer-card.h new file mode 100644 index 0000000..eeaa29f --- /dev/null +++ b/plugins/media-keys/cut-n-paste/gvc-mixer-card.h @@ -0,0 +1,90 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008-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 __GVC_MIXER_CARD_H +#define __GVC_MIXER_CARD_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define GVC_TYPE_MIXER_CARD (gvc_mixer_card_get_type ()) +#define GVC_MIXER_CARD(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_MIXER_CARD, GvcMixerCard)) +#define GVC_MIXER_CARD_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_MIXER_CARD, GvcMixerCardClass)) +#define GVC_IS_MIXER_CARD(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_MIXER_CARD)) +#define GVC_IS_MIXER_CARD_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_MIXER_CARD)) +#define GVC_MIXER_CARD_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_MIXER_CARD, GvcMixerCardClass)) + +typedef struct GvcMixerCardPrivate GvcMixerCardPrivate; + +typedef struct +{ + GObject parent; + GvcMixerCardPrivate *priv; +} GvcMixerCard; + +typedef struct +{ + GObjectClass parent_class; + + /* vtable */ +} GvcMixerCardClass; + +typedef struct +{ + char *profile; + char *human_profile; + char *status; + guint priority; +} GvcMixerCardProfile; + +GType gvc_mixer_card_get_type (void); +GvcMixerCard * gvc_mixer_card_new (pa_context *context, + guint index); + +guint gvc_mixer_card_get_id (GvcMixerCard *card); +guint gvc_mixer_card_get_index (GvcMixerCard *card); +const char * gvc_mixer_card_get_name (GvcMixerCard *card); +const char * gvc_mixer_card_get_icon_name (GvcMixerCard *card); +GvcMixerCardProfile * gvc_mixer_card_get_profile (GvcMixerCard *card); +const GList * gvc_mixer_card_get_profiles (GvcMixerCard *card); + +pa_context * gvc_mixer_card_get_pa_context (GvcMixerCard *card); +gboolean gvc_mixer_card_change_profile (GvcMixerCard *card, + const char *profile); + +/* private */ +gboolean gvc_mixer_card_set_name (GvcMixerCard *card, + const char *name); +gboolean gvc_mixer_card_set_icon_name (GvcMixerCard *card, + const char *name); +gboolean gvc_mixer_card_set_profile (GvcMixerCard *card, + const char *profile); +gboolean gvc_mixer_card_set_profiles (GvcMixerCard *card, + GList *profiles); + +#ifdef __cplusplus +} +#endif + +#endif /* __GVC_MIXER_CARD_H */ diff --git a/plugins/media-keys/cut-n-paste/gvc-mixer-control.c b/plugins/media-keys/cut-n-paste/gvc-mixer-control.c new file mode 100644 index 0000000..2c8d510 --- /dev/null +++ b/plugins/media-keys/cut-n-paste/gvc-mixer-control.c @@ -0,0 +1,2123 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2006-2008 Lennart Poettering + * Copyright (C) 2008 Sjoerd Simons + * Copyright (C) 2008 William Jon McCann + * + * 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 +#include +#include + +#include +#include + +#include +#include +#include + +#include "gvc-mixer-control.h" +#include "gvc-mixer-sink.h" +#include "gvc-mixer-source.h" +#include "gvc-mixer-sink-input.h" +#include "gvc-mixer-source-output.h" +#include "gvc-mixer-event-role.h" +#include "gvc-mixer-card.h" + +#define GVC_MIXER_CONTROL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_MIXER_CONTROL, GvcMixerControlPrivate)) + +#define RECONNECT_DELAY 5 + +enum { + PROP_0, + PROP_NAME +}; + +struct GvcMixerControlPrivate +{ + pa_glib_mainloop *pa_mainloop; + pa_mainloop_api *pa_api; + pa_context *pa_context; + int n_outstanding; + guint reconnect_id; + char *name; + + gboolean default_sink_is_set; + guint default_sink_id; + char *default_sink_name; + gboolean default_source_is_set; + guint default_source_id; + char *default_source_name; + + gboolean event_sink_input_is_set; + guint event_sink_input_id; + + GHashTable *all_streams; + GHashTable *sinks; /* fixed outputs */ + GHashTable *sources; /* fixed inputs */ + GHashTable *sink_inputs; /* routable output streams */ + GHashTable *source_outputs; /* routable input streams */ + GHashTable *clients; + GHashTable *cards; + + GvcMixerStream *new_default_stream; /* new default stream, used in gvc_mixer_control_set_default_sink () */ +}; + +enum { + CONNECTING, + READY, + STREAM_ADDED, + STREAM_REMOVED, + CARD_ADDED, + CARD_REMOVED, + DEFAULT_SINK_CHANGED, + DEFAULT_SOURCE_CHANGED, + LAST_SIGNAL +}; + +static guint signals [LAST_SIGNAL] = { 0, }; + +static void gvc_mixer_control_class_init (GvcMixerControlClass *klass); +static void gvc_mixer_control_init (GvcMixerControl *mixer_control); +static void gvc_mixer_control_finalize (GObject *object); + +G_DEFINE_TYPE (GvcMixerControl, gvc_mixer_control, G_TYPE_OBJECT) + +pa_context * +gvc_mixer_control_get_pa_context (GvcMixerControl *control) +{ + g_return_val_if_fail (GVC_IS_MIXER_CONTROL (control), NULL); + return control->priv->pa_context; +} + +GvcMixerStream * +gvc_mixer_control_get_event_sink_input (GvcMixerControl *control) +{ + GvcMixerStream *stream; + + g_return_val_if_fail (GVC_IS_MIXER_CONTROL (control), NULL); + + stream = g_hash_table_lookup (control->priv->all_streams, + GUINT_TO_POINTER (control->priv->event_sink_input_id)); + + return stream; +} + +static void +gvc_mixer_control_stream_restore_cb (pa_context *c, + const pa_ext_stream_restore_info *info, + int eol, + void *userdata) +{ + pa_operation *o; + GvcMixerControl *control = (GvcMixerControl *) userdata; + pa_ext_stream_restore_info new_info; + + if (eol || control->priv->new_default_stream == NULL) + return; + + new_info.name = info->name; + new_info.channel_map = info->channel_map; + new_info.volume = info->volume; + new_info.mute = info->mute; + + new_info.device = gvc_mixer_stream_get_name (control->priv->new_default_stream); + + o = pa_ext_stream_restore_write (control->priv->pa_context, + PA_UPDATE_REPLACE, + &new_info, 1, + TRUE, NULL, NULL); + + if (o == NULL) { + g_warning ("pa_ext_stream_restore_write() failed: %s", + pa_strerror (pa_context_errno (control->priv->pa_context))); + return; + } + + g_debug ("Changed default device for %s to %s", info->name, info->device); + + pa_operation_unref (o); +} + +gboolean +gvc_mixer_control_set_default_sink (GvcMixerControl *control, + GvcMixerStream *stream) +{ + pa_operation *o; + + g_return_val_if_fail (GVC_IS_MIXER_CONTROL (control), FALSE); + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + + o = pa_context_set_default_sink (control->priv->pa_context, + gvc_mixer_stream_get_name (stream), + NULL, + NULL); + if (o == NULL) { + g_warning ("pa_context_set_default_sink() failed: %s", + pa_strerror (pa_context_errno (control->priv->pa_context))); + return FALSE; + } + + pa_operation_unref (o); + + control->priv->new_default_stream = stream; + g_object_add_weak_pointer (G_OBJECT (stream), (gpointer *) &control->priv->new_default_stream); + + o = pa_ext_stream_restore_read (control->priv->pa_context, + gvc_mixer_control_stream_restore_cb, + control); + + if (o == NULL) { + g_warning ("pa_ext_stream_restore_read() failed: %s", + pa_strerror (pa_context_errno (control->priv->pa_context))); + return FALSE; + } + + pa_operation_unref (o); + + return TRUE; +} + +gboolean +gvc_mixer_control_set_default_source (GvcMixerControl *control, + GvcMixerStream *stream) +{ + pa_operation *o; + + g_return_val_if_fail (GVC_IS_MIXER_CONTROL (control), FALSE); + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + + o = pa_context_set_default_source (control->priv->pa_context, + gvc_mixer_stream_get_name (stream), + NULL, + NULL); + if (o == NULL) { + g_warning ("pa_context_set_default_source() failed"); + return FALSE; + } + + pa_operation_unref (o); + + return TRUE; +} + +GvcMixerStream * +gvc_mixer_control_get_default_sink (GvcMixerControl *control) +{ + GvcMixerStream *stream; + + g_return_val_if_fail (GVC_IS_MIXER_CONTROL (control), NULL); + + if (control->priv->default_sink_is_set) { + stream = g_hash_table_lookup (control->priv->all_streams, + GUINT_TO_POINTER (control->priv->default_sink_id)); + } else { + stream = NULL; + } + + return stream; +} + +GvcMixerStream * +gvc_mixer_control_get_default_source (GvcMixerControl *control) +{ + GvcMixerStream *stream; + + g_return_val_if_fail (GVC_IS_MIXER_CONTROL (control), NULL); + + if (control->priv->default_source_is_set) { + stream = g_hash_table_lookup (control->priv->all_streams, + GUINT_TO_POINTER (control->priv->default_source_id)); + } else { + stream = NULL; + } + + return stream; +} + +static gpointer +gvc_mixer_control_lookup_id (GHashTable *hash_table, + guint id) +{ + return g_hash_table_lookup (hash_table, + GUINT_TO_POINTER (id)); +} + +GvcMixerStream * +gvc_mixer_control_lookup_stream_id (GvcMixerControl *control, + guint id) +{ + g_return_val_if_fail (GVC_IS_MIXER_CONTROL (control), NULL); + + return gvc_mixer_control_lookup_id (control->priv->all_streams, id); +} + +GvcMixerCard * +gvc_mixer_control_lookup_card_id (GvcMixerControl *control, + guint id) +{ + g_return_val_if_fail (GVC_IS_MIXER_CONTROL (control), NULL); + + return gvc_mixer_control_lookup_id (control->priv->cards, id); +} + +static void +listify_hash_values_hfunc (gpointer key, + gpointer value, + gpointer user_data) +{ + GSList **list = user_data; + + *list = g_slist_prepend (*list, value); +} + +static int +gvc_name_collate (const char *namea, + const char *nameb) +{ + if (nameb == NULL && namea == NULL) + return 0; + if (nameb == NULL) + return 1; + if (namea == NULL) + return -1; + + return g_utf8_collate (namea, nameb); +} + +static int +gvc_card_collate (GvcMixerCard *a, + GvcMixerCard *b) +{ + const char *namea; + const char *nameb; + + g_return_val_if_fail (a == NULL || GVC_IS_MIXER_CARD (a), 0); + g_return_val_if_fail (b == NULL || GVC_IS_MIXER_CARD (b), 0); + + namea = gvc_mixer_card_get_name (a); + nameb = gvc_mixer_card_get_name (b); + + return gvc_name_collate (namea, nameb); +} + +GSList * +gvc_mixer_control_get_cards (GvcMixerControl *control) +{ + GSList *retval; + + g_return_val_if_fail (GVC_IS_MIXER_CONTROL (control), NULL); + + retval = NULL; + g_hash_table_foreach (control->priv->cards, + listify_hash_values_hfunc, + &retval); + return g_slist_sort (retval, (GCompareFunc) gvc_card_collate); +} + +static int +gvc_stream_collate (GvcMixerStream *a, + GvcMixerStream *b) +{ + const char *namea; + const char *nameb; + + g_return_val_if_fail (a == NULL || GVC_IS_MIXER_STREAM (a), 0); + g_return_val_if_fail (b == NULL || GVC_IS_MIXER_STREAM (b), 0); + + namea = gvc_mixer_stream_get_name (a); + nameb = gvc_mixer_stream_get_name (b); + + return gvc_name_collate (namea, nameb); +} + +GSList * +gvc_mixer_control_get_streams (GvcMixerControl *control) +{ + GSList *retval; + + g_return_val_if_fail (GVC_IS_MIXER_CONTROL (control), NULL); + + retval = NULL; + g_hash_table_foreach (control->priv->all_streams, + listify_hash_values_hfunc, + &retval); + return g_slist_sort (retval, (GCompareFunc) gvc_stream_collate); +} + +GSList * +gvc_mixer_control_get_sinks (GvcMixerControl *control) +{ + GSList *retval; + + g_return_val_if_fail (GVC_IS_MIXER_CONTROL (control), NULL); + + retval = NULL; + g_hash_table_foreach (control->priv->sinks, + listify_hash_values_hfunc, + &retval); + return g_slist_sort (retval, (GCompareFunc) gvc_stream_collate); +} + +GSList * +gvc_mixer_control_get_sources (GvcMixerControl *control) +{ + GSList *retval; + + g_return_val_if_fail (GVC_IS_MIXER_CONTROL (control), NULL); + + retval = NULL; + g_hash_table_foreach (control->priv->sources, + listify_hash_values_hfunc, + &retval); + return g_slist_sort (retval, (GCompareFunc) gvc_stream_collate); +} + +GSList * +gvc_mixer_control_get_sink_inputs (GvcMixerControl *control) +{ + GSList *retval; + + g_return_val_if_fail (GVC_IS_MIXER_CONTROL (control), NULL); + + retval = NULL; + g_hash_table_foreach (control->priv->sink_inputs, + listify_hash_values_hfunc, + &retval); + return g_slist_sort (retval, (GCompareFunc) gvc_stream_collate); +} + +GSList * +gvc_mixer_control_get_source_outputs (GvcMixerControl *control) +{ + GSList *retval; + + g_return_val_if_fail (GVC_IS_MIXER_CONTROL (control), NULL); + + retval = NULL; + g_hash_table_foreach (control->priv->source_outputs, + listify_hash_values_hfunc, + &retval); + return g_slist_sort (retval, (GCompareFunc) gvc_stream_collate); +} + +static void +dec_outstanding (GvcMixerControl *control) +{ + if (control->priv->n_outstanding <= 0) { + return; + } + + if (--control->priv->n_outstanding <= 0) { + g_signal_emit (G_OBJECT (control), signals[READY], 0); + } +} + +gboolean +gvc_mixer_control_is_ready (GvcMixerControl *control) +{ + g_return_val_if_fail (GVC_IS_MIXER_CONTROL (control), FALSE); + + return (control->priv->n_outstanding == 0); +} + + +static void +_set_default_source (GvcMixerControl *control, + GvcMixerStream *stream) +{ + guint new_id; + + if (stream == NULL) { + control->priv->default_source_id = 0; + control->priv->default_source_is_set = FALSE; + return; + } + + new_id = gvc_mixer_stream_get_id (stream); + + if (control->priv->default_source_id != new_id) { + control->priv->default_source_id = new_id; + control->priv->default_source_is_set = TRUE; + g_signal_emit (control, + signals[DEFAULT_SOURCE_CHANGED], + 0, + new_id); + } +} + +static void +_set_default_sink (GvcMixerControl *control, + GvcMixerStream *stream) +{ + guint new_id; + + if (stream == NULL) { + control->priv->default_sink_id = 0; + control->priv->default_sink_is_set = FALSE; + return; + } + + new_id = gvc_mixer_stream_get_id (stream); + + if (control->priv->default_sink_id != new_id) { + control->priv->default_sink_id = new_id; + control->priv->default_sink_is_set = TRUE; + + g_signal_emit (control, + signals[DEFAULT_SINK_CHANGED], + 0, + new_id); + } +} + +static gboolean +_stream_has_name (gpointer key, + GvcMixerStream *stream, + const char *name) +{ + const char *t_name; + + t_name = gvc_mixer_stream_get_name (stream); + + if (t_name != NULL + && name != NULL + && strcmp (t_name, name) == 0) { + return TRUE; + } + + return FALSE; +} + +static GvcMixerStream * +find_stream_for_name (GvcMixerControl *control, + const char *name) +{ + GvcMixerStream *stream; + + stream = g_hash_table_find (control->priv->all_streams, + (GHRFunc)_stream_has_name, + (char *)name); + return stream; +} + +static void +update_default_source_from_name (GvcMixerControl *control, + const char *name) +{ + gboolean changed; + + if ((control->priv->default_source_name == NULL + && name != NULL) + || (control->priv->default_source_name != NULL + && name == NULL) + || strcmp (control->priv->default_source_name, name) != 0) { + changed = TRUE; + } + + if (changed) { + GvcMixerStream *stream; + + g_free (control->priv->default_source_name); + control->priv->default_source_name = g_strdup (name); + + stream = find_stream_for_name (control, name); + _set_default_source (control, stream); + } +} + +static void +update_default_sink_from_name (GvcMixerControl *control, + const char *name) +{ + gboolean changed; + + if ((control->priv->default_sink_name == NULL + && name != NULL) + || (control->priv->default_sink_name != NULL + && name == NULL) + || strcmp (control->priv->default_sink_name, name) != 0) { + changed = TRUE; + } + + if (changed) { + GvcMixerStream *stream; + g_free (control->priv->default_sink_name); + control->priv->default_sink_name = g_strdup (name); + + stream = find_stream_for_name (control, name); + _set_default_sink (control, stream); + } +} + +static void +update_server (GvcMixerControl *control, + const pa_server_info *info) +{ + if (info->default_source_name != NULL) { + update_default_source_from_name (control, info->default_source_name); + } + if (info->default_sink_name != NULL) { + update_default_sink_from_name (control, info->default_sink_name); + } +} + +static void +remove_stream (GvcMixerControl *control, + GvcMixerStream *stream) +{ + guint id; + + g_object_ref (stream); + + id = gvc_mixer_stream_get_id (stream); + + if (id == control->priv->default_sink_id) { + _set_default_sink (control, NULL); + } else if (id == control->priv->default_source_id) { + _set_default_source (control, NULL); + } + + g_hash_table_remove (control->priv->all_streams, + GUINT_TO_POINTER (id)); + g_signal_emit (G_OBJECT (control), + signals[STREAM_REMOVED], + 0, + gvc_mixer_stream_get_id (stream)); + g_object_unref (stream); +} + +static void +add_stream (GvcMixerControl *control, + GvcMixerStream *stream) +{ + g_hash_table_insert (control->priv->all_streams, + GUINT_TO_POINTER (gvc_mixer_stream_get_id (stream)), + stream); + g_signal_emit (G_OBJECT (control), + signals[STREAM_ADDED], + 0, + gvc_mixer_stream_get_id (stream)); +} + +static void +update_sink (GvcMixerControl *control, + const pa_sink_info *info) +{ + GvcMixerStream *stream; + gboolean is_new; + pa_volume_t max_volume; + GvcChannelMap *map; + char map_buff[PA_CHANNEL_MAP_SNPRINT_MAX]; + + pa_channel_map_snprint (map_buff, PA_CHANNEL_MAP_SNPRINT_MAX, &info->channel_map); +#if 1 + g_debug ("Updating sink: index=%u name='%s' description='%s' map='%s'", + info->index, + info->name, + info->description, + map_buff); +#endif + + map = NULL; + is_new = FALSE; + stream = g_hash_table_lookup (control->priv->sinks, + GUINT_TO_POINTER (info->index)); + if (stream == NULL) { +#if PA_MICRO > 15 + GList *list = NULL; + guint i; +#endif /* PA_MICRO > 15 */ + + map = gvc_channel_map_new_from_pa_channel_map (&info->channel_map); + stream = gvc_mixer_sink_new (control->priv->pa_context, + info->index, + map); +#if PA_MICRO > 15 + for (i = 0; i < info->n_ports; i++) { + GvcMixerStreamPort *port; + + port = g_new0 (GvcMixerStreamPort, 1); + port->port = g_strdup (info->ports[i]->name); + port->human_port = g_strdup (info->ports[i]->description); + port->priority = info->ports[i]->priority; + list = g_list_prepend (list, port); + } + gvc_mixer_stream_set_ports (stream, list); +#endif /* PA_MICRO > 15 */ + g_object_unref (map); + is_new = TRUE; + } else if (gvc_mixer_stream_is_running (stream)) { + /* Ignore events if volume changes are outstanding */ + g_debug ("Ignoring event, volume changes are outstanding"); + return; + } + + max_volume = pa_cvolume_max (&info->volume); + gvc_mixer_stream_set_name (stream, info->name); + gvc_mixer_stream_set_description (stream, info->description); + gvc_mixer_stream_set_icon_name (stream, "audio-card"); + gvc_mixer_stream_set_volume (stream, (guint)max_volume); + gvc_mixer_stream_set_is_muted (stream, info->mute); + gvc_mixer_stream_set_can_decibel (stream, !!(info->flags & PA_SINK_DECIBEL_VOLUME)); +#if PA_MICRO > 15 + if (info->active_port != NULL) + gvc_mixer_stream_set_port (stream, info->active_port->name); +#endif /* PA_MICRO > 15 */ + + if (is_new) { + g_hash_table_insert (control->priv->sinks, + GUINT_TO_POINTER (info->index), + g_object_ref (stream)); + add_stream (control, stream); + } + + if (control->priv->default_sink_name != NULL + && info->name != NULL + && strcmp (control->priv->default_sink_name, info->name) == 0) { + _set_default_sink (control, stream); + } + + if (map == NULL) + map = gvc_mixer_stream_get_channel_map (stream); + gvc_channel_map_volume_changed (map, &info->volume, FALSE); +} + +static void +update_source (GvcMixerControl *control, + const pa_source_info *info) +{ + GvcMixerStream *stream; + gboolean is_new; + pa_volume_t max_volume; + +#if 1 + g_debug ("Updating source: index=%u name='%s' description='%s'", + info->index, + info->name, + info->description); +#endif + + /* completely ignore monitors, they're not real sources */ + if (info->monitor_of_sink != PA_INVALID_INDEX) { + return; + } + + is_new = FALSE; + + stream = g_hash_table_lookup (control->priv->sources, + GUINT_TO_POINTER (info->index)); + if (stream == NULL) { +#if PA_MICRO > 15 + GList *list = NULL; + guint i; +#endif /* PA_MICRO > 15 */ + GvcChannelMap *map; + + map = gvc_channel_map_new_from_pa_channel_map (&info->channel_map); + stream = gvc_mixer_source_new (control->priv->pa_context, + info->index, + map); +#if PA_MICRO > 15 + for (i = 0; i < info->n_ports; i++) { + GvcMixerStreamPort *port; + + port = g_new0 (GvcMixerStreamPort, 1); + port->port = g_strdup (info->ports[i]->name); + port->human_port = g_strdup (info->ports[i]->description); + port->priority = info->ports[i]->priority; + list = g_list_prepend (list, port); + } + gvc_mixer_stream_set_ports (stream, list); +#endif /* PA_MICRO > 15 */ + + g_object_unref (map); + is_new = TRUE; + } else if (gvc_mixer_stream_is_running (stream)) { + /* Ignore events if volume changes are outstanding */ + g_debug ("Ignoring event, volume changes are outstanding"); + return; + } + + max_volume = pa_cvolume_max (&info->volume); + + gvc_mixer_stream_set_name (stream, info->name); + gvc_mixer_stream_set_description (stream, info->description); + gvc_mixer_stream_set_icon_name (stream, "audio-input-microphone"); + gvc_mixer_stream_set_volume (stream, (guint)max_volume); + gvc_mixer_stream_set_is_muted (stream, info->mute); + gvc_mixer_stream_set_can_decibel (stream, !!(info->flags & PA_SOURCE_DECIBEL_VOLUME)); + gvc_mixer_stream_set_base_volume (stream, (guint32) info->base_volume); +#if PA_MICRO > 15 + if (info->active_port != NULL) + gvc_mixer_stream_set_port (stream, info->active_port->name); +#endif /* PA_MICRO > 15 */ + + if (is_new) { + g_hash_table_insert (control->priv->sources, + GUINT_TO_POINTER (info->index), + g_object_ref (stream)); + add_stream (control, stream); + } + + if (control->priv->default_source_name != NULL + && info->name != NULL + && strcmp (control->priv->default_source_name, info->name) == 0) { + _set_default_source (control, stream); + } +} + +static void +set_icon_name_from_proplist (GvcMixerStream *stream, + pa_proplist *l, + const char *default_icon_name) +{ + const char *t; + + if ((t = pa_proplist_gets (l, PA_PROP_MEDIA_ICON_NAME))) { + goto finish; + } + + if ((t = pa_proplist_gets (l, PA_PROP_WINDOW_ICON_NAME))) { + goto finish; + } + + if ((t = pa_proplist_gets (l, PA_PROP_APPLICATION_ICON_NAME))) { + goto finish; + } + + if ((t = pa_proplist_gets (l, PA_PROP_MEDIA_ROLE))) { + + if (strcmp (t, "video") == 0 || + strcmp (t, "phone") == 0) { + goto finish; + } + + if (strcmp (t, "music") == 0) { + t = "audio"; + goto finish; + } + + if (strcmp (t, "game") == 0) { + t = "applications-games"; + goto finish; + } + + if (strcmp (t, "event") == 0) { + t = "dialog-information"; + goto finish; + } + } + + t = default_icon_name; + + finish: + gvc_mixer_stream_set_icon_name (stream, t); +} + +static void +set_is_event_stream_from_proplist (GvcMixerStream *stream, + pa_proplist *l) +{ + const char *t; + gboolean is_event_stream; + + is_event_stream = FALSE; + + if ((t = pa_proplist_gets (l, PA_PROP_MEDIA_ROLE))) { + if (g_str_equal (t, "event")) + is_event_stream = TRUE; + } + + gvc_mixer_stream_set_is_event_stream (stream, is_event_stream); +} + +static void +set_application_id_from_proplist (GvcMixerStream *stream, + pa_proplist *l) +{ + const char *t; + + if ((t = pa_proplist_gets (l, PA_PROP_APPLICATION_ID))) { + gvc_mixer_stream_set_application_id (stream, t); + } +} + +static void +update_sink_input (GvcMixerControl *control, + const pa_sink_input_info *info) +{ + GvcMixerStream *stream; + gboolean is_new; + pa_volume_t max_volume; + const char *name; + +#if 0 + g_debug ("Updating sink input: index=%u name='%s' client=%u sink=%u", + info->index, + info->name, + info->client, + info->sink); +#endif + + is_new = FALSE; + + stream = g_hash_table_lookup (control->priv->sink_inputs, + GUINT_TO_POINTER (info->index)); + if (stream == NULL) { + GvcChannelMap *map; + map = gvc_channel_map_new_from_pa_channel_map (&info->channel_map); + stream = gvc_mixer_sink_input_new (control->priv->pa_context, + info->index, + map); + g_object_unref (map); + is_new = TRUE; + } else if (gvc_mixer_stream_is_running (stream)) { + /* Ignore events if volume changes are outstanding */ + g_debug ("Ignoring event, volume changes are outstanding"); + return; + } + + max_volume = pa_cvolume_max (&info->volume); + + name = (const char *)g_hash_table_lookup (control->priv->clients, + GUINT_TO_POINTER (info->client)); + gvc_mixer_stream_set_name (stream, name); + gvc_mixer_stream_set_description (stream, info->name); + + set_application_id_from_proplist (stream, info->proplist); + set_is_event_stream_from_proplist (stream, info->proplist); + set_icon_name_from_proplist (stream, info->proplist, "applications-multimedia"); + gvc_mixer_stream_set_volume (stream, (guint)max_volume); + gvc_mixer_stream_set_is_muted (stream, info->mute); + gvc_mixer_stream_set_is_virtual (stream, info->client == PA_INVALID_INDEX); + + if (is_new) { + g_hash_table_insert (control->priv->sink_inputs, + GUINT_TO_POINTER (info->index), + g_object_ref (stream)); + add_stream (control, stream); + } +} + +static void +update_source_output (GvcMixerControl *control, + const pa_source_output_info *info) +{ + GvcMixerStream *stream; + gboolean is_new; + const char *name; + +#if 1 + g_debug ("Updating source output: index=%u name='%s' client=%u source=%u", + info->index, + info->name, + info->client, + info->source); +#endif + + is_new = FALSE; + stream = g_hash_table_lookup (control->priv->source_outputs, + GUINT_TO_POINTER (info->index)); + if (stream == NULL) { + GvcChannelMap *map; + map = gvc_channel_map_new_from_pa_channel_map (&info->channel_map); + stream = gvc_mixer_source_output_new (control->priv->pa_context, + info->index, + map); + g_object_unref (map); + is_new = TRUE; + } + + name = (const char *)g_hash_table_lookup (control->priv->clients, + GUINT_TO_POINTER (info->client)); + + gvc_mixer_stream_set_name (stream, name); + gvc_mixer_stream_set_description (stream, info->name); + set_application_id_from_proplist (stream, info->proplist); + set_is_event_stream_from_proplist (stream, info->proplist); + set_icon_name_from_proplist (stream, info->proplist, "audio-input-microphone"); + + if (is_new) { + g_hash_table_insert (control->priv->source_outputs, + GUINT_TO_POINTER (info->index), + g_object_ref (stream)); + add_stream (control, stream); + } +} + +static void +update_client (GvcMixerControl *control, + const pa_client_info *info) +{ +#if 1 + g_debug ("Updating client: index=%u name='%s'", + info->index, + info->name); +#endif + g_hash_table_insert (control->priv->clients, + GUINT_TO_POINTER (info->index), + g_strdup (info->name)); +} + +static char * +card_num_streams_to_status (guint sinks, + guint sources) +{ + char *sinks_str; + char *sources_str; + char *ret; + + if (sinks == 0 && sources == 0) { + /* translators: + * The device has been disabled */ + return g_strdup (_("Disabled")); + } + if (sinks == 0) { + sinks_str = NULL; + } else { + /* translators: + * The number of sound outputs on a particular device */ + sinks_str = g_strdup_printf (ngettext ("%u Output", + "%u Outputs", + sinks), + sinks); + } + if (sources == 0) { + sources_str = NULL; + } else { + /* translators: + * The number of sound inputs on a particular device */ + sources_str = g_strdup_printf (ngettext ("%u Input", + "%u Inputs", + sources), + sources); + } + if (sources_str == NULL) + return sinks_str; + if (sinks_str == NULL) + return sources_str; + ret = g_strdup_printf ("%s / %s", sinks_str, sources_str); + g_free (sinks_str); + g_free (sources_str); + return ret; +} + +static void +update_card (GvcMixerControl *control, + const pa_card_info *info) +{ + GvcMixerCard *card; + gboolean is_new; +#if 1 + guint i; + const char *key; + void *state; + + g_debug ("Udpating card %s (index: %u driver: %s):", + info->name, info->index, info->driver); + + for (i = 0; i < info->n_profiles; i++) { + struct pa_card_profile_info pi = info->profiles[i]; + gboolean is_default; + + is_default = (g_strcmp0 (pi.name, info->active_profile->name) == 0); + g_debug ("\tProfile '%s': %d sources %d sinks%s", + pi.name, pi.n_sources, pi.n_sinks, + is_default ? " (Current)" : ""); + } + state = NULL; + key = pa_proplist_iterate (info->proplist, &state); + while (key != NULL) { + g_debug ("\tProperty: '%s' = '%s'", + key, pa_proplist_gets (info->proplist, key)); + key = pa_proplist_iterate (info->proplist, &state); + } +#endif + card = g_hash_table_lookup (control->priv->cards, + GUINT_TO_POINTER (info->index)); + if (card == NULL) { + GList *list = NULL; + + for (i = 0; i < info->n_profiles; i++) { + struct pa_card_profile_info pi = info->profiles[i]; + GvcMixerCardProfile *profile; + + profile = g_new0 (GvcMixerCardProfile, 1); + profile->profile = g_strdup (pi.name); + profile->human_profile = g_strdup (pi.description); + profile->status = card_num_streams_to_status (pi.n_sinks, pi.n_sources); + profile->priority = pi.priority; + list = g_list_prepend (list, profile); + } + card = gvc_mixer_card_new (control->priv->pa_context, + info->index); + gvc_mixer_card_set_profiles (card, list); + is_new = TRUE; + } + + gvc_mixer_card_set_name (card, pa_proplist_gets (info->proplist, "device.description")); + gvc_mixer_card_set_icon_name (card, pa_proplist_gets (info->proplist, "device.icon_name")); + gvc_mixer_card_set_profile (card, info->active_profile->name); + + if (is_new) { + g_hash_table_insert (control->priv->cards, + GUINT_TO_POINTER (info->index), + g_object_ref (card)); + } + g_signal_emit (G_OBJECT (control), + signals[CARD_ADDED], + 0, + info->index); +} + +static void +_pa_context_get_sink_info_cb (pa_context *context, + const pa_sink_info *i, + int eol, + void *userdata) +{ + GvcMixerControl *control = GVC_MIXER_CONTROL (userdata); + + if (eol < 0) { + if (pa_context_errno (context) == PA_ERR_NOENTITY) { + return; + } + + g_warning ("Sink callback failure"); + return; + } + + if (eol > 0) { + dec_outstanding (control); + return; + } + + update_sink (control, i); +} + +static void +_pa_context_get_source_info_cb (pa_context *context, + const pa_source_info *i, + int eol, + void *userdata) +{ + GvcMixerControl *control = GVC_MIXER_CONTROL (userdata); + + if (eol < 0) { + if (pa_context_errno (context) == PA_ERR_NOENTITY) { + return; + } + + g_warning ("Source callback failure"); + return; + } + + if (eol > 0) { + dec_outstanding (control); + return; + } + + update_source (control, i); +} + +static void +_pa_context_get_sink_input_info_cb (pa_context *context, + const pa_sink_input_info *i, + int eol, + void *userdata) +{ + GvcMixerControl *control = GVC_MIXER_CONTROL (userdata); + + if (eol < 0) { + if (pa_context_errno (context) == PA_ERR_NOENTITY) { + return; + } + + g_warning ("Sink input callback failure"); + return; + } + + if (eol > 0) { + dec_outstanding (control); + return; + } + + update_sink_input (control, i); +} + +static void +_pa_context_get_source_output_info_cb (pa_context *context, + const pa_source_output_info *i, + int eol, + void *userdata) +{ + GvcMixerControl *control = GVC_MIXER_CONTROL (userdata); + + if (eol < 0) { + if (pa_context_errno (context) == PA_ERR_NOENTITY) { + return; + } + + g_warning ("Source output callback failure"); + return; + } + + if (eol > 0) { + dec_outstanding (control); + return; + } + + update_source_output (control, i); +} + +static void +_pa_context_get_client_info_cb (pa_context *context, + const pa_client_info *i, + int eol, + void *userdata) +{ + GvcMixerControl *control = GVC_MIXER_CONTROL (userdata); + + if (eol < 0) { + if (pa_context_errno (context) == PA_ERR_NOENTITY) { + return; + } + + g_warning ("Client callback failure"); + return; + } + + if (eol > 0) { + dec_outstanding (control); + return; + } + + update_client (control, i); +} + +static void +_pa_context_get_card_info_by_index_cb (pa_context *context, + const pa_card_info *i, + int eol, + void *userdata) +{ + GvcMixerControl *control = GVC_MIXER_CONTROL (userdata); + + if (eol < 0) { + if (pa_context_errno (context) == PA_ERR_NOENTITY) + return; + + g_warning ("Card callback failure"); + return; + } + + if (eol > 0) { + dec_outstanding (control); + return; + } + + update_card (control, i); +} + +static void +_pa_context_get_server_info_cb (pa_context *context, + const pa_server_info *i, + void *userdata) +{ + GvcMixerControl *control = GVC_MIXER_CONTROL (userdata); + + if (i == NULL) { + g_warning ("Server info callback failure"); + return; + } + + update_server (control, i); + dec_outstanding (control); +} + +static void +remove_event_role_stream (GvcMixerControl *control) +{ + g_debug ("Removing event role"); +} + +static void +update_event_role_stream (GvcMixerControl *control, + const pa_ext_stream_restore_info *info) +{ + GvcMixerStream *stream; + gboolean is_new; + pa_volume_t max_volume; + + if (strcmp (info->name, "sink-input-by-media-role:event") != 0) { + return; + } + +#if 0 + g_debug ("Updating event role: name='%s' device='%s'", + info->name, + info->device); +#endif + + is_new = FALSE; + + if (!control->priv->event_sink_input_is_set) { + pa_channel_map pa_map; + GvcChannelMap *map; + + pa_map.channels = 1; + pa_map.map[0] = PA_CHANNEL_POSITION_MONO; + map = gvc_channel_map_new_from_pa_channel_map (&pa_map); + + stream = gvc_mixer_event_role_new (control->priv->pa_context, + info->device, + map); + control->priv->event_sink_input_id = gvc_mixer_stream_get_id (stream); + control->priv->event_sink_input_is_set = TRUE; + + is_new = TRUE; + } else { + stream = g_hash_table_lookup (control->priv->all_streams, + GUINT_TO_POINTER (control->priv->event_sink_input_id)); + } + + max_volume = pa_cvolume_max (&info->volume); + + gvc_mixer_stream_set_name (stream, _("System Sounds")); + gvc_mixer_stream_set_icon_name (stream, "multimedia-volume-control"); + gvc_mixer_stream_set_volume (stream, (guint)max_volume); + gvc_mixer_stream_set_is_muted (stream, info->mute); + + if (is_new) { + add_stream (control, stream); + } +} + +static void +_pa_ext_stream_restore_read_cb (pa_context *context, + const pa_ext_stream_restore_info *i, + int eol, + void *userdata) +{ + GvcMixerControl *control = GVC_MIXER_CONTROL (userdata); + + if (eol < 0) { + g_debug ("Failed to initialized stream_restore extension: %s", + pa_strerror (pa_context_errno (context))); + remove_event_role_stream (control); + return; + } + + if (eol > 0) { + dec_outstanding (control); + return; + } + + update_event_role_stream (control, i); +} + +static void +_pa_ext_stream_restore_subscribe_cb (pa_context *context, + void *userdata) +{ + GvcMixerControl *control = GVC_MIXER_CONTROL (userdata); + pa_operation *o; + + o = pa_ext_stream_restore_read (context, + _pa_ext_stream_restore_read_cb, + control); + if (o == NULL) { + g_warning ("pa_ext_stream_restore_read() failed"); + return; + } + + pa_operation_unref (o); +} + +static void +req_update_server_info (GvcMixerControl *control, + int index) +{ + pa_operation *o; + + o = pa_context_get_server_info (control->priv->pa_context, + _pa_context_get_server_info_cb, + control); + if (o == NULL) { + g_warning ("pa_context_get_server_info() failed"); + return; + } + pa_operation_unref (o); +} + +static void +req_update_client_info (GvcMixerControl *control, + int index) +{ + pa_operation *o; + + if (index < 0) { + o = pa_context_get_client_info_list (control->priv->pa_context, + _pa_context_get_client_info_cb, + control); + } else { + o = pa_context_get_client_info (control->priv->pa_context, + index, + _pa_context_get_client_info_cb, + control); + } + + if (o == NULL) { + g_warning ("pa_context_client_info_list() failed"); + return; + } + pa_operation_unref (o); +} + +static void +req_update_card (GvcMixerControl *control, + int index) +{ + pa_operation *o; + + if (index < 0) { + o = pa_context_get_card_info_list (control->priv->pa_context, + _pa_context_get_card_info_by_index_cb, + control); + } else { + o = pa_context_get_card_info_by_index (control->priv->pa_context, + index, + _pa_context_get_card_info_by_index_cb, + control); + } + + if (o == NULL) { + g_warning ("pa_context_get_card_info_by_index() failed"); + return; + } + pa_operation_unref (o); +} + +static void +req_update_sink_info (GvcMixerControl *control, + int index) +{ + pa_operation *o; + + if (index < 0) { + o = pa_context_get_sink_info_list (control->priv->pa_context, + _pa_context_get_sink_info_cb, + control); + } else { + o = pa_context_get_sink_info_by_index (control->priv->pa_context, + index, + _pa_context_get_sink_info_cb, + control); + } + + if (o == NULL) { + g_warning ("pa_context_get_sink_info_list() failed"); + return; + } + pa_operation_unref (o); +} + +static void +req_update_source_info (GvcMixerControl *control, + int index) +{ + pa_operation *o; + + if (index < 0) { + o = pa_context_get_source_info_list (control->priv->pa_context, + _pa_context_get_source_info_cb, + control); + } else { + o = pa_context_get_source_info_by_index(control->priv->pa_context, + index, + _pa_context_get_source_info_cb, + control); + } + + if (o == NULL) { + g_warning ("pa_context_get_source_info_list() failed"); + return; + } + pa_operation_unref (o); +} + +static void +req_update_sink_input_info (GvcMixerControl *control, + int index) +{ + pa_operation *o; + + if (index < 0) { + o = pa_context_get_sink_input_info_list (control->priv->pa_context, + _pa_context_get_sink_input_info_cb, + control); + } else { + o = pa_context_get_sink_input_info (control->priv->pa_context, + index, + _pa_context_get_sink_input_info_cb, + control); + } + + if (o == NULL) { + g_warning ("pa_context_get_sink_input_info_list() failed"); + return; + } + pa_operation_unref (o); +} + +static void +req_update_source_output_info (GvcMixerControl *control, + int index) +{ + pa_operation *o; + + if (index < 0) { + o = pa_context_get_source_output_info_list (control->priv->pa_context, + _pa_context_get_source_output_info_cb, + control); + } else { + o = pa_context_get_source_output_info (control->priv->pa_context, + index, + _pa_context_get_source_output_info_cb, + control); + } + + if (o == NULL) { + g_warning ("pa_context_get_source_output_info_list() failed"); + return; + } + pa_operation_unref (o); +} + +static void +remove_client (GvcMixerControl *control, + guint index) +{ + g_hash_table_remove (control->priv->clients, + GUINT_TO_POINTER (index)); +} + +static void +remove_card (GvcMixerControl *control, + guint index) +{ + g_hash_table_remove (control->priv->cards, + GUINT_TO_POINTER (index)); + + g_signal_emit (G_OBJECT (control), + signals[CARD_REMOVED], + 0, + index); +} + +static void +remove_sink (GvcMixerControl *control, + guint index) +{ + GvcMixerStream *stream; + +#if 0 + g_debug ("Removing sink: index=%u", index); +#endif + + stream = g_hash_table_lookup (control->priv->sinks, + GUINT_TO_POINTER (index)); + if (stream == NULL) { + return; + } + g_hash_table_remove (control->priv->sinks, + GUINT_TO_POINTER (index)); + + remove_stream (control, stream); +} + +static void +remove_source (GvcMixerControl *control, + guint index) +{ + GvcMixerStream *stream; + +#if 0 + g_debug ("Removing source: index=%u", index); +#endif + + stream = g_hash_table_lookup (control->priv->sources, + GUINT_TO_POINTER (index)); + if (stream == NULL) { + return; + } + g_hash_table_remove (control->priv->sources, + GUINT_TO_POINTER (index)); + + remove_stream (control, stream); +} + +static void +remove_sink_input (GvcMixerControl *control, + guint index) +{ + GvcMixerStream *stream; + +#if 0 + g_debug ("Removing sink input: index=%u", index); +#endif + stream = g_hash_table_lookup (control->priv->sink_inputs, + GUINT_TO_POINTER (index)); + if (stream == NULL) { + return; + } + g_hash_table_remove (control->priv->sink_inputs, + GUINT_TO_POINTER (index)); + + remove_stream (control, stream); +} + +static void +remove_source_output (GvcMixerControl *control, + guint index) +{ + GvcMixerStream *stream; + +#if 0 + g_debug ("Removing source output: index=%u", index); +#endif + + stream = g_hash_table_lookup (control->priv->source_outputs, + GUINT_TO_POINTER (index)); + if (stream == NULL) { + return; + } + g_hash_table_remove (control->priv->source_outputs, + GUINT_TO_POINTER (index)); + + remove_stream (control, stream); +} + +static void +_pa_context_subscribe_cb (pa_context *context, + pa_subscription_event_type_t t, + uint32_t index, + void *userdata) +{ + GvcMixerControl *control = GVC_MIXER_CONTROL (userdata); + + switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) { + case PA_SUBSCRIPTION_EVENT_SINK: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { + remove_sink (control, index); + } else { + req_update_sink_info (control, index); + } + break; + + case PA_SUBSCRIPTION_EVENT_SOURCE: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { + remove_source (control, index); + } else { + req_update_source_info (control, index); + } + break; + + case PA_SUBSCRIPTION_EVENT_SINK_INPUT: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { + remove_sink_input (control, index); + } else { + req_update_sink_input_info (control, index); + } + break; + + case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { + remove_source_output (control, index); + } else { + req_update_source_output_info (control, index); + } + break; + + case PA_SUBSCRIPTION_EVENT_CLIENT: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { + remove_client (control, index); + } else { + req_update_client_info (control, index); + } + break; + + case PA_SUBSCRIPTION_EVENT_SERVER: + req_update_server_info (control, index); + break; + + case PA_SUBSCRIPTION_EVENT_CARD: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { + remove_card (control, index); + } else { + req_update_card (control, index); + } + break; + } +} + +static void +gvc_mixer_control_ready (GvcMixerControl *control) +{ + pa_operation *o; + + pa_context_set_subscribe_callback (control->priv->pa_context, + _pa_context_subscribe_cb, + control); + o = pa_context_subscribe (control->priv->pa_context, + (pa_subscription_mask_t) + (PA_SUBSCRIPTION_MASK_SINK| + PA_SUBSCRIPTION_MASK_SOURCE| + PA_SUBSCRIPTION_MASK_SINK_INPUT| + PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT| + PA_SUBSCRIPTION_MASK_CLIENT| + PA_SUBSCRIPTION_MASK_SERVER| + PA_SUBSCRIPTION_MASK_CARD), + NULL, + NULL); + + if (o == NULL) { + g_warning ("pa_context_subscribe() failed"); + return; + } + pa_operation_unref (o); + + req_update_server_info (control, -1); + req_update_client_info (control, -1); + req_update_sink_info (control, -1); + req_update_source_info (control, -1); + req_update_sink_input_info (control, -1); + req_update_source_output_info (control, -1); + req_update_card (control, -1); + + control->priv->n_outstanding = 6; + + /* This call is not always supported */ + o = pa_ext_stream_restore_read (control->priv->pa_context, + _pa_ext_stream_restore_read_cb, + control); + if (o != NULL) { + pa_operation_unref (o); + control->priv->n_outstanding++; + + pa_ext_stream_restore_set_subscribe_cb (control->priv->pa_context, + _pa_ext_stream_restore_subscribe_cb, + control); + + o = pa_ext_stream_restore_subscribe (control->priv->pa_context, + 1, + NULL, + NULL); + if (o != NULL) { + pa_operation_unref (o); + } + + } else { + g_debug ("Failed to initialized stream_restore extension: %s", + pa_strerror (pa_context_errno (control->priv->pa_context))); + } +} + +static void +gvc_mixer_new_pa_context (GvcMixerControl *self) +{ + pa_proplist *proplist; + + g_return_if_fail (self); + g_return_if_fail (!self->priv->pa_context); + + proplist = pa_proplist_new (); + pa_proplist_sets (proplist, + PA_PROP_APPLICATION_NAME, + self->priv->name); + pa_proplist_sets (proplist, + PA_PROP_APPLICATION_ID, + "org.mate.VolumeControl"); + pa_proplist_sets (proplist, + PA_PROP_APPLICATION_ICON_NAME, + "multimedia-volume-control"); + pa_proplist_sets (proplist, + PA_PROP_APPLICATION_VERSION, + PACKAGE_VERSION); + + self->priv->pa_context = pa_context_new_with_proplist (self->priv->pa_api, NULL, proplist); + + pa_proplist_free (proplist); + g_assert (self->priv->pa_context); +} + +static void +remove_all_streams (GvcMixerControl *control, GHashTable *hash_table) +{ + GHashTableIter iter; + gpointer key, value; + + g_hash_table_iter_init (&iter, hash_table); + while (g_hash_table_iter_next (&iter, &key, &value)) { + remove_stream (control, value); + g_hash_table_iter_remove (&iter); + } +} + +static gboolean +idle_reconnect (gpointer data) +{ + GvcMixerControl *control = GVC_MIXER_CONTROL (data); + GHashTableIter iter; + gpointer key, value; + + g_return_val_if_fail (control, FALSE); + + if (control->priv->pa_context) { + pa_context_unref (control->priv->pa_context); + control->priv->pa_context = NULL; + gvc_mixer_new_pa_context (control); + } + + remove_all_streams (control, control->priv->sinks); + remove_all_streams (control, control->priv->sources); + remove_all_streams (control, control->priv->sink_inputs); + remove_all_streams (control, control->priv->source_outputs); + + g_hash_table_iter_init (&iter, control->priv->clients); + while (g_hash_table_iter_next (&iter, &key, &value)) + g_hash_table_iter_remove (&iter); + + gvc_mixer_control_open (control); /* cannot fail */ + + control->priv->reconnect_id = 0; + return FALSE; +} + +static void +_pa_context_state_cb (pa_context *context, + void *userdata) +{ + GvcMixerControl *control = GVC_MIXER_CONTROL (userdata); + + switch (pa_context_get_state (context)) { + case PA_CONTEXT_UNCONNECTED: + case PA_CONTEXT_CONNECTING: + case PA_CONTEXT_AUTHORIZING: + case PA_CONTEXT_SETTING_NAME: + break; + + case PA_CONTEXT_READY: + gvc_mixer_control_ready (control); + break; + + case PA_CONTEXT_FAILED: + g_warning ("Connection failed, reconnecting..."); + if (control->priv->reconnect_id == 0) + control->priv->reconnect_id = g_timeout_add_seconds (RECONNECT_DELAY, idle_reconnect, control); + break; + + case PA_CONTEXT_TERMINATED: + default: + /* FIXME: */ + break; + } +} + +gboolean +gvc_mixer_control_open (GvcMixerControl *control) +{ + int res; + + g_return_val_if_fail (GVC_IS_MIXER_CONTROL (control), FALSE); + g_return_val_if_fail (control->priv->pa_context != NULL, FALSE); + g_return_val_if_fail (pa_context_get_state (control->priv->pa_context) == PA_CONTEXT_UNCONNECTED, FALSE); + + pa_context_set_state_callback (control->priv->pa_context, + _pa_context_state_cb, + control); + + g_signal_emit (G_OBJECT (control), signals[CONNECTING], 0); + res = pa_context_connect (control->priv->pa_context, NULL, (pa_context_flags_t) PA_CONTEXT_NOFAIL, NULL); + if (res < 0) { + g_warning ("Failed to connect context: %s", + pa_strerror (pa_context_errno (control->priv->pa_context))); + } + + return res; +} + +gboolean +gvc_mixer_control_close (GvcMixerControl *control) +{ + g_return_val_if_fail (GVC_IS_MIXER_CONTROL (control), FALSE); + g_return_val_if_fail (control->priv->pa_context != NULL, FALSE); + + pa_context_disconnect (control->priv->pa_context); + return TRUE; +} + +static void +gvc_mixer_control_dispose (GObject *object) +{ + GvcMixerControl *control = GVC_MIXER_CONTROL (object); + + if (control->priv->pa_context != NULL) { + pa_context_unref (control->priv->pa_context); + control->priv->pa_context = NULL; + } + + if (control->priv->default_source_name != NULL) { + g_free (control->priv->default_source_name); + control->priv->default_source_name = NULL; + } + if (control->priv->default_sink_name != NULL) { + g_free (control->priv->default_sink_name); + control->priv->default_sink_name = NULL; + } + + if (control->priv->pa_mainloop != NULL) { + pa_glib_mainloop_free (control->priv->pa_mainloop); + control->priv->pa_mainloop = NULL; + } + + if (control->priv->all_streams != NULL) { + g_hash_table_destroy (control->priv->all_streams); + control->priv->all_streams = NULL; + } + + if (control->priv->sinks != NULL) { + g_hash_table_destroy (control->priv->sinks); + control->priv->sinks = NULL; + } + if (control->priv->sources != NULL) { + g_hash_table_destroy (control->priv->sources); + control->priv->sources = NULL; + } + if (control->priv->sink_inputs != NULL) { + g_hash_table_destroy (control->priv->sink_inputs); + control->priv->sink_inputs = NULL; + } + if (control->priv->source_outputs != NULL) { + g_hash_table_destroy (control->priv->source_outputs); + control->priv->source_outputs = NULL; + } + if (control->priv->clients != NULL) { + g_hash_table_destroy (control->priv->clients); + control->priv->clients = NULL; + } + if (control->priv->cards != NULL) { + g_hash_table_destroy (control->priv->cards); + control->priv->cards = NULL; + } + + G_OBJECT_CLASS (gvc_mixer_control_parent_class)->dispose (object); +} + +static void +gvc_mixer_control_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GvcMixerControl *self = GVC_MIXER_CONTROL (object); + + switch (prop_id) { + case PROP_NAME: + g_free (self->priv->name); + self->priv->name = g_value_dup_string (value); + g_object_notify (G_OBJECT (self), "name"); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gvc_mixer_control_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GvcMixerControl *self = GVC_MIXER_CONTROL (object); + + switch (prop_id) { + case PROP_NAME: + g_value_set_string (value, self->priv->name); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + +static GObject * +gvc_mixer_control_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_params) +{ + GObject *object; + GvcMixerControl *self; + + object = G_OBJECT_CLASS (gvc_mixer_control_parent_class)->constructor (type, n_construct_properties, construct_params); + + self = GVC_MIXER_CONTROL (object); + + gvc_mixer_new_pa_context (self); + + return object; +} + +static void +gvc_mixer_control_class_init (GvcMixerControlClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructor = gvc_mixer_control_constructor; + object_class->dispose = gvc_mixer_control_dispose; + object_class->finalize = gvc_mixer_control_finalize; + object_class->set_property = gvc_mixer_control_set_property; + object_class->get_property = gvc_mixer_control_get_property; + + g_object_class_install_property (object_class, + PROP_NAME, + g_param_spec_string ("name", + "Name", + "Name to display for this mixer control", + NULL, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + + signals [CONNECTING] = + g_signal_new ("connecting", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GvcMixerControlClass, connecting), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + signals [READY] = + g_signal_new ("ready", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GvcMixerControlClass, ready), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + signals [STREAM_ADDED] = + g_signal_new ("stream-added", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GvcMixerControlClass, stream_added), + NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); + signals [STREAM_REMOVED] = + g_signal_new ("stream-removed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GvcMixerControlClass, stream_removed), + NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); + signals [CARD_ADDED] = + g_signal_new ("card-added", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GvcMixerControlClass, card_added), + NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); + signals [CARD_REMOVED] = + g_signal_new ("card-removed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GvcMixerControlClass, card_removed), + NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); + signals [DEFAULT_SINK_CHANGED] = + g_signal_new ("default-sink-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GvcMixerControlClass, default_sink_changed), + NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); + signals [DEFAULT_SOURCE_CHANGED] = + g_signal_new ("default-source-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GvcMixerControlClass, default_source_changed), + NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); + + g_type_class_add_private (klass, sizeof (GvcMixerControlPrivate)); +} + +static void +gvc_mixer_control_init (GvcMixerControl *control) +{ + control->priv = GVC_MIXER_CONTROL_GET_PRIVATE (control); + + control->priv->pa_mainloop = pa_glib_mainloop_new (g_main_context_default ()); + g_assert (control->priv->pa_mainloop); + + control->priv->pa_api = pa_glib_mainloop_get_api (control->priv->pa_mainloop); + g_assert (control->priv->pa_api); + + control->priv->all_streams = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)g_object_unref); + control->priv->sinks = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)g_object_unref); + control->priv->sources = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)g_object_unref); + control->priv->sink_inputs = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)g_object_unref); + control->priv->source_outputs = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)g_object_unref); + control->priv->cards = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)g_object_unref); + + control->priv->clients = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify)g_free); +} + +static void +gvc_mixer_control_finalize (GObject *object) +{ + GvcMixerControl *mixer_control; + + g_return_if_fail (object != NULL); + g_return_if_fail (GVC_IS_MIXER_CONTROL (object)); + + mixer_control = GVC_MIXER_CONTROL (object); + g_free (mixer_control->priv->name); + mixer_control->priv->name = NULL; + + g_return_if_fail (mixer_control->priv != NULL); + G_OBJECT_CLASS (gvc_mixer_control_parent_class)->finalize (object); +} + +GvcMixerControl * +gvc_mixer_control_new (const char *name) +{ + GObject *control; + control = g_object_new (GVC_TYPE_MIXER_CONTROL, + "name", name, + NULL); + return GVC_MIXER_CONTROL (control); +} diff --git a/plugins/media-keys/cut-n-paste/gvc-mixer-control.h b/plugins/media-keys/cut-n-paste/gvc-mixer-control.h new file mode 100644 index 0000000..95dc756 --- /dev/null +++ b/plugins/media-keys/cut-n-paste/gvc-mixer-control.h @@ -0,0 +1,102 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 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 __GVC_MIXER_CONTROL_H +#define __GVC_MIXER_CONTROL_H + +#include +#include +#include "gvc-mixer-stream.h" +#include "gvc-mixer-card.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GVC_TYPE_MIXER_CONTROL (gvc_mixer_control_get_type ()) +#define GVC_MIXER_CONTROL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_MIXER_CONTROL, GvcMixerControl)) +#define GVC_MIXER_CONTROL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_MIXER_CONTROL, GvcMixerControlClass)) +#define GVC_IS_MIXER_CONTROL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_MIXER_CONTROL)) +#define GVC_IS_MIXER_CONTROL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_MIXER_CONTROL)) +#define GVC_MIXER_CONTROL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_MIXER_CONTROL, GvcMixerControlClass)) + +typedef struct GvcMixerControlPrivate GvcMixerControlPrivate; + +typedef struct +{ + GObject parent; + GvcMixerControlPrivate *priv; +} GvcMixerControl; + +typedef struct +{ + GObjectClass parent_class; + + void (*connecting) (GvcMixerControl *control); + void (*ready) (GvcMixerControl *control); + void (*stream_added) (GvcMixerControl *control, + guint id); + void (*stream_removed) (GvcMixerControl *control, + guint id); + void (*card_added) (GvcMixerControl *control, + guint id); + void (*card_removed) (GvcMixerControl *control, + guint id); + void (*default_sink_changed) (GvcMixerControl *control, + guint id); + void (*default_source_changed) (GvcMixerControl *control, + guint id); +} GvcMixerControlClass; + +GType gvc_mixer_control_get_type (void); + +GvcMixerControl * gvc_mixer_control_new (const char *name); + +gboolean gvc_mixer_control_open (GvcMixerControl *control); +gboolean gvc_mixer_control_close (GvcMixerControl *control); +gboolean gvc_mixer_control_is_ready (GvcMixerControl *control); + +pa_context * gvc_mixer_control_get_pa_context (GvcMixerControl *control); +GSList * gvc_mixer_control_get_cards (GvcMixerControl *control); +GSList * gvc_mixer_control_get_streams (GvcMixerControl *control); +GSList * gvc_mixer_control_get_sinks (GvcMixerControl *control); +GSList * gvc_mixer_control_get_sources (GvcMixerControl *control); +GSList * gvc_mixer_control_get_sink_inputs (GvcMixerControl *control); +GSList * gvc_mixer_control_get_source_outputs (GvcMixerControl *control); + +GvcMixerStream * gvc_mixer_control_lookup_stream_id (GvcMixerControl *control, + guint id); +GvcMixerCard * gvc_mixer_control_lookup_card_id (GvcMixerControl *control, + guint id); + +GvcMixerStream * gvc_mixer_control_get_default_sink (GvcMixerControl *control); +GvcMixerStream * gvc_mixer_control_get_default_source (GvcMixerControl *control); +GvcMixerStream * gvc_mixer_control_get_event_sink_input (GvcMixerControl *control); + +gboolean gvc_mixer_control_set_default_sink (GvcMixerControl *control, + GvcMixerStream *stream); +gboolean gvc_mixer_control_set_default_source (GvcMixerControl *control, + GvcMixerStream *stream); + +#ifdef __cplusplus +} +#endif + +#endif /* __GVC_MIXER_CONTROL_H */ diff --git a/plugins/media-keys/cut-n-paste/gvc-mixer-event-role.c b/plugins/media-keys/cut-n-paste/gvc-mixer-event-role.c new file mode 100644 index 0000000..69e38ce --- /dev/null +++ b/plugins/media-keys/cut-n-paste/gvc-mixer-event-role.c @@ -0,0 +1,239 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 William Jon McCann + * + * 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 +#include +#include + +#include +#include + +#include +#include + +#include "gvc-mixer-event-role.h" + +#define GVC_MIXER_EVENT_ROLE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_MIXER_EVENT_ROLE, GvcMixerEventRolePrivate)) + +struct GvcMixerEventRolePrivate +{ + char *device; +}; + +enum +{ + PROP_0, + PROP_DEVICE +}; + +static void gvc_mixer_event_role_class_init (GvcMixerEventRoleClass *klass); +static void gvc_mixer_event_role_init (GvcMixerEventRole *mixer_event_role); +static void gvc_mixer_event_role_finalize (GObject *object); + +G_DEFINE_TYPE (GvcMixerEventRole, gvc_mixer_event_role, GVC_TYPE_MIXER_STREAM) + +static gboolean +update_settings (GvcMixerEventRole *role, + gboolean is_muted, + gpointer *op) +{ + pa_operation *o; + guint index; + GvcChannelMap *map; + pa_context *context; + pa_ext_stream_restore_info info; + + index = gvc_mixer_stream_get_index (GVC_MIXER_STREAM (role)); + + map = gvc_mixer_stream_get_channel_map (GVC_MIXER_STREAM(role)); + + info.volume = *gvc_channel_map_get_cvolume(map); + info.name = "sink-input-by-media-role:event"; + info.channel_map = *gvc_channel_map_get_pa_channel_map(map); + info.device = role->priv->device; + info.mute = is_muted; + + context = gvc_mixer_stream_get_pa_context (GVC_MIXER_STREAM (role)); + + o = pa_ext_stream_restore_write (context, + PA_UPDATE_REPLACE, + &info, + 1, + TRUE, + NULL, + NULL); + + if (o == NULL) { + g_warning ("pa_ext_stream_restore_write() failed"); + return FALSE; + } + + if (op != NULL) + *op = o; + + return TRUE; +} + +static gboolean +gvc_mixer_event_role_push_volume (GvcMixerStream *stream, gpointer *op) +{ + return update_settings (GVC_MIXER_EVENT_ROLE (stream), + gvc_mixer_stream_get_is_muted (stream), op); +} + +static gboolean +gvc_mixer_event_role_change_is_muted (GvcMixerStream *stream, + gboolean is_muted) +{ + return update_settings (GVC_MIXER_EVENT_ROLE (stream), + is_muted, NULL); +} + +static gboolean +gvc_mixer_event_role_set_device (GvcMixerEventRole *role, + const char *device) +{ + g_return_val_if_fail (GVC_IS_MIXER_EVENT_ROLE (role), FALSE); + + g_free (role->priv->device); + role->priv->device = g_strdup (device); + g_object_notify (G_OBJECT (role), "device"); + + return TRUE; +} + +static void +gvc_mixer_event_role_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GvcMixerEventRole *self = GVC_MIXER_EVENT_ROLE (object); + + switch (prop_id) { + case PROP_DEVICE: + gvc_mixer_event_role_set_device (self, g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gvc_mixer_event_role_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GvcMixerEventRole *self = GVC_MIXER_EVENT_ROLE (object); + + switch (prop_id) { + case PROP_DEVICE: + g_value_set_string (value, self->priv->device); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +gvc_mixer_event_role_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_params) +{ + GObject *object; + GvcMixerEventRole *self; + + object = G_OBJECT_CLASS (gvc_mixer_event_role_parent_class)->constructor (type, n_construct_properties, construct_params); + + self = GVC_MIXER_EVENT_ROLE (object); + + return object; +} + +static void +gvc_mixer_event_role_class_init (GvcMixerEventRoleClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GvcMixerStreamClass *stream_class = GVC_MIXER_STREAM_CLASS (klass); + + object_class->constructor = gvc_mixer_event_role_constructor; + object_class->finalize = gvc_mixer_event_role_finalize; + object_class->set_property = gvc_mixer_event_role_set_property; + object_class->get_property = gvc_mixer_event_role_get_property; + + stream_class->push_volume = gvc_mixer_event_role_push_volume; + stream_class->change_is_muted = gvc_mixer_event_role_change_is_muted; + + g_object_class_install_property (object_class, + PROP_DEVICE, + g_param_spec_string ("device", + "Device", + "Device", + NULL, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); + + g_type_class_add_private (klass, sizeof (GvcMixerEventRolePrivate)); +} + +static void +gvc_mixer_event_role_init (GvcMixerEventRole *event_role) +{ + event_role->priv = GVC_MIXER_EVENT_ROLE_GET_PRIVATE (event_role); + +} + +static void +gvc_mixer_event_role_finalize (GObject *object) +{ + GvcMixerEventRole *mixer_event_role; + + g_return_if_fail (object != NULL); + g_return_if_fail (GVC_IS_MIXER_EVENT_ROLE (object)); + + mixer_event_role = GVC_MIXER_EVENT_ROLE (object); + + g_return_if_fail (mixer_event_role->priv != NULL); + + g_free (mixer_event_role->priv->device); + + G_OBJECT_CLASS (gvc_mixer_event_role_parent_class)->finalize (object); +} + +GvcMixerStream * +gvc_mixer_event_role_new (pa_context *context, + const char *device, + GvcChannelMap *channel_map) +{ + GObject *object; + + object = g_object_new (GVC_TYPE_MIXER_EVENT_ROLE, + "pa-context", context, + "index", 0, + "device", device, + "channel-map", channel_map, + NULL); + + return GVC_MIXER_STREAM (object); +} diff --git a/plugins/media-keys/cut-n-paste/gvc-mixer-event-role.h b/plugins/media-keys/cut-n-paste/gvc-mixer-event-role.h new file mode 100644 index 0000000..ee91fa8 --- /dev/null +++ b/plugins/media-keys/cut-n-paste/gvc-mixer-event-role.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 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 __GVC_MIXER_EVENT_ROLE_H +#define __GVC_MIXER_EVENT_ROLE_H + +#include +#include "gvc-mixer-stream.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GVC_TYPE_MIXER_EVENT_ROLE (gvc_mixer_event_role_get_type ()) +#define GVC_MIXER_EVENT_ROLE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_MIXER_EVENT_ROLE, GvcMixerEventRole)) +#define GVC_MIXER_EVENT_ROLE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_MIXER_EVENT_ROLE, GvcMixerEventRoleClass)) +#define GVC_IS_MIXER_EVENT_ROLE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_MIXER_EVENT_ROLE)) +#define GVC_IS_MIXER_EVENT_ROLE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_MIXER_EVENT_ROLE)) +#define GVC_MIXER_EVENT_ROLE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_MIXER_EVENT_ROLE, GvcMixerEventRoleClass)) + +typedef struct GvcMixerEventRolePrivate GvcMixerEventRolePrivate; + +typedef struct +{ + GvcMixerStream parent; + GvcMixerEventRolePrivate *priv; +} GvcMixerEventRole; + +typedef struct +{ + GvcMixerStreamClass parent_class; +} GvcMixerEventRoleClass; + +GType gvc_mixer_event_role_get_type (void); + +GvcMixerStream * gvc_mixer_event_role_new (pa_context *context, + const char *device, + GvcChannelMap *channel_map); + +#ifdef __cplusplus +} +#endif + +#endif /* __GVC_MIXER_EVENT_ROLE_H */ diff --git a/plugins/media-keys/cut-n-paste/gvc-mixer-sink-input.c b/plugins/media-keys/cut-n-paste/gvc-mixer-sink-input.c new file mode 100644 index 0000000..35551bb --- /dev/null +++ b/plugins/media-keys/cut-n-paste/gvc-mixer-sink-input.c @@ -0,0 +1,188 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 William Jon McCann + * + * 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 +#include +#include + +#include +#include + +#include + +#include "gvc-mixer-sink-input.h" + +#define GVC_MIXER_SINK_INPUT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_MIXER_SINK_INPUT, GvcMixerSinkInputPrivate)) + +struct GvcMixerSinkInputPrivate +{ + gpointer dummy; +}; + +static void gvc_mixer_sink_input_class_init (GvcMixerSinkInputClass *klass); +static void gvc_mixer_sink_input_init (GvcMixerSinkInput *mixer_sink_input); +static void gvc_mixer_sink_input_finalize (GObject *object); +static void gvc_mixer_sink_input_dispose (GObject *object); + +G_DEFINE_TYPE (GvcMixerSinkInput, gvc_mixer_sink_input, GVC_TYPE_MIXER_STREAM) + +static gboolean +gvc_mixer_sink_input_push_volume (GvcMixerStream *stream, gpointer *op) +{ + pa_operation *o; + guint index; + GvcChannelMap *map; + pa_context *context; + const pa_cvolume *cv; + guint num_channels; + + index = gvc_mixer_stream_get_index (stream); + + map = gvc_mixer_stream_get_channel_map (stream); + num_channels = gvc_channel_map_get_num_channels (map); + + cv = gvc_channel_map_get_cvolume(map); + + context = gvc_mixer_stream_get_pa_context (stream); + + o = pa_context_set_sink_input_volume (context, + index, + cv, + NULL, + NULL); + + if (o == NULL) { + g_warning ("pa_context_set_sink_input_volume() failed"); + return FALSE; + } + + *op = o; + + return TRUE; +} + +static gboolean +gvc_mixer_sink_input_change_is_muted (GvcMixerStream *stream, + gboolean is_muted) +{ + pa_operation *o; + guint index; + pa_context *context; + + index = gvc_mixer_stream_get_index (stream); + context = gvc_mixer_stream_get_pa_context (stream); + + o = pa_context_set_sink_input_mute (context, + index, + is_muted, + NULL, + NULL); + + if (o == NULL) { + g_warning ("pa_context_set_sink_input_mute_by_index() failed"); + return FALSE; + } + + pa_operation_unref(o); + + return TRUE; +} + +static GObject * +gvc_mixer_sink_input_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_params) +{ + GObject *object; + GvcMixerSinkInput *self; + + object = G_OBJECT_CLASS (gvc_mixer_sink_input_parent_class)->constructor (type, n_construct_properties, construct_params); + + self = GVC_MIXER_SINK_INPUT (object); + + return object; +} + +static void +gvc_mixer_sink_input_class_init (GvcMixerSinkInputClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GvcMixerStreamClass *stream_class = GVC_MIXER_STREAM_CLASS (klass); + + object_class->constructor = gvc_mixer_sink_input_constructor; + object_class->dispose = gvc_mixer_sink_input_dispose; + object_class->finalize = gvc_mixer_sink_input_finalize; + + stream_class->push_volume = gvc_mixer_sink_input_push_volume; + stream_class->change_is_muted = gvc_mixer_sink_input_change_is_muted; + + g_type_class_add_private (klass, sizeof (GvcMixerSinkInputPrivate)); +} + +static void +gvc_mixer_sink_input_init (GvcMixerSinkInput *sink_input) +{ + sink_input->priv = GVC_MIXER_SINK_INPUT_GET_PRIVATE (sink_input); +} + +static void +gvc_mixer_sink_input_dispose (GObject *object) +{ + GvcMixerSinkInput *mixer_sink_input; + + g_return_if_fail (object != NULL); + g_return_if_fail (GVC_IS_MIXER_SINK_INPUT (object)); + + mixer_sink_input = GVC_MIXER_SINK_INPUT (object); + + G_OBJECT_CLASS (gvc_mixer_sink_input_parent_class)->dispose (object); +} + +static void +gvc_mixer_sink_input_finalize (GObject *object) +{ + GvcMixerSinkInput *mixer_sink_input; + + g_return_if_fail (object != NULL); + g_return_if_fail (GVC_IS_MIXER_SINK_INPUT (object)); + + mixer_sink_input = GVC_MIXER_SINK_INPUT (object); + + g_return_if_fail (mixer_sink_input->priv != NULL); + G_OBJECT_CLASS (gvc_mixer_sink_input_parent_class)->finalize (object); +} + +GvcMixerStream * +gvc_mixer_sink_input_new (pa_context *context, + guint index, + GvcChannelMap *channel_map) +{ + GObject *object; + + object = g_object_new (GVC_TYPE_MIXER_SINK_INPUT, + "pa-context", context, + "index", index, + "channel-map", channel_map, + NULL); + + return GVC_MIXER_STREAM (object); +} diff --git a/plugins/media-keys/cut-n-paste/gvc-mixer-sink-input.h b/plugins/media-keys/cut-n-paste/gvc-mixer-sink-input.h new file mode 100644 index 0000000..6e44811 --- /dev/null +++ b/plugins/media-keys/cut-n-paste/gvc-mixer-sink-input.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 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 __GVC_MIXER_SINK_INPUT_H +#define __GVC_MIXER_SINK_INPUT_H + +#include +#include "gvc-mixer-stream.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GVC_TYPE_MIXER_SINK_INPUT (gvc_mixer_sink_input_get_type ()) +#define GVC_MIXER_SINK_INPUT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_MIXER_SINK_INPUT, GvcMixerSinkInput)) +#define GVC_MIXER_SINK_INPUT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_MIXER_SINK_INPUT, GvcMixerSinkInputClass)) +#define GVC_IS_MIXER_SINK_INPUT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_MIXER_SINK_INPUT)) +#define GVC_IS_MIXER_SINK_INPUT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_MIXER_SINK_INPUT)) +#define GVC_MIXER_SINK_INPUT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_MIXER_SINK_INPUT, GvcMixerSinkInputClass)) + +typedef struct GvcMixerSinkInputPrivate GvcMixerSinkInputPrivate; + +typedef struct +{ + GvcMixerStream parent; + GvcMixerSinkInputPrivate *priv; +} GvcMixerSinkInput; + +typedef struct +{ + GvcMixerStreamClass parent_class; +} GvcMixerSinkInputClass; + +GType gvc_mixer_sink_input_get_type (void); + +GvcMixerStream * gvc_mixer_sink_input_new (pa_context *context, + guint index, + GvcChannelMap *map); + +#ifdef __cplusplus +} +#endif + +#endif /* __GVC_MIXER_SINK_INPUT_H */ diff --git a/plugins/media-keys/cut-n-paste/gvc-mixer-sink.c b/plugins/media-keys/cut-n-paste/gvc-mixer-sink.c new file mode 100644 index 0000000..5e95f63 --- /dev/null +++ b/plugins/media-keys/cut-n-paste/gvc-mixer-sink.c @@ -0,0 +1,220 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 William Jon McCann + * + * 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 +#include +#include + +#include +#include + +#include + +#include "gvc-mixer-sink.h" + +#define GVC_MIXER_SINK_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_MIXER_SINK, GvcMixerSinkPrivate)) + +struct GvcMixerSinkPrivate +{ + gpointer dummy; +}; + +static void gvc_mixer_sink_class_init (GvcMixerSinkClass *klass); +static void gvc_mixer_sink_init (GvcMixerSink *mixer_sink); +static void gvc_mixer_sink_finalize (GObject *object); +static void gvc_mixer_sink_dispose (GObject *object); + +G_DEFINE_TYPE (GvcMixerSink, gvc_mixer_sink, GVC_TYPE_MIXER_STREAM) + +static gboolean +gvc_mixer_sink_push_volume (GvcMixerStream *stream, gpointer *op) +{ + pa_operation *o; + guint index; + GvcChannelMap *map; + pa_context *context; + const pa_cvolume *cv; + + index = gvc_mixer_stream_get_index (stream); + + map = gvc_mixer_stream_get_channel_map (stream); + + /* set the volume */ + cv = gvc_channel_map_get_cvolume(map); + + context = gvc_mixer_stream_get_pa_context (stream); + + o = pa_context_set_sink_volume_by_index (context, + index, + cv, + NULL, + NULL); + + if (o == NULL) { + g_warning ("pa_context_set_sink_volume_by_index() failed: %s", pa_strerror(pa_context_errno(context))); + return FALSE; + } + + *op = o; + + return TRUE; +} + +static gboolean +gvc_mixer_sink_change_is_muted (GvcMixerStream *stream, + gboolean is_muted) +{ + pa_operation *o; + guint index; + pa_context *context; + + index = gvc_mixer_stream_get_index (stream); + context = gvc_mixer_stream_get_pa_context (stream); + + o = pa_context_set_sink_mute_by_index (context, + index, + is_muted, + NULL, + NULL); + + if (o == NULL) { + g_warning ("pa_context_set_sink_mute_by_index() failed: %s", pa_strerror(pa_context_errno(context))); + return FALSE; + } + + pa_operation_unref(o); + + return TRUE; +} + +static gboolean +gvc_mixer_sink_change_port (GvcMixerStream *stream, + const char *port) +{ +#if PA_MICRO > 15 + pa_operation *o; + guint index; + pa_context *context; + + index = gvc_mixer_stream_get_index (stream); + context = gvc_mixer_stream_get_pa_context (stream); + + o = pa_context_set_sink_port_by_index (context, + index, + port, + NULL, + NULL); + + if (o == NULL) { + g_warning ("pa_context_set_sink_port_by_index() failed: %s", pa_strerror(pa_context_errno(context))); + return FALSE; + } + + pa_operation_unref(o); + + return TRUE; +#else + return FALSE; +#endif /* PA_MICRO > 15 */ +} + +static GObject * +gvc_mixer_sink_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_params) +{ + GObject *object; + GvcMixerSink *self; + + object = G_OBJECT_CLASS (gvc_mixer_sink_parent_class)->constructor (type, n_construct_properties, construct_params); + + self = GVC_MIXER_SINK (object); + + return object; +} + +static void +gvc_mixer_sink_class_init (GvcMixerSinkClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GvcMixerStreamClass *stream_class = GVC_MIXER_STREAM_CLASS (klass); + + object_class->constructor = gvc_mixer_sink_constructor; + object_class->dispose = gvc_mixer_sink_dispose; + object_class->finalize = gvc_mixer_sink_finalize; + + stream_class->push_volume = gvc_mixer_sink_push_volume; + stream_class->change_port = gvc_mixer_sink_change_port; + stream_class->change_is_muted = gvc_mixer_sink_change_is_muted; + + g_type_class_add_private (klass, sizeof (GvcMixerSinkPrivate)); +} + +static void +gvc_mixer_sink_init (GvcMixerSink *sink) +{ + sink->priv = GVC_MIXER_SINK_GET_PRIVATE (sink); +} + +static void +gvc_mixer_sink_dispose (GObject *object) +{ + GvcMixerSink *mixer_sink; + + g_return_if_fail (object != NULL); + g_return_if_fail (GVC_IS_MIXER_SINK (object)); + + mixer_sink = GVC_MIXER_SINK (object); + + G_OBJECT_CLASS (gvc_mixer_sink_parent_class)->dispose (object); +} + +static void +gvc_mixer_sink_finalize (GObject *object) +{ + GvcMixerSink *mixer_sink; + + g_return_if_fail (object != NULL); + g_return_if_fail (GVC_IS_MIXER_SINK (object)); + + mixer_sink = GVC_MIXER_SINK (object); + + g_return_if_fail (mixer_sink->priv != NULL); + G_OBJECT_CLASS (gvc_mixer_sink_parent_class)->finalize (object); +} + +GvcMixerStream * +gvc_mixer_sink_new (pa_context *context, + guint index, + GvcChannelMap *channel_map) + +{ + GObject *object; + + object = g_object_new (GVC_TYPE_MIXER_SINK, + "pa-context", context, + "index", index, + "channel-map", channel_map, + NULL); + + return GVC_MIXER_STREAM (object); +} diff --git a/plugins/media-keys/cut-n-paste/gvc-mixer-sink.h b/plugins/media-keys/cut-n-paste/gvc-mixer-sink.h new file mode 100644 index 0000000..1e457dc --- /dev/null +++ b/plugins/media-keys/cut-n-paste/gvc-mixer-sink.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 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 __GVC_MIXER_SINK_H +#define __GVC_MIXER_SINK_H + +#include +#include "gvc-mixer-stream.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GVC_TYPE_MIXER_SINK (gvc_mixer_sink_get_type ()) +#define GVC_MIXER_SINK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_MIXER_SINK, GvcMixerSink)) +#define GVC_MIXER_SINK_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_MIXER_SINK, GvcMixerSinkClass)) +#define GVC_IS_MIXER_SINK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_MIXER_SINK)) +#define GVC_IS_MIXER_SINK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_MIXER_SINK)) +#define GVC_MIXER_SINK_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_MIXER_SINK, GvcMixerSinkClass)) + +typedef struct GvcMixerSinkPrivate GvcMixerSinkPrivate; + +typedef struct +{ + GvcMixerStream parent; + GvcMixerSinkPrivate *priv; +} GvcMixerSink; + +typedef struct +{ + GvcMixerStreamClass parent_class; +} GvcMixerSinkClass; + +GType gvc_mixer_sink_get_type (void); + +GvcMixerStream * gvc_mixer_sink_new (pa_context *context, + guint index, + GvcChannelMap *map); + +#ifdef __cplusplus +} +#endif + +#endif /* __GVC_MIXER_SINK_H */ diff --git a/plugins/media-keys/cut-n-paste/gvc-mixer-source-output.c b/plugins/media-keys/cut-n-paste/gvc-mixer-source-output.c new file mode 100644 index 0000000..b4cc34d --- /dev/null +++ b/plugins/media-keys/cut-n-paste/gvc-mixer-source-output.c @@ -0,0 +1,128 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 William Jon McCann + * + * 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 +#include +#include + +#include +#include + +#include + +#include "gvc-mixer-source-output.h" + +#define GVC_MIXER_SOURCE_OUTPUT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_MIXER_SOURCE_OUTPUT, GvcMixerSourceOutputPrivate)) + +struct GvcMixerSourceOutputPrivate +{ + gpointer dummy; +}; + +static void gvc_mixer_source_output_class_init (GvcMixerSourceOutputClass *klass); +static void gvc_mixer_source_output_init (GvcMixerSourceOutput *mixer_source_output); +static void gvc_mixer_source_output_finalize (GObject *object); + +G_DEFINE_TYPE (GvcMixerSourceOutput, gvc_mixer_source_output, GVC_TYPE_MIXER_STREAM) + +static gboolean +gvc_mixer_source_output_push_volume (GvcMixerStream *stream, gpointer *op) +{ + /* FIXME: */ + *op = NULL; + return TRUE; +} + +static gboolean +gvc_mixer_source_output_change_is_muted (GvcMixerStream *stream, + gboolean is_muted) +{ + /* FIXME: */ + return TRUE; +} + +static GObject * +gvc_mixer_source_output_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_params) +{ + GObject *object; + GvcMixerSourceOutput *self; + + object = G_OBJECT_CLASS (gvc_mixer_source_output_parent_class)->constructor (type, n_construct_properties, construct_params); + + self = GVC_MIXER_SOURCE_OUTPUT (object); + + return object; +} + +static void +gvc_mixer_source_output_class_init (GvcMixerSourceOutputClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GvcMixerStreamClass *stream_class = GVC_MIXER_STREAM_CLASS (klass); + + object_class->constructor = gvc_mixer_source_output_constructor; + object_class->finalize = gvc_mixer_source_output_finalize; + + stream_class->push_volume = gvc_mixer_source_output_push_volume; + stream_class->change_is_muted = gvc_mixer_source_output_change_is_muted; + + g_type_class_add_private (klass, sizeof (GvcMixerSourceOutputPrivate)); +} + +static void +gvc_mixer_source_output_init (GvcMixerSourceOutput *source_output) +{ + source_output->priv = GVC_MIXER_SOURCE_OUTPUT_GET_PRIVATE (source_output); + +} + +static void +gvc_mixer_source_output_finalize (GObject *object) +{ + GvcMixerSourceOutput *mixer_source_output; + + g_return_if_fail (object != NULL); + g_return_if_fail (GVC_IS_MIXER_SOURCE_OUTPUT (object)); + + mixer_source_output = GVC_MIXER_SOURCE_OUTPUT (object); + + g_return_if_fail (mixer_source_output->priv != NULL); + G_OBJECT_CLASS (gvc_mixer_source_output_parent_class)->finalize (object); +} + +GvcMixerStream * +gvc_mixer_source_output_new (pa_context *context, + guint index, + GvcChannelMap *channel_map) +{ + GObject *object; + + object = g_object_new (GVC_TYPE_MIXER_SOURCE_OUTPUT, + "pa-context", context, + "index", index, + "channel-map", channel_map, + NULL); + + return GVC_MIXER_STREAM (object); +} diff --git a/plugins/media-keys/cut-n-paste/gvc-mixer-source-output.h b/plugins/media-keys/cut-n-paste/gvc-mixer-source-output.h new file mode 100644 index 0000000..6ebaca9 --- /dev/null +++ b/plugins/media-keys/cut-n-paste/gvc-mixer-source-output.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 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 __GVC_MIXER_SOURCE_OUTPUT_H +#define __GVC_MIXER_SOURCE_OUTPUT_H + +#include +#include "gvc-mixer-stream.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GVC_TYPE_MIXER_SOURCE_OUTPUT (gvc_mixer_source_output_get_type ()) +#define GVC_MIXER_SOURCE_OUTPUT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_MIXER_SOURCE_OUTPUT, GvcMixerSourceOutput)) +#define GVC_MIXER_SOURCE_OUTPUT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_MIXER_SOURCE_OUTPUT, GvcMixerSourceOutputClass)) +#define GVC_IS_MIXER_SOURCE_OUTPUT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_MIXER_SOURCE_OUTPUT)) +#define GVC_IS_MIXER_SOURCE_OUTPUT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_MIXER_SOURCE_OUTPUT)) +#define GVC_MIXER_SOURCE_OUTPUT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_MIXER_SOURCE_OUTPUT, GvcMixerSourceOutputClass)) + +typedef struct GvcMixerSourceOutputPrivate GvcMixerSourceOutputPrivate; + +typedef struct +{ + GvcMixerStream parent; + GvcMixerSourceOutputPrivate *priv; +} GvcMixerSourceOutput; + +typedef struct +{ + GvcMixerStreamClass parent_class; +} GvcMixerSourceOutputClass; + +GType gvc_mixer_source_output_get_type (void); + +GvcMixerStream * gvc_mixer_source_output_new (pa_context *context, + guint index, + GvcChannelMap *map); + +#ifdef __cplusplus +} +#endif + +#endif /* __GVC_MIXER_SOURCE_OUTPUT_H */ diff --git a/plugins/media-keys/cut-n-paste/gvc-mixer-source.c b/plugins/media-keys/cut-n-paste/gvc-mixer-source.c new file mode 100644 index 0000000..d13be9d --- /dev/null +++ b/plugins/media-keys/cut-n-paste/gvc-mixer-source.c @@ -0,0 +1,220 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 William Jon McCann + * + * 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 +#include +#include + +#include +#include + +#include + +#include "gvc-mixer-source.h" + +#define GVC_MIXER_SOURCE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_MIXER_SOURCE, GvcMixerSourcePrivate)) + +struct GvcMixerSourcePrivate +{ + gpointer dummy; +}; + +static void gvc_mixer_source_class_init (GvcMixerSourceClass *klass); +static void gvc_mixer_source_init (GvcMixerSource *mixer_source); +static void gvc_mixer_source_finalize (GObject *object); +static void gvc_mixer_source_dispose (GObject *object); + +G_DEFINE_TYPE (GvcMixerSource, gvc_mixer_source, GVC_TYPE_MIXER_STREAM) + +static gboolean +gvc_mixer_source_push_volume (GvcMixerStream *stream, gpointer *op) +{ + pa_operation *o; + guint index; + GvcChannelMap *map; + pa_context *context; + const pa_cvolume *cv; + + index = gvc_mixer_stream_get_index (stream); + + map = gvc_mixer_stream_get_channel_map (stream); + + /* set the volume */ + cv = gvc_channel_map_get_cvolume (map); + + context = gvc_mixer_stream_get_pa_context (stream); + + o = pa_context_set_source_volume_by_index (context, + index, + cv, + NULL, + NULL); + + if (o == NULL) { + g_warning ("pa_context_set_source_volume_by_index() failed: %s", pa_strerror(pa_context_errno(context))); + return FALSE; + } + + *op = o; + + return TRUE; +} + +static gboolean +gvc_mixer_source_change_is_muted (GvcMixerStream *stream, + gboolean is_muted) +{ + pa_operation *o; + guint index; + pa_context *context; + + index = gvc_mixer_stream_get_index (stream); + context = gvc_mixer_stream_get_pa_context (stream); + + o = pa_context_set_source_mute_by_index (context, + index, + is_muted, + NULL, + NULL); + + if (o == NULL) { + g_warning ("pa_context_set_source_mute_by_index() failed: %s", pa_strerror(pa_context_errno(context))); + return FALSE; + } + + pa_operation_unref(o); + + return TRUE; +} + +static gboolean +gvc_mixer_source_change_port (GvcMixerStream *stream, + const char *port) +{ +#if PA_MICRO > 15 + pa_operation *o; + guint index; + pa_context *context; + + index = gvc_mixer_stream_get_index (stream); + context = gvc_mixer_stream_get_pa_context (stream); + + o = pa_context_set_source_port_by_index (context, + index, + port, + NULL, + NULL); + + if (o == NULL) { + g_warning ("pa_context_set_source_port_by_index() failed: %s", pa_strerror(pa_context_errno(context))); + return FALSE; + } + + pa_operation_unref(o); + + return TRUE; +#else + return FALSE; +#endif /* PA_MICRO > 15 */ +} + +static GObject * +gvc_mixer_source_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_params) +{ + GObject *object; + GvcMixerSource *self; + + object = G_OBJECT_CLASS (gvc_mixer_source_parent_class)->constructor (type, n_construct_properties, construct_params); + + self = GVC_MIXER_SOURCE (object); + + return object; +} + +static void +gvc_mixer_source_class_init (GvcMixerSourceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GvcMixerStreamClass *stream_class = GVC_MIXER_STREAM_CLASS (klass); + + object_class->constructor = gvc_mixer_source_constructor; + object_class->dispose = gvc_mixer_source_dispose; + object_class->finalize = gvc_mixer_source_finalize; + + stream_class->push_volume = gvc_mixer_source_push_volume; + stream_class->change_is_muted = gvc_mixer_source_change_is_muted; + stream_class->change_port = gvc_mixer_source_change_port; + + g_type_class_add_private (klass, sizeof (GvcMixerSourcePrivate)); +} + +static void +gvc_mixer_source_init (GvcMixerSource *source) +{ + source->priv = GVC_MIXER_SOURCE_GET_PRIVATE (source); +} + +static void +gvc_mixer_source_dispose (GObject *object) +{ + GvcMixerSource *mixer_source; + + g_return_if_fail (object != NULL); + g_return_if_fail (GVC_IS_MIXER_SOURCE (object)); + + mixer_source = GVC_MIXER_SOURCE (object); + + G_OBJECT_CLASS (gvc_mixer_source_parent_class)->dispose (object); +} + +static void +gvc_mixer_source_finalize (GObject *object) +{ + GvcMixerSource *mixer_source; + + g_return_if_fail (object != NULL); + g_return_if_fail (GVC_IS_MIXER_SOURCE (object)); + + mixer_source = GVC_MIXER_SOURCE (object); + + g_return_if_fail (mixer_source->priv != NULL); + G_OBJECT_CLASS (gvc_mixer_source_parent_class)->finalize (object); +} + +GvcMixerStream * +gvc_mixer_source_new (pa_context *context, + guint index, + GvcChannelMap *channel_map) + +{ + GObject *object; + + object = g_object_new (GVC_TYPE_MIXER_SOURCE, + "pa-context", context, + "index", index, + "channel-map", channel_map, + NULL); + + return GVC_MIXER_STREAM (object); +} diff --git a/plugins/media-keys/cut-n-paste/gvc-mixer-source.h b/plugins/media-keys/cut-n-paste/gvc-mixer-source.h new file mode 100644 index 0000000..502f31c --- /dev/null +++ b/plugins/media-keys/cut-n-paste/gvc-mixer-source.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 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 __GVC_MIXER_SOURCE_H +#define __GVC_MIXER_SOURCE_H + +#include +#include "gvc-mixer-stream.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GVC_TYPE_MIXER_SOURCE (gvc_mixer_source_get_type ()) +#define GVC_MIXER_SOURCE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_MIXER_SOURCE, GvcMixerSource)) +#define GVC_MIXER_SOURCE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_MIXER_SOURCE, GvcMixerSourceClass)) +#define GVC_IS_MIXER_SOURCE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_MIXER_SOURCE)) +#define GVC_IS_MIXER_SOURCE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_MIXER_SOURCE)) +#define GVC_MIXER_SOURCE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_MIXER_SOURCE, GvcMixerSourceClass)) + +typedef struct GvcMixerSourcePrivate GvcMixerSourcePrivate; + +typedef struct +{ + GvcMixerStream parent; + GvcMixerSourcePrivate *priv; +} GvcMixerSource; + +typedef struct +{ + GvcMixerStreamClass parent_class; +} GvcMixerSourceClass; + +GType gvc_mixer_source_get_type (void); + +GvcMixerStream * gvc_mixer_source_new (pa_context *context, + guint index, + GvcChannelMap *map); + +#ifdef __cplusplus +} +#endif + +#endif /* __GVC_MIXER_SOURCE_H */ diff --git a/plugins/media-keys/cut-n-paste/gvc-mixer-stream.c b/plugins/media-keys/cut-n-paste/gvc-mixer-stream.c new file mode 100644 index 0000000..4662d46 --- /dev/null +++ b/plugins/media-keys/cut-n-paste/gvc-mixer-stream.c @@ -0,0 +1,875 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 William Jon McCann + * + * 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 +#include +#include + +#include +#include + +#include + +#include "gvc-mixer-stream.h" + +#define GVC_MIXER_STREAM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_MIXER_STREAM, GvcMixerStreamPrivate)) + +static guint32 stream_serial = 1; + +struct GvcMixerStreamPrivate +{ + pa_context *pa_context; + guint id; + guint index; + GvcChannelMap *channel_map; + char *name; + char *description; + char *application_id; + char *icon_name; + gboolean is_muted; + gboolean can_decibel; + gboolean is_event_stream; + gboolean is_virtual; + pa_volume_t base_volume; + pa_operation *change_volume_op; + char *port; + char *human_port; + GList *ports; +}; + +enum +{ + PROP_0, + PROP_ID, + PROP_PA_CONTEXT, + PROP_CHANNEL_MAP, + PROP_INDEX, + PROP_NAME, + PROP_DESCRIPTION, + PROP_APPLICATION_ID, + PROP_ICON_NAME, + PROP_VOLUME, + PROP_DECIBEL, + PROP_IS_MUTED, + PROP_CAN_DECIBEL, + PROP_IS_EVENT_STREAM, + PROP_IS_VIRTUAL, + PROP_PORT, +}; + +static void gvc_mixer_stream_class_init (GvcMixerStreamClass *klass); +static void gvc_mixer_stream_init (GvcMixerStream *mixer_stream); +static void gvc_mixer_stream_finalize (GObject *object); + +G_DEFINE_ABSTRACT_TYPE (GvcMixerStream, gvc_mixer_stream, G_TYPE_OBJECT) + +static guint32 +get_next_stream_serial (void) +{ + guint32 serial; + + serial = stream_serial++; + + if ((gint32)stream_serial < 0) { + stream_serial = 1; + } + + return serial; +} + +pa_context * +gvc_mixer_stream_get_pa_context (GvcMixerStream *stream) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), 0); + return stream->priv->pa_context; +} + +guint +gvc_mixer_stream_get_index (GvcMixerStream *stream) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), 0); + return stream->priv->index; +} + +guint +gvc_mixer_stream_get_id (GvcMixerStream *stream) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), 0); + return stream->priv->id; +} + +GvcChannelMap * +gvc_mixer_stream_get_channel_map (GvcMixerStream *stream) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), NULL); + return stream->priv->channel_map; +} + +pa_volume_t +gvc_mixer_stream_get_volume (GvcMixerStream *stream) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), 0); + + return (pa_volume_t) gvc_channel_map_get_volume(stream->priv->channel_map)[VOLUME]; +} + +gdouble +gvc_mixer_stream_get_decibel (GvcMixerStream *stream) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), 0); + + return pa_sw_volume_to_dB( + (pa_volume_t) gvc_channel_map_get_volume(stream->priv->channel_map)[VOLUME]); +} + +gboolean +gvc_mixer_stream_set_volume (GvcMixerStream *stream, + pa_volume_t volume) +{ + pa_cvolume cv; + + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + + cv = *gvc_channel_map_get_cvolume(stream->priv->channel_map); + pa_cvolume_scale(&cv, volume); + + if (!pa_cvolume_equal(gvc_channel_map_get_cvolume(stream->priv->channel_map), &cv)) { + gvc_channel_map_volume_changed(stream->priv->channel_map, &cv, FALSE); + g_object_notify (G_OBJECT (stream), "volume"); + return TRUE; + } + + return FALSE; +} + +gboolean +gvc_mixer_stream_set_decibel (GvcMixerStream *stream, + gdouble db) +{ + pa_cvolume cv; + + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + + cv = *gvc_channel_map_get_cvolume(stream->priv->channel_map); + pa_cvolume_scale(&cv, pa_sw_volume_from_dB(db)); + + if (!pa_cvolume_equal(gvc_channel_map_get_cvolume(stream->priv->channel_map), &cv)) { + gvc_channel_map_volume_changed(stream->priv->channel_map, &cv, FALSE); + g_object_notify (G_OBJECT (stream), "volume"); + } + + return TRUE; +} + +gboolean +gvc_mixer_stream_get_is_muted (GvcMixerStream *stream) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + return stream->priv->is_muted; +} + +gboolean +gvc_mixer_stream_get_can_decibel (GvcMixerStream *stream) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + return stream->priv->can_decibel; +} + +gboolean +gvc_mixer_stream_set_is_muted (GvcMixerStream *stream, + gboolean is_muted) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + + if (is_muted != stream->priv->is_muted) { + stream->priv->is_muted = is_muted; + g_object_notify (G_OBJECT (stream), "is-muted"); + } + + return TRUE; +} + +gboolean +gvc_mixer_stream_set_can_decibel (GvcMixerStream *stream, + gboolean can_decibel) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + + if (can_decibel != stream->priv->can_decibel) { + stream->priv->can_decibel = can_decibel; + g_object_notify (G_OBJECT (stream), "can-decibel"); + } + + return TRUE; +} + +const char * +gvc_mixer_stream_get_name (GvcMixerStream *stream) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), NULL); + return stream->priv->name; +} + +const char * +gvc_mixer_stream_get_description (GvcMixerStream *stream) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), NULL); + return stream->priv->description; +} + +gboolean +gvc_mixer_stream_set_name (GvcMixerStream *stream, + const char *name) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + + g_free (stream->priv->name); + stream->priv->name = g_strdup (name); + g_object_notify (G_OBJECT (stream), "name"); + + return TRUE; +} + +gboolean +gvc_mixer_stream_set_description (GvcMixerStream *stream, + const char *description) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + + g_free (stream->priv->description); + stream->priv->description = g_strdup (description); + g_object_notify (G_OBJECT (stream), "description"); + + return TRUE; +} + +gboolean +gvc_mixer_stream_is_event_stream (GvcMixerStream *stream) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + + return stream->priv->is_event_stream; +} + +gboolean +gvc_mixer_stream_set_is_event_stream (GvcMixerStream *stream, + gboolean is_event_stream) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + + stream->priv->is_event_stream = is_event_stream; + g_object_notify (G_OBJECT (stream), "is-event-stream"); + + return TRUE; +} + +gboolean +gvc_mixer_stream_is_virtual (GvcMixerStream *stream) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + + return stream->priv->is_virtual; +} + +gboolean +gvc_mixer_stream_set_is_virtual (GvcMixerStream *stream, + gboolean is_virtual) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + + stream->priv->is_virtual = is_virtual; + g_object_notify (G_OBJECT (stream), "is-virtual"); + + return TRUE; +} + +const char * +gvc_mixer_stream_get_application_id (GvcMixerStream *stream) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), NULL); + return stream->priv->application_id; +} + +gboolean +gvc_mixer_stream_set_application_id (GvcMixerStream *stream, + const char *application_id) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + + g_free (stream->priv->application_id); + stream->priv->application_id = g_strdup (application_id); + g_object_notify (G_OBJECT (stream), "application-id"); + + return TRUE; +} + +static void +on_channel_map_volume_changed (GvcChannelMap *channel_map, + gboolean set, + GvcMixerStream *stream) +{ + if (set == TRUE) + gvc_mixer_stream_push_volume (stream); + + g_object_notify (G_OBJECT (stream), "volume"); +} + +static gboolean +gvc_mixer_stream_set_channel_map (GvcMixerStream *stream, + GvcChannelMap *channel_map) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + + if (channel_map != NULL) { + g_object_ref (channel_map); + } + + if (stream->priv->channel_map != NULL) { + g_signal_handlers_disconnect_by_func (stream->priv->channel_map, + on_channel_map_volume_changed, + stream); + g_object_unref (stream->priv->channel_map); + } + + stream->priv->channel_map = channel_map; + + if (stream->priv->channel_map != NULL) { + g_signal_connect (stream->priv->channel_map, + "volume-changed", + G_CALLBACK (on_channel_map_volume_changed), + stream); + + g_object_notify (G_OBJECT (stream), "channel-map"); + } + + return TRUE; +} + +const char * +gvc_mixer_stream_get_icon_name (GvcMixerStream *stream) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), NULL); + return stream->priv->icon_name; +} + +gboolean +gvc_mixer_stream_set_icon_name (GvcMixerStream *stream, + const char *icon_name) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + + g_free (stream->priv->icon_name); + stream->priv->icon_name = g_strdup (icon_name); + g_object_notify (G_OBJECT (stream), "icon-name"); + + return TRUE; +} + +pa_volume_t +gvc_mixer_stream_get_base_volume (GvcMixerStream *stream) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), 0); + + return stream->priv->base_volume; +} + +gboolean +gvc_mixer_stream_set_base_volume (GvcMixerStream *stream, + pa_volume_t base_volume) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + + stream->priv->base_volume = base_volume; + + return TRUE; +} + +GvcMixerStreamPort * +gvc_mixer_stream_get_port (GvcMixerStream *stream) +{ + GList *l; + + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), NULL); + g_return_val_if_fail (stream->priv->ports != NULL, NULL); + + for (l = stream->priv->ports; l != NULL; l = l->next) { + GvcMixerStreamPort *p = l->data; + if (g_strcmp0 (stream->priv->port, p->port) == 0) { + return p; + } + } + + g_assert_not_reached (); + + return NULL; +} + +gboolean +gvc_mixer_stream_set_port (GvcMixerStream *stream, + const char *port) +{ + GList *l; + + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + g_return_val_if_fail (stream->priv->ports != NULL, FALSE); + + g_free (stream->priv->port); + stream->priv->port = g_strdup (port); + + g_free (stream->priv->human_port); + stream->priv->human_port = NULL; + + for (l = stream->priv->ports; l != NULL; l = l->next) { + GvcMixerStreamPort *p = l->data; + if (g_str_equal (stream->priv->port, p->port)) { + stream->priv->human_port = g_strdup (p->human_port); + break; + } + } + + g_object_notify (G_OBJECT (stream), "port"); + + return TRUE; +} + +gboolean +gvc_mixer_stream_change_port (GvcMixerStream *stream, + const char *port) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + return GVC_MIXER_STREAM_GET_CLASS (stream)->change_port (stream, port); +} + +const GList * +gvc_mixer_stream_get_ports (GvcMixerStream *stream) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + return stream->priv->ports; +} + +static int +sort_ports (GvcMixerStreamPort *a, + GvcMixerStreamPort *b) +{ + if (a->priority == b->priority) + return 0; + if (a->priority > b->priority) + return 1; + return -1; +} + +gboolean +gvc_mixer_stream_set_ports (GvcMixerStream *stream, + GList *ports) +{ + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + g_return_val_if_fail (stream->priv->ports == NULL, FALSE); + + stream->priv->ports = g_list_sort (ports, (GCompareFunc) sort_ports); + + return TRUE; +} + +static void +gvc_mixer_stream_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GvcMixerStream *self = GVC_MIXER_STREAM (object); + + switch (prop_id) { + case PROP_PA_CONTEXT: + self->priv->pa_context = g_value_get_pointer (value); + break; + case PROP_INDEX: + self->priv->index = g_value_get_ulong (value); + break; + case PROP_ID: + self->priv->id = g_value_get_ulong (value); + break; + case PROP_CHANNEL_MAP: + gvc_mixer_stream_set_channel_map (self, g_value_get_object (value)); + break; + case PROP_NAME: + gvc_mixer_stream_set_name (self, g_value_get_string (value)); + break; + case PROP_DESCRIPTION: + gvc_mixer_stream_set_description (self, g_value_get_string (value)); + break; + case PROP_APPLICATION_ID: + gvc_mixer_stream_set_application_id (self, g_value_get_string (value)); + break; + case PROP_ICON_NAME: + gvc_mixer_stream_set_icon_name (self, g_value_get_string (value)); + break; + case PROP_VOLUME: + gvc_mixer_stream_set_volume (self, g_value_get_ulong (value)); + break; + case PROP_DECIBEL: + gvc_mixer_stream_set_decibel (self, g_value_get_double (value)); + break; + case PROP_IS_MUTED: + gvc_mixer_stream_set_is_muted (self, g_value_get_boolean (value)); + break; + case PROP_IS_EVENT_STREAM: + gvc_mixer_stream_set_is_event_stream (self, g_value_get_boolean (value)); + break; + case PROP_IS_VIRTUAL: + gvc_mixer_stream_set_is_virtual (self, g_value_get_boolean (value)); + break; + case PROP_CAN_DECIBEL: + gvc_mixer_stream_set_can_decibel (self, g_value_get_boolean (value)); + break; + case PROP_PORT: + gvc_mixer_stream_set_port (self, g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gvc_mixer_stream_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GvcMixerStream *self = GVC_MIXER_STREAM (object); + + switch (prop_id) { + case PROP_PA_CONTEXT: + g_value_set_pointer (value, self->priv->pa_context); + break; + case PROP_INDEX: + g_value_set_ulong (value, self->priv->index); + break; + case PROP_ID: + g_value_set_ulong (value, self->priv->id); + break; + case PROP_CHANNEL_MAP: + g_value_set_object (value, self->priv->channel_map); + break; + case PROP_NAME: + g_value_set_string (value, self->priv->name); + break; + case PROP_DESCRIPTION: + g_value_set_string (value, self->priv->description); + break; + case PROP_APPLICATION_ID: + g_value_set_string (value, self->priv->application_id); + break; + case PROP_ICON_NAME: + g_value_set_string (value, self->priv->icon_name); + break; + case PROP_VOLUME: + g_value_set_ulong (value, + pa_cvolume_max(gvc_channel_map_get_cvolume(self->priv->channel_map))); + break; + case PROP_DECIBEL: + g_value_set_double (value, + pa_sw_volume_to_dB(pa_cvolume_max(gvc_channel_map_get_cvolume(self->priv->channel_map)))); + break; + case PROP_IS_MUTED: + g_value_set_boolean (value, self->priv->is_muted); + break; + case PROP_IS_EVENT_STREAM: + g_value_set_boolean (value, self->priv->is_event_stream); + break; + case PROP_IS_VIRTUAL: + g_value_set_boolean (value, self->priv->is_virtual); + break; + case PROP_CAN_DECIBEL: + g_value_set_boolean (value, self->priv->can_decibel); + break; + case PROP_PORT: + g_value_set_string (value, self->priv->port); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +gvc_mixer_stream_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_params) +{ + GObject *object; + GvcMixerStream *self; + + object = G_OBJECT_CLASS (gvc_mixer_stream_parent_class)->constructor (type, n_construct_properties, construct_params); + + self = GVC_MIXER_STREAM (object); + + self->priv->id = get_next_stream_serial (); + + return object; +} + +static gboolean +gvc_mixer_stream_real_change_port (GvcMixerStream *stream, + const char *port) +{ + return FALSE; +} + +static gboolean +gvc_mixer_stream_real_push_volume (GvcMixerStream *stream, gpointer *op) +{ + return FALSE; +} + +static gboolean +gvc_mixer_stream_real_change_is_muted (GvcMixerStream *stream, + gboolean is_muted) +{ + return FALSE; +} + +gboolean +gvc_mixer_stream_push_volume (GvcMixerStream *stream) +{ + pa_operation *op; + gboolean ret; + + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + + if (stream->priv->is_event_stream != FALSE) + return TRUE; + + g_debug ("Pushing new volume to stream '%s' (%s)", + stream->priv->description, stream->priv->name); + + ret = GVC_MIXER_STREAM_GET_CLASS (stream)->push_volume (stream, (gpointer *) &op); + if (ret) { + if (stream->priv->change_volume_op != NULL) + pa_operation_unref (stream->priv->change_volume_op); + stream->priv->change_volume_op = op; + } + return ret; +} + +gboolean +gvc_mixer_stream_change_is_muted (GvcMixerStream *stream, + gboolean is_muted) +{ + gboolean ret; + g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE); + ret = GVC_MIXER_STREAM_GET_CLASS (stream)->change_is_muted (stream, is_muted); + return ret; +} + +gboolean +gvc_mixer_stream_is_running (GvcMixerStream *stream) +{ + if (stream->priv->change_volume_op == NULL) + return FALSE; + + if ((pa_operation_get_state(stream->priv->change_volume_op) == PA_OPERATION_RUNNING)) + return TRUE; + + pa_operation_unref(stream->priv->change_volume_op); + stream->priv->change_volume_op = NULL; + + return FALSE; +} + +static void +gvc_mixer_stream_class_init (GvcMixerStreamClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->constructor = gvc_mixer_stream_constructor; + gobject_class->finalize = gvc_mixer_stream_finalize; + gobject_class->set_property = gvc_mixer_stream_set_property; + gobject_class->get_property = gvc_mixer_stream_get_property; + + klass->push_volume = gvc_mixer_stream_real_push_volume; + klass->change_port = gvc_mixer_stream_real_change_port; + klass->change_is_muted = gvc_mixer_stream_real_change_is_muted; + + g_object_class_install_property (gobject_class, + PROP_INDEX, + g_param_spec_ulong ("index", + "Index", + "The index for this stream", + 0, G_MAXULONG, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (gobject_class, + PROP_ID, + g_param_spec_ulong ("id", + "id", + "The id for this stream", + 0, G_MAXULONG, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (gobject_class, + PROP_CHANNEL_MAP, + g_param_spec_object ("channel-map", + "channel map", + "The channel map for this stream", + GVC_TYPE_CHANNEL_MAP, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); + g_object_class_install_property (gobject_class, + PROP_PA_CONTEXT, + g_param_spec_pointer ("pa-context", + "PulseAudio context", + "The PulseAudio context for this stream", + G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (gobject_class, + PROP_VOLUME, + g_param_spec_ulong ("volume", + "Volume", + "The volume for this stream", + 0, G_MAXULONG, 0, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_DECIBEL, + g_param_spec_double ("decibel", + "Decibel", + "The decibel level for this stream", + -G_MAXDOUBLE, G_MAXDOUBLE, 0, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); + + g_object_class_install_property (gobject_class, + PROP_NAME, + g_param_spec_string ("name", + "Name", + "Name to display for this stream", + NULL, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); + g_object_class_install_property (gobject_class, + PROP_DESCRIPTION, + g_param_spec_string ("description", + "Description", + "Description to display for this stream", + NULL, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); + g_object_class_install_property (gobject_class, + PROP_APPLICATION_ID, + g_param_spec_string ("application-id", + "Application identifier", + "Application identifier for this stream", + NULL, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); + g_object_class_install_property (gobject_class, + PROP_ICON_NAME, + g_param_spec_string ("icon-name", + "Icon Name", + "Name of icon to display for this stream", + NULL, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); + g_object_class_install_property (gobject_class, + PROP_IS_MUTED, + g_param_spec_boolean ("is-muted", + "is muted", + "Whether stream is muted", + FALSE, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); + g_object_class_install_property (gobject_class, + PROP_CAN_DECIBEL, + g_param_spec_boolean ("can-decibel", + "can decibel", + "Whether stream volume can be converted to decibel units", + FALSE, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); + g_object_class_install_property (gobject_class, + PROP_IS_EVENT_STREAM, + g_param_spec_boolean ("is-event-stream", + "is event stream", + "Whether stream's role is to play an event", + FALSE, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); + g_object_class_install_property (gobject_class, + PROP_IS_VIRTUAL, + g_param_spec_boolean ("is-virtual", + "is virtual stream", + "Whether the stream is virtual", + FALSE, + G_PARAM_READWRITE|G_PARAM_CONSTRUCT)); + g_object_class_install_property (gobject_class, + PROP_PORT, + g_param_spec_string ("port", + "Port", + "The name of the current port for this stream", + NULL, + G_PARAM_READWRITE)); + g_type_class_add_private (klass, sizeof (GvcMixerStreamPrivate)); +} + +static void +gvc_mixer_stream_init (GvcMixerStream *stream) +{ + stream->priv = GVC_MIXER_STREAM_GET_PRIVATE (stream); +} + +static void +free_port (GvcMixerStreamPort *p) +{ + g_free (p->port); + g_free (p->human_port); + g_free (p); +} + +static void +gvc_mixer_stream_finalize (GObject *object) +{ + GvcMixerStream *mixer_stream; + + g_return_if_fail (object != NULL); + g_return_if_fail (GVC_IS_MIXER_STREAM (object)); + + mixer_stream = GVC_MIXER_STREAM (object); + + g_return_if_fail (mixer_stream->priv != NULL); + + g_free (mixer_stream->priv->name); + mixer_stream->priv->name = NULL; + + g_free (mixer_stream->priv->description); + mixer_stream->priv->description = NULL; + + g_free (mixer_stream->priv->application_id); + mixer_stream->priv->application_id = NULL; + + g_free (mixer_stream->priv->icon_name); + mixer_stream->priv->icon_name = NULL; + + g_free (mixer_stream->priv->port); + mixer_stream->priv->port = NULL; + + g_free (mixer_stream->priv->human_port); + mixer_stream->priv->human_port = NULL; + + g_list_foreach (mixer_stream->priv->ports, (GFunc) free_port, NULL); + g_list_free (mixer_stream->priv->ports); + mixer_stream->priv->ports = NULL; + + if (mixer_stream->priv->change_volume_op) { + pa_operation_unref(mixer_stream->priv->change_volume_op); + mixer_stream->priv->change_volume_op = NULL; + } + + G_OBJECT_CLASS (gvc_mixer_stream_parent_class)->finalize (object); +} diff --git a/plugins/media-keys/cut-n-paste/gvc-mixer-stream.h b/plugins/media-keys/cut-n-paste/gvc-mixer-stream.h new file mode 100644 index 0000000..16ab21e --- /dev/null +++ b/plugins/media-keys/cut-n-paste/gvc-mixer-stream.h @@ -0,0 +1,128 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 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 __GVC_MIXER_STREAM_H +#define __GVC_MIXER_STREAM_H + +#include +#include + +#include "gvc-channel-map.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GVC_TYPE_MIXER_STREAM (gvc_mixer_stream_get_type ()) +#define GVC_MIXER_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_MIXER_STREAM, GvcMixerStream)) +#define GVC_MIXER_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_MIXER_STREAM, GvcMixerStreamClass)) +#define GVC_IS_MIXER_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_MIXER_STREAM)) +#define GVC_IS_MIXER_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_MIXER_STREAM)) +#define GVC_MIXER_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_MIXER_STREAM, GvcMixerStreamClass)) + +typedef struct GvcMixerStreamPrivate GvcMixerStreamPrivate; + +typedef struct +{ + GObject parent; + GvcMixerStreamPrivate *priv; +} GvcMixerStream; + +typedef struct +{ + GObjectClass parent_class; + + /* vtable */ + gboolean (*push_volume) (GvcMixerStream *stream, + gpointer *operation); + gboolean (*change_is_muted) (GvcMixerStream *stream, + gboolean is_muted); + gboolean (*change_port) (GvcMixerStream *stream, + const char *port); +} GvcMixerStreamClass; + +typedef struct +{ + char *port; + char *human_port; + guint priority; +} GvcMixerStreamPort; + +GType gvc_mixer_stream_get_type (void); + +pa_context * gvc_mixer_stream_get_pa_context (GvcMixerStream *stream); +guint gvc_mixer_stream_get_index (GvcMixerStream *stream); +guint gvc_mixer_stream_get_id (GvcMixerStream *stream); +GvcChannelMap * gvc_mixer_stream_get_channel_map (GvcMixerStream *stream); +GvcMixerStreamPort *gvc_mixer_stream_get_port (GvcMixerStream *stream); +const GList * gvc_mixer_stream_get_ports (GvcMixerStream *stream); +gboolean gvc_mixer_stream_change_port (GvcMixerStream *stream, + const char *port); + +pa_volume_t gvc_mixer_stream_get_volume (GvcMixerStream *stream); +gdouble gvc_mixer_stream_get_decibel (GvcMixerStream *stream); +gboolean gvc_mixer_stream_push_volume (GvcMixerStream *stream); +pa_volume_t gvc_mixer_stream_get_base_volume (GvcMixerStream *stream); + +gboolean gvc_mixer_stream_get_is_muted (GvcMixerStream *stream); +gboolean gvc_mixer_stream_get_can_decibel (GvcMixerStream *stream); +gboolean gvc_mixer_stream_change_is_muted (GvcMixerStream *stream, + gboolean is_muted); +gboolean gvc_mixer_stream_is_running (GvcMixerStream *stream); +const char * gvc_mixer_stream_get_name (GvcMixerStream *stream); +const char * gvc_mixer_stream_get_icon_name (GvcMixerStream *stream); +const char * gvc_mixer_stream_get_description (GvcMixerStream *stream); +const char * gvc_mixer_stream_get_application_id (GvcMixerStream *stream); +gboolean gvc_mixer_stream_is_event_stream (GvcMixerStream *stream); +gboolean gvc_mixer_stream_is_virtual (GvcMixerStream *stream); + +/* private */ +gboolean gvc_mixer_stream_set_volume (GvcMixerStream *stream, + pa_volume_t volume); +gboolean gvc_mixer_stream_set_decibel (GvcMixerStream *stream, + gdouble db); +gboolean gvc_mixer_stream_set_is_muted (GvcMixerStream *stream, + gboolean is_muted); +gboolean gvc_mixer_stream_set_can_decibel (GvcMixerStream *stream, + gboolean can_decibel); +gboolean gvc_mixer_stream_set_name (GvcMixerStream *stream, + const char *name); +gboolean gvc_mixer_stream_set_description (GvcMixerStream *stream, + const char *description); +gboolean gvc_mixer_stream_set_icon_name (GvcMixerStream *stream, + const char *name); +gboolean gvc_mixer_stream_set_is_event_stream (GvcMixerStream *stream, + gboolean is_event_stream); +gboolean gvc_mixer_stream_set_is_virtual (GvcMixerStream *stream, + gboolean is_event_stream); +gboolean gvc_mixer_stream_set_application_id (GvcMixerStream *stream, + const char *application_id); +gboolean gvc_mixer_stream_set_base_volume (GvcMixerStream *stream, + pa_volume_t base_volume); +gboolean gvc_mixer_stream_set_port (GvcMixerStream *stream, + const char *port); +gboolean gvc_mixer_stream_set_ports (GvcMixerStream *stream, + GList *ports); + +#ifdef __cplusplus +} +#endif + +#endif /* __GVC_MIXER_STREAM_H */ diff --git a/plugins/media-keys/gsd-marshal.list b/plugins/media-keys/gsd-marshal.list new file mode 100644 index 0000000..72f9937 --- /dev/null +++ b/plugins/media-keys/gsd-marshal.list @@ -0,0 +1 @@ +VOID:STRING,STRING diff --git a/plugins/media-keys/gsd-media-keys-manager.c b/plugins/media-keys/gsd-media-keys-manager.c new file mode 100644 index 0000000..ae6383a --- /dev/null +++ b/plugins/media-keys/gsd-media-keys-manager.c @@ -0,0 +1,1373 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2001-2003 Bastien Nocera + * Copyright (C) 2006-2007 William Jon McCann + * + * 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 +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "mate-settings-profile.h" +#include "gsd-marshal.h" +#include "gsd-media-keys-manager.h" +#include "gsd-media-keys-manager-glue.h" + +#include "eggaccelerators.h" +#include "acme.h" +#include "gsd-media-keys-window.h" + +#ifdef HAVE_PULSE +#include +#include "gvc-mixer-control.h" +#endif /* HAVE_PULSE */ + +#define GSD_DBUS_PATH "/org/mate/SettingsDaemon" +#define GSD_DBUS_NAME "org.mate.SettingsDaemon" +#define GSD_MEDIA_KEYS_DBUS_PATH GSD_DBUS_PATH "/MediaKeys" +#define GSD_MEDIA_KEYS_DBUS_NAME GSD_DBUS_NAME ".MediaKeys" + +#define TOUCHPAD_ENABLED_KEY "/desktop/mate/peripherals/touchpad/touchpad_enabled" + +#define VOLUME_STEP 6 /* percents for one volume button press */ +#define MAX_VOLUME 65536.0 + +#define GSD_MEDIA_KEYS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_MEDIA_KEYS_MANAGER, GsdMediaKeysManagerPrivate)) + +typedef struct { + char *application; + guint32 time; +} MediaPlayer; + +struct GsdMediaKeysManagerPrivate +{ +#ifdef HAVE_PULSE + /* Volume bits */ + GvcMixerControl *volume; + GvcMixerStream *stream; +#endif /* HAVE_PULSE */ + GtkWidget *dialog; + MateConfClient *conf_client; + GVolumeMonitor *volume_monitor; + + /* Multihead stuff */ + GdkScreen *current_screen; + GSList *screens; + + GList *media_players; + + DBusGConnection *connection; + guint notify[HANDLED_KEYS]; +}; + +enum { + MEDIA_PLAYER_KEY_PRESSED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +static void gsd_media_keys_manager_class_init (GsdMediaKeysManagerClass *klass); +static void gsd_media_keys_manager_init (GsdMediaKeysManager *media_keys_manager); +static void gsd_media_keys_manager_finalize (GObject *object); + +G_DEFINE_TYPE (GsdMediaKeysManager, gsd_media_keys_manager, G_TYPE_OBJECT) + +static gpointer manager_object = NULL; + + +static void +init_screens (GsdMediaKeysManager *manager) +{ + GdkDisplay *display; + int i; + + display = gdk_display_get_default (); + for (i = 0; i < gdk_display_get_n_screens (display); i++) { + GdkScreen *screen; + + screen = gdk_display_get_screen (display, i); + if (screen == NULL) { + continue; + } + manager->priv->screens = g_slist_append (manager->priv->screens, screen); + } + + manager->priv->current_screen = manager->priv->screens->data; +} + + +static void +acme_error (char * msg) +{ + GtkWidget *error_dialog; + + error_dialog = gtk_message_dialog_new (NULL, + GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + msg, NULL); + gtk_dialog_set_default_response (GTK_DIALOG (error_dialog), + GTK_RESPONSE_OK); + gtk_widget_show (error_dialog); + g_signal_connect (error_dialog, + "response", + G_CALLBACK (gtk_widget_destroy), + NULL); +} + +static char * +get_term_command (GsdMediaKeysManager *manager) +{ + char *cmd_term; + char *cmd = NULL; + + cmd_term = mateconf_client_get_string (manager->priv->conf_client, + "/desktop/mate/applications/terminal/exec", NULL); + if ((cmd_term != NULL) && (strcmp (cmd_term, "") != 0)) { + char *cmd_args; + cmd_args = mateconf_client_get_string (manager->priv->conf_client, + "/desktop/mate/applications/terminal/exec_arg", NULL); + if ((cmd_args != NULL) && (strcmp (cmd_term, "") != 0)) { + cmd = g_strdup_printf ("%s %s -e", cmd_term, cmd_args); + } else { + cmd = g_strdup_printf ("%s -e", cmd_term); + } + + g_free (cmd_args); + } + + g_free (cmd_term); + + return cmd; +} + +static void +execute (GsdMediaKeysManager *manager, + char *cmd, + gboolean sync, + gboolean need_term) +{ + gboolean retval; + char **argv; + int argc; + char *exec; + char *term = NULL; + + retval = FALSE; + + if (need_term) { + term = get_term_command (manager); + if (term == NULL) { + acme_error (_("Could not get default terminal. Verify that your default " + "terminal command is set and points to a valid application.")); + return; + } + } + + if (term) { + exec = g_strdup_printf ("%s %s", term, cmd); + g_free (term); + } else { + exec = g_strdup (cmd); + } + + if (g_shell_parse_argv (exec, &argc, &argv, NULL)) { + if (sync != FALSE) { + retval = g_spawn_sync (g_get_home_dir (), + argv, + NULL, + G_SPAWN_SEARCH_PATH, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL); + } else { + retval = g_spawn_async (g_get_home_dir (), + argv, + NULL, + G_SPAWN_SEARCH_PATH, + NULL, + NULL, + NULL, + NULL); + } + g_strfreev (argv); + } + + if (retval == FALSE) { + char *msg; + msg = g_strdup_printf (_("Couldn't execute command: %s\n" + "Verify that this is a valid command."), + exec); + + acme_error (msg); + g_free (msg); + } + g_free (exec); +} + +static void +dialog_init (GsdMediaKeysManager *manager) +{ + if (manager->priv->dialog != NULL + && !gsd_osd_window_is_valid (GSD_OSD_WINDOW (manager->priv->dialog))) { + gtk_widget_destroy (manager->priv->dialog); + manager->priv->dialog = NULL; + } + + if (manager->priv->dialog == NULL) { + manager->priv->dialog = gsd_media_keys_window_new (); + } +} + +static gboolean +is_valid_shortcut (const char *string) +{ + if (string == NULL || string[0] == '\0') { + return FALSE; + } + if (strcmp (string, "disabled") == 0) { + return FALSE; + } + + return TRUE; +} + +static void +update_kbd_cb (MateConfClient *client, + guint id, + MateConfEntry *entry, + GsdMediaKeysManager *manager) +{ + int i; + gboolean need_flush = TRUE; + + g_return_if_fail (entry->key != NULL); + + gdk_error_trap_push (); + + /* Find the key that was modified */ + for (i = 0; i < HANDLED_KEYS; i++) { + if (strcmp (entry->key, keys[i].mateconf_key) == 0) { + char *tmp; + Key *key; + + if (keys[i].key != NULL) { + need_flush = TRUE; + grab_key_unsafe (keys[i].key, FALSE, manager->priv->screens); + } + + g_free (keys[i].key); + keys[i].key = NULL; + + tmp = mateconf_client_get_string (manager->priv->conf_client, + keys[i].mateconf_key, NULL); + + if (is_valid_shortcut (tmp) == FALSE) { + g_free (tmp); + break; + } + + key = g_new0 (Key, 1); + if (!egg_accelerator_parse_virtual (tmp, &key->keysym, &key->keycodes, &key->state)) { + g_free (tmp); + g_free (key); + break; + } + + need_flush = TRUE; + grab_key_unsafe (key, TRUE, manager->priv->screens); + keys[i].key = key; + + g_free (tmp); + + break; + } + } + + if (need_flush) + gdk_flush (); + if (gdk_error_trap_pop ()) + g_warning ("Grab failed for some keys, another application may already have access the them."); +} + +static void +init_kbd (GsdMediaKeysManager *manager) +{ + int i; + gboolean need_flush = FALSE; + + mate_settings_profile_start (NULL); + + gdk_error_trap_push (); + + for (i = 0; i < HANDLED_KEYS; i++) { + char *tmp; + Key *key; + + manager->priv->notify[i] = + mateconf_client_notify_add (manager->priv->conf_client, + keys[i].mateconf_key, + (MateConfClientNotifyFunc) update_kbd_cb, + manager, + NULL, + NULL); + + tmp = mateconf_client_get_string (manager->priv->conf_client, + keys[i].mateconf_key, + NULL); + + if (!is_valid_shortcut (tmp)) { + g_debug ("Not a valid shortcut: '%s'", tmp); + g_free (tmp); + continue; + } + + key = g_new0 (Key, 1); + if (!egg_accelerator_parse_virtual (tmp, &key->keysym, &key->keycodes, &key->state)) { + g_debug ("Unable to parse: '%s'", tmp); + g_free (tmp); + g_free (key); + continue; + } + + g_free (tmp); + + keys[i].key = key; + + need_flush = TRUE; + grab_key_unsafe (key, TRUE, manager->priv->screens); + } + + if (need_flush) + gdk_flush (); + if (gdk_error_trap_pop ()) + g_warning ("Grab failed for some keys, another application may already have access the them."); + + mate_settings_profile_end (NULL); +} + +static void +dialog_show (GsdMediaKeysManager *manager) +{ + int orig_w; + int orig_h; + int screen_w; + int screen_h; + int x; + int y; + int pointer_x; + int pointer_y; + GtkRequisition win_req; + GdkScreen *pointer_screen; + GdkRectangle geometry; + int monitor; + + gtk_window_set_screen (GTK_WINDOW (manager->priv->dialog), + manager->priv->current_screen); + + /* + * get the window size + * if the window hasn't been mapped, it doesn't necessarily + * know its true size, yet, so we need to jump through hoops + */ + gtk_window_get_default_size (GTK_WINDOW (manager->priv->dialog), &orig_w, &orig_h); + gtk_widget_size_request (manager->priv->dialog, &win_req); + + if (win_req.width > orig_w) { + orig_w = win_req.width; + } + if (win_req.height > orig_h) { + orig_h = win_req.height; + } + + pointer_screen = NULL; + gdk_display_get_pointer (gdk_screen_get_display (manager->priv->current_screen), + &pointer_screen, + &pointer_x, + &pointer_y, + NULL); + if (pointer_screen != manager->priv->current_screen) { + /* The pointer isn't on the current screen, so just + * assume the default monitor + */ + monitor = 0; + } else { + monitor = gdk_screen_get_monitor_at_point (manager->priv->current_screen, + pointer_x, + pointer_y); + } + + gdk_screen_get_monitor_geometry (manager->priv->current_screen, + monitor, + &geometry); + + screen_w = geometry.width; + screen_h = geometry.height; + + x = ((screen_w - orig_w) / 2) + geometry.x; + y = geometry.y + (screen_h / 2) + (screen_h / 2 - orig_h) / 2; + + gtk_window_move (GTK_WINDOW (manager->priv->dialog), x, y); + + gtk_widget_show (manager->priv->dialog); + + gdk_display_sync (gdk_screen_get_display (manager->priv->current_screen)); +} + +static void +do_unknown_action (GsdMediaKeysManager *manager, + const char *url) +{ + char *string; + + g_return_if_fail (url != NULL); + + string = mateconf_client_get_string (manager->priv->conf_client, + "/desktop/mate/url-handlers/unknown/command", + NULL); + + if ((string != NULL) && (strcmp (string, "") != 0)) { + char *cmd; + cmd = g_strdup_printf (string, url); + execute (manager, cmd, FALSE, FALSE); + g_free (cmd); + } + g_free (string); +} + +static void +do_help_action (GsdMediaKeysManager *manager) +{ + char *string; + + string = mateconf_client_get_string (manager->priv->conf_client, + "/desktop/mate/url-handlers/ghelp/command", + NULL); + + if ((string != NULL) && (strcmp (string, "") != 0)) { + char *cmd; + cmd = g_strdup_printf (string, ""); + execute (manager, cmd, FALSE, FALSE); + g_free (cmd); + } else { + do_unknown_action (manager, "ghelp:"); + } + + g_free (string); +} + +static void +do_mail_action (GsdMediaKeysManager *manager) +{ + char *string; + + string = mateconf_client_get_string (manager->priv->conf_client, + "/desktop/mate/url-handlers/mailto/command", + NULL); + + if ((string != NULL) && (strcmp (string, "") != 0)) { + char *cmd; + cmd = g_strdup_printf (string, ""); + execute (manager, + cmd, + FALSE, + mateconf_client_get_bool (manager->priv->conf_client, + "/desktop/mate/url-handlers/mailto/needs_terminal", NULL)); + g_free (cmd); + } + g_free (string); +} + +static void +do_media_action (GsdMediaKeysManager *manager) +{ + char *command; + + command = mateconf_client_get_string (manager->priv->conf_client, + "/desktop/mate/applications/media/exec", NULL); + if ((command != NULL) && (strcmp (command, "") != 0)) { + execute (manager, + command, + FALSE, + mateconf_client_get_bool (manager->priv->conf_client, + "/desktop/mate/applications/media/needs_term", NULL)); + } + g_free (command); +} + +static void +do_www_action (GsdMediaKeysManager *manager, + const char *url) +{ + char *string; + + string = mateconf_client_get_string (manager->priv->conf_client, + "/desktop/mate/url-handlers/http/command", + NULL); + + if ((string != NULL) && (strcmp (string, "") != 0)) { + gchar *cmd; + + if (url == NULL) { + cmd = g_strdup_printf (string, ""); + } else { + cmd = g_strdup_printf (string, url); + } + + execute (manager, + cmd, + FALSE, + mateconf_client_get_bool (manager->priv->conf_client, + "/desktop/mate/url-handlers/http/needs_terminal", NULL)); + g_free (cmd); + } else { + do_unknown_action (manager, url ? url : ""); + } + g_free (string); +} + +static void +do_exit_action (GsdMediaKeysManager *manager) +{ + execute (manager, "mate-session-save --shutdown-dialog", FALSE, FALSE); +} + +static void +do_eject_action_cb (GDrive *drive, + GAsyncResult *res, + GsdMediaKeysManager *manager) +{ + g_drive_eject_with_operation_finish (drive, res, NULL); +} + +#define NO_SCORE 0 +#define SCORE_CAN_EJECT 50 +#define SCORE_HAS_MEDIA 100 +static void +do_eject_action (GsdMediaKeysManager *manager) +{ + GList *drives, *l; + GDrive *fav_drive; + guint score; + + /* Find the best drive to eject */ + fav_drive = NULL; + score = NO_SCORE; + drives = g_volume_monitor_get_connected_drives (manager->priv->volume_monitor); + for (l = drives; l != NULL; l = l->next) { + GDrive *drive = l->data; + + if (g_drive_can_eject (drive) == FALSE) + continue; + if (g_drive_is_media_removable (drive) == FALSE) + continue; + if (score < SCORE_CAN_EJECT) { + fav_drive = drive; + score = SCORE_CAN_EJECT; + } + if (g_drive_has_media (drive) == FALSE) + continue; + if (score < SCORE_HAS_MEDIA) { + fav_drive = drive; + score = SCORE_HAS_MEDIA; + break; + } + } + + /* Show the dialogue */ + dialog_init (manager); + gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog), + "media-eject", + FALSE); + dialog_show (manager); + + /* Clean up the drive selection and exit if no suitable + * drives are found */ + if (fav_drive != NULL) + fav_drive = g_object_ref (fav_drive); + + g_list_foreach (drives, (GFunc) g_object_unref, NULL); + if (fav_drive == NULL) + return; + + /* Eject! */ + g_drive_eject_with_operation (fav_drive, G_MOUNT_UNMOUNT_FORCE, + NULL, NULL, + (GAsyncReadyCallback) do_eject_action_cb, + manager); + g_object_unref (fav_drive); +} + +static void +do_touchpad_action (GsdMediaKeysManager *manager) +{ + MateConfClient *client = manager->priv->conf_client; + gboolean state = mateconf_client_get_bool (client, TOUCHPAD_ENABLED_KEY, NULL); + + dialog_init (manager); + gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog), + (!state) ? "touchpad-enabled" : "touchpad-disabled", + FALSE); + dialog_show (manager); + + mateconf_client_set_bool (client, TOUCHPAD_ENABLED_KEY, !state, NULL); +} + +#ifdef HAVE_PULSE +static void +update_dialog (GsdMediaKeysManager *manager, + guint vol, + gboolean muted, + gboolean sound_changed) +{ + vol = (int) (100 * (double) vol / PA_VOLUME_NORM); + vol = CLAMP (vol, 0, 100); + + dialog_init (manager); + gsd_media_keys_window_set_volume_muted (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog), + muted); + gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog), vol); + gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog), + GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME); + dialog_show (manager); + + if (sound_changed != FALSE && muted == FALSE) + ca_gtk_play_for_widget (manager->priv->dialog, 0, + CA_PROP_EVENT_ID, "audio-volume-change", + CA_PROP_EVENT_DESCRIPTION, "volume changed through key press", + CA_PROP_APPLICATION_ID, "org.mate.VolumeControl", + NULL); +} + +static void +do_sound_action (GsdMediaKeysManager *manager, + int type) +{ + gboolean muted; + guint vol, norm_vol_step; + int vol_step; + gboolean sound_changed; + + if (manager->priv->stream == NULL) + return; + + vol_step = mateconf_client_get_int (manager->priv->conf_client, + MATECONF_MISC_DIR "/volume_step", + NULL); + + if (vol_step <= 0 || vol_step > 100) + vol_step = VOLUME_STEP; + + norm_vol_step = PA_VOLUME_NORM * vol_step / 100; + + /* FIXME: this is racy */ + vol = gvc_mixer_stream_get_volume (manager->priv->stream); + muted = gvc_mixer_stream_get_is_muted (manager->priv->stream); + sound_changed = FALSE; + + switch (type) { + case MUTE_KEY: + muted = !muted; + gvc_mixer_stream_change_is_muted (manager->priv->stream, muted); + sound_changed = TRUE; + break; + case VOLUME_DOWN_KEY: + if (!muted && (vol <= norm_vol_step)) { + muted = !muted; + vol = 0; + gvc_mixer_stream_change_is_muted (manager->priv->stream, muted); + if (gvc_mixer_stream_set_volume (manager->priv->stream, vol) != FALSE) { + gvc_mixer_stream_push_volume (manager->priv->stream); + sound_changed = TRUE; + } + } else if (!muted) { + vol = vol - norm_vol_step; + if (gvc_mixer_stream_set_volume (manager->priv->stream, vol) != FALSE) { + gvc_mixer_stream_push_volume (manager->priv->stream); + sound_changed = TRUE; + } + } + break; + case VOLUME_UP_KEY: + if (muted) { + muted = !muted; + if (vol == 0) { + vol = vol + norm_vol_step; + gvc_mixer_stream_change_is_muted (manager->priv->stream, muted); + if (gvc_mixer_stream_set_volume (manager->priv->stream, vol) != FALSE) { + gvc_mixer_stream_push_volume (manager->priv->stream); + sound_changed = TRUE; + } + } else { + gvc_mixer_stream_change_is_muted (manager->priv->stream, muted); + sound_changed = TRUE; + } + } else { + if (vol < MAX_VOLUME) { + if (vol + norm_vol_step >= MAX_VOLUME) { + vol = MAX_VOLUME; + } else { + vol = vol + norm_vol_step; + } + if (gvc_mixer_stream_set_volume (manager->priv->stream, vol) != FALSE) { + gvc_mixer_stream_push_volume (manager->priv->stream); + sound_changed = TRUE; + } + } + } + break; + } + + update_dialog (manager, vol, muted, sound_changed); +} + +static void +update_default_sink (GsdMediaKeysManager *manager) +{ + GvcMixerStream *stream; + + stream = gvc_mixer_control_get_default_sink (manager->priv->volume); + if (stream == manager->priv->stream) + return; + + if (manager->priv->stream != NULL) { + g_object_unref (manager->priv->stream); + manager->priv->stream = NULL; + } + + if (stream != NULL) { + manager->priv->stream = g_object_ref (stream); + } else { + g_warning ("Unable to get default sink"); + } +} + +static void +on_control_ready (GvcMixerControl *control, + GsdMediaKeysManager *manager) +{ + update_default_sink (manager); +} + +static void +on_control_default_sink_changed (GvcMixerControl *control, + guint id, + GsdMediaKeysManager *manager) +{ + update_default_sink (manager); +} + +#endif /* HAVE_PULSE */ + +static gint +find_by_application (gconstpointer a, + gconstpointer b) +{ + return strcmp (((MediaPlayer *)a)->application, b); +} + +static gint +find_by_time (gconstpointer a, + gconstpointer b) +{ + return ((MediaPlayer *)a)->time < ((MediaPlayer *)b)->time; +} + +/* + * Register a new media player. Most applications will want to call + * this with time = GDK_CURRENT_TIME. This way, the last registered + * player will receive media events. In some cases, applications + * may want to register with a lower priority (usually 1), to grab + * events only nobody is interested. + */ +gboolean +gsd_media_keys_manager_grab_media_player_keys (GsdMediaKeysManager *manager, + const char *application, + guint32 time, + GError **error) +{ + GList *iter; + MediaPlayer *media_player; + + if (time == GDK_CURRENT_TIME) { + GTimeVal tv; + + g_get_current_time (&tv); + time = tv.tv_sec * 1000 + tv.tv_usec / 1000; + } + + iter = g_list_find_custom (manager->priv->media_players, + application, + find_by_application); + + if (iter != NULL) { + if (((MediaPlayer *)iter->data)->time < time) { + g_free (((MediaPlayer *)iter->data)->application); + g_free (iter->data); + manager->priv->media_players = g_list_delete_link (manager->priv->media_players, iter); + } else { + return TRUE; + } + } + + g_debug ("Registering %s at %u", application, time); + media_player = g_new0 (MediaPlayer, 1); + media_player->application = g_strdup (application); + media_player->time = time; + + manager->priv->media_players = g_list_insert_sorted (manager->priv->media_players, + media_player, + find_by_time); + + return TRUE; +} + +gboolean +gsd_media_keys_manager_release_media_player_keys (GsdMediaKeysManager *manager, + const char *application, + GError **error) +{ + GList *iter; + + iter = g_list_find_custom (manager->priv->media_players, + application, + find_by_application); + + if (iter != NULL) { + g_debug ("Deregistering %s", application); + g_free (((MediaPlayer *)iter->data)->application); + g_free (iter->data); + manager->priv->media_players = g_list_delete_link (manager->priv->media_players, iter); + } + + return TRUE; +} + +static gboolean +gsd_media_player_key_pressed (GsdMediaKeysManager *manager, + const char *key) +{ + const char *application = NULL; + gboolean have_listeners; + + have_listeners = (manager->priv->media_players != NULL); + + if (have_listeners) { + application = ((MediaPlayer *)manager->priv->media_players->data)->application; + } + + g_signal_emit (manager, signals[MEDIA_PLAYER_KEY_PRESSED], 0, application, key); + + return !have_listeners; +} + +static gboolean +do_multimedia_player_action (GsdMediaKeysManager *manager, + const char *key) +{ + return gsd_media_player_key_pressed (manager, key); +} + +static gboolean +do_action (GsdMediaKeysManager *manager, + int type) +{ + char *cmd; + char *path; + + switch (type) { + case TOUCHPAD_KEY: + do_touchpad_action (manager); + break; + case MUTE_KEY: + case VOLUME_DOWN_KEY: + case VOLUME_UP_KEY: +#ifdef HAVE_PULSE + do_sound_action (manager, type); +#endif /* HAVE_PULSE */ + break; + case POWER_KEY: + do_exit_action (manager); + break; + case EJECT_KEY: + do_eject_action (manager); + break; + case HOME_KEY: + path = g_shell_quote (g_get_home_dir ()); + cmd = g_strconcat ("caja --no-desktop ", path, NULL); + g_free (path); + execute (manager, cmd, FALSE, FALSE); + g_free (cmd); + break; + case SEARCH_KEY: + cmd = NULL; + if ((cmd = g_find_program_in_path ("beagle-search"))) { + execute (manager, "beagle-search", FALSE, FALSE); + } else if ((cmd = g_find_program_in_path ("tracker-search-tool"))) { + execute (manager, "tracker-search-tool", FALSE, FALSE); + } else { + execute (manager, "mate-search-tool", FALSE, FALSE); + } + g_free (cmd); + break; + case EMAIL_KEY: + do_mail_action (manager); + break; + case SCREENSAVER_KEY: + if ((cmd = g_find_program_in_path ("mate-screensaver-command"))) { + execute (manager, "mate-screensaver-command --lock", FALSE, FALSE); + } else { + execute (manager, "xscreensaver-command -lock", FALSE, FALSE); + } + + g_free (cmd); + break; + case HELP_KEY: + do_help_action (manager); + break; + case WWW_KEY: + do_www_action (manager, NULL); + break; + case MEDIA_KEY: + do_media_action (manager); + break; + case CALCULATOR_KEY: + execute (manager, "gcalctool", FALSE, FALSE); + break; + case PLAY_KEY: + return do_multimedia_player_action (manager, "Play"); + break; + case PAUSE_KEY: + return do_multimedia_player_action (manager, "Pause"); + break; + case STOP_KEY: + return do_multimedia_player_action (manager, "Stop"); + break; + case PREVIOUS_KEY: + return do_multimedia_player_action (manager, "Previous"); + break; + case NEXT_KEY: + return do_multimedia_player_action (manager, "Next"); + break; + default: + g_assert_not_reached (); + } + + return FALSE; +} + +static GdkScreen * +acme_get_screen_from_event (GsdMediaKeysManager *manager, + XAnyEvent *xanyev) +{ + GdkWindow *window; + GdkScreen *screen; + GSList *l; + + /* Look for which screen we're receiving events */ + for (l = manager->priv->screens; l != NULL; l = l->next) { + screen = (GdkScreen *) l->data; + window = gdk_screen_get_root_window (screen); + + if (GDK_WINDOW_XID (window) == xanyev->window) { + return screen; + } + } + + return NULL; +} + +static GdkFilterReturn +acme_filter_events (GdkXEvent *xevent, + GdkEvent *event, + GsdMediaKeysManager *manager) +{ + XEvent *xev = (XEvent *) xevent; + XAnyEvent *xany = (XAnyEvent *) xevent; + int i; + + /* verify we have a key event */ + if (xev->type != KeyPress && xev->type != KeyRelease) { + return GDK_FILTER_CONTINUE; + } + + for (i = 0; i < HANDLED_KEYS; i++) { + if (match_key (keys[i].key, xev)) { + switch (keys[i].key_type) { + case VOLUME_DOWN_KEY: + case VOLUME_UP_KEY: + /* auto-repeatable keys */ + if (xev->type != KeyPress) { + return GDK_FILTER_CONTINUE; + } + break; + default: + if (xev->type != KeyRelease) { + return GDK_FILTER_CONTINUE; + } + } + + manager->priv->current_screen = acme_get_screen_from_event (manager, xany); + + if (do_action (manager, keys[i].key_type) == FALSE) { + return GDK_FILTER_REMOVE; + } else { + return GDK_FILTER_CONTINUE; + } + } + } + + return GDK_FILTER_CONTINUE; +} + +static gboolean +start_media_keys_idle_cb (GsdMediaKeysManager *manager) +{ + GSList *l; + + g_debug ("Starting media_keys manager"); + mate_settings_profile_start (NULL); + manager->priv->volume_monitor = g_volume_monitor_get (); + manager->priv->conf_client = mateconf_client_get_default (); + + mateconf_client_add_dir (manager->priv->conf_client, + MATECONF_BINDING_DIR, + MATECONF_CLIENT_PRELOAD_ONELEVEL, + NULL); + + init_screens (manager); + init_kbd (manager); + + /* Start filtering the events */ + for (l = manager->priv->screens; l != NULL; l = l->next) { + mate_settings_profile_start ("gdk_window_add_filter"); + + g_debug ("adding key filter for screen: %d", + gdk_screen_get_number (l->data)); + + gdk_window_add_filter (gdk_screen_get_root_window (l->data), + (GdkFilterFunc)acme_filter_events, + manager); + mate_settings_profile_end ("gdk_window_add_filter"); + } + + mate_settings_profile_end (NULL); + + return FALSE; +} + +gboolean +gsd_media_keys_manager_start (GsdMediaKeysManager *manager, + GError **error) +{ + mate_settings_profile_start (NULL); + +#ifdef HAVE_PULSE + /* initialise Volume handler + * + * We do this one here to force checking gstreamer cache, etc. + * The rest (grabbing and setting the keys) can happen in an + * idle. + */ + mate_settings_profile_start ("gvc_mixer_control_new"); + + manager->priv->volume = gvc_mixer_control_new ("MATE Volume Control Media Keys"); + + g_signal_connect (manager->priv->volume, + "ready", + G_CALLBACK (on_control_ready), + manager); + g_signal_connect (manager->priv->volume, + "default-sink-changed", + G_CALLBACK (on_control_default_sink_changed), + manager); + + gvc_mixer_control_open (manager->priv->volume); + + mate_settings_profile_end ("gvc_mixer_control_new"); +#endif /* HAVE_PULSE */ + g_idle_add ((GSourceFunc) start_media_keys_idle_cb, manager); + + mate_settings_profile_end (NULL); + + return TRUE; +} + +void +gsd_media_keys_manager_stop (GsdMediaKeysManager *manager) +{ + GsdMediaKeysManagerPrivate *priv = manager->priv; + GSList *ls; + GList *l; + int i; + gboolean need_flush; + + g_debug ("Stopping media_keys manager"); + + for (ls = priv->screens; ls != NULL; ls = ls->next) { + gdk_window_remove_filter (gdk_screen_get_root_window (ls->data), + (GdkFilterFunc) acme_filter_events, + manager); + } + + if (priv->conf_client) { + mateconf_client_remove_dir (priv->conf_client, + MATECONF_BINDING_DIR, + NULL); + + for (i = 0; i < HANDLED_KEYS; ++i) { + if (priv->notify[i] != 0) { + mateconf_client_notify_remove (priv->conf_client, priv->notify[i]); + priv->notify[i] = 0; + } + } + + g_object_unref (priv->conf_client); + priv->conf_client = NULL; + } + + if (priv->volume_monitor != NULL) { + g_object_unref (priv->volume_monitor); + priv->volume_monitor = NULL; + } + + if (priv->connection != NULL) { + dbus_g_connection_unref (priv->connection); + priv->connection = NULL; + } + + need_flush = FALSE; + gdk_error_trap_push (); + + for (i = 0; i < HANDLED_KEYS; ++i) { + if (keys[i].key) { + need_flush = TRUE; + grab_key_unsafe (keys[i].key, FALSE, priv->screens); + + g_free (keys[i].key->keycodes); + g_free (keys[i].key); + keys[i].key = NULL; + } + } + + if (need_flush) + gdk_flush (); + gdk_error_trap_pop (); + + g_slist_free (priv->screens); + priv->screens = NULL; + +#ifdef HAVE_PULSE + if (priv->stream) { + g_object_unref (priv->stream); + priv->stream = NULL; + } + + if (priv->volume) { + g_object_unref (priv->volume); + priv->volume = NULL; + } +#endif /* HAVE_PULSE */ + + if (priv->dialog != NULL) { + gtk_widget_destroy (priv->dialog); + priv->dialog = NULL; + } + + for (l = priv->media_players; l; l = l->next) { + MediaPlayer *mp = l->data; + g_free (mp->application); + g_free (mp); + } + g_list_free (priv->media_players); + priv->media_players = NULL; +} + +static void +gsd_media_keys_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GsdMediaKeysManager *self; + + self = GSD_MEDIA_KEYS_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gsd_media_keys_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GsdMediaKeysManager *self; + + self = GSD_MEDIA_KEYS_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +gsd_media_keys_manager_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GsdMediaKeysManager *media_keys_manager; + GsdMediaKeysManagerClass *klass; + + klass = GSD_MEDIA_KEYS_MANAGER_CLASS (g_type_class_peek (GSD_TYPE_MEDIA_KEYS_MANAGER)); + + media_keys_manager = GSD_MEDIA_KEYS_MANAGER (G_OBJECT_CLASS (gsd_media_keys_manager_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + + return G_OBJECT (media_keys_manager); +} + +static void +gsd_media_keys_manager_dispose (GObject *object) +{ + GsdMediaKeysManager *media_keys_manager; + + media_keys_manager = GSD_MEDIA_KEYS_MANAGER (object); + + G_OBJECT_CLASS (gsd_media_keys_manager_parent_class)->dispose (object); +} + +static void +gsd_media_keys_manager_class_init (GsdMediaKeysManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gsd_media_keys_manager_get_property; + object_class->set_property = gsd_media_keys_manager_set_property; + object_class->constructor = gsd_media_keys_manager_constructor; + object_class->dispose = gsd_media_keys_manager_dispose; + object_class->finalize = gsd_media_keys_manager_finalize; + + signals[MEDIA_PLAYER_KEY_PRESSED] = + g_signal_new ("media-player-key-pressed", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GsdMediaKeysManagerClass, media_player_key_pressed), + NULL, + NULL, + gsd_marshal_VOID__STRING_STRING, + G_TYPE_NONE, + 2, + G_TYPE_STRING, + G_TYPE_STRING); + + dbus_g_object_type_install_info (GSD_TYPE_MEDIA_KEYS_MANAGER, &dbus_glib_gsd_media_keys_manager_object_info); + + g_type_class_add_private (klass, sizeof (GsdMediaKeysManagerPrivate)); +} + +static void +gsd_media_keys_manager_init (GsdMediaKeysManager *manager) +{ + manager->priv = GSD_MEDIA_KEYS_MANAGER_GET_PRIVATE (manager); + +} + +static void +gsd_media_keys_manager_finalize (GObject *object) +{ + GsdMediaKeysManager *media_keys_manager; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_MEDIA_KEYS_MANAGER (object)); + + media_keys_manager = GSD_MEDIA_KEYS_MANAGER (object); + + g_return_if_fail (media_keys_manager->priv != NULL); + + G_OBJECT_CLASS (gsd_media_keys_manager_parent_class)->finalize (object); +} + +static gboolean +register_manager (GsdMediaKeysManager *manager) +{ + GError *error = NULL; + + manager->priv->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + if (manager->priv->connection == NULL) { + if (error != NULL) { + g_error ("Error getting session bus: %s", error->message); + g_error_free (error); + } + return FALSE; + } + + dbus_g_connection_register_g_object (manager->priv->connection, GSD_MEDIA_KEYS_DBUS_PATH, G_OBJECT (manager)); + + return TRUE; +} + +GsdMediaKeysManager * +gsd_media_keys_manager_new (void) +{ + if (manager_object != NULL) { + g_object_ref (manager_object); + } else { + gboolean res; + + manager_object = g_object_new (GSD_TYPE_MEDIA_KEYS_MANAGER, NULL); + g_object_add_weak_pointer (manager_object, + (gpointer *) &manager_object); + res = register_manager (manager_object); + if (! res) { + g_object_unref (manager_object); + return NULL; + } + } + + return GSD_MEDIA_KEYS_MANAGER (manager_object); +} diff --git a/plugins/media-keys/gsd-media-keys-manager.h b/plugins/media-keys/gsd-media-keys-manager.h new file mode 100644 index 0000000..19dafd5 --- /dev/null +++ b/plugins/media-keys/gsd-media-keys-manager.h @@ -0,0 +1,72 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann + * + * 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 __GSD_MEDIA_KEYS_MANAGER_H +#define __GSD_MEDIA_KEYS_MANAGER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_MEDIA_KEYS_MANAGER (gsd_media_keys_manager_get_type ()) +#define GSD_MEDIA_KEYS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_MEDIA_KEYS_MANAGER, GsdMediaKeysManager)) +#define GSD_MEDIA_KEYS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_MEDIA_KEYS_MANAGER, GsdMediaKeysManagerClass)) +#define GSD_IS_MEDIA_KEYS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_MEDIA_KEYS_MANAGER)) +#define GSD_IS_MEDIA_KEYS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_MEDIA_KEYS_MANAGER)) +#define GSD_MEDIA_KEYS_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_MEDIA_KEYS_MANAGER, GsdMediaKeysManagerClass)) + +typedef struct GsdMediaKeysManagerPrivate GsdMediaKeysManagerPrivate; + +typedef struct +{ + GObject parent; + GsdMediaKeysManagerPrivate *priv; +} GsdMediaKeysManager; + +typedef struct +{ + GObjectClass parent_class; + void (* media_player_key_pressed) (GsdMediaKeysManager *manager, + const char *application, + const char *key); +} GsdMediaKeysManagerClass; + +GType gsd_media_keys_manager_get_type (void); + +GsdMediaKeysManager * gsd_media_keys_manager_new (void); +gboolean gsd_media_keys_manager_start (GsdMediaKeysManager *manager, + GError **error); +void gsd_media_keys_manager_stop (GsdMediaKeysManager *manager); + +gboolean gsd_media_keys_manager_grab_media_player_keys (GsdMediaKeysManager *manager, + const char *application, + guint32 time, + GError **error); +gboolean gsd_media_keys_manager_release_media_player_keys (GsdMediaKeysManager *manager, + const char *application, + GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __GSD_MEDIA_KEYS_MANAGER_H */ diff --git a/plugins/media-keys/gsd-media-keys-manager.xml b/plugins/media-keys/gsd-media-keys-manager.xml new file mode 100644 index 0000000..12cd03a --- /dev/null +++ b/plugins/media-keys/gsd-media-keys-manager.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/plugins/media-keys/gsd-media-keys-plugin.c b/plugins/media-keys/gsd-media-keys-plugin.c new file mode 100644 index 0000000..319a42a --- /dev/null +++ b/plugins/media-keys/gsd-media-keys-plugin.c @@ -0,0 +1,104 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann + * + * 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, 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 +#include + +#include "mate-settings-plugin.h" +#include "gsd-media-keys-plugin.h" +#include "gsd-media-keys-manager.h" + +struct GsdMediaKeysPluginPrivate { + GsdMediaKeysManager *manager; +}; + +#define GSD_MEDIA_KEYS_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSD_TYPE_MEDIA_KEYS_PLUGIN, GsdMediaKeysPluginPrivate)) + +MATE_SETTINGS_PLUGIN_REGISTER (GsdMediaKeysPlugin, gsd_media_keys_plugin) + +static void +gsd_media_keys_plugin_init (GsdMediaKeysPlugin *plugin) +{ + plugin->priv = GSD_MEDIA_KEYS_PLUGIN_GET_PRIVATE (plugin); + + g_debug ("GsdMediaKeysPlugin initializing"); + + plugin->priv->manager = gsd_media_keys_manager_new (); +} + +static void +gsd_media_keys_plugin_finalize (GObject *object) +{ + GsdMediaKeysPlugin *plugin; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_MEDIA_KEYS_PLUGIN (object)); + + g_debug ("GsdMediaKeysPlugin finalizing"); + + plugin = GSD_MEDIA_KEYS_PLUGIN (object); + + g_return_if_fail (plugin->priv != NULL); + + if (plugin->priv->manager != NULL) { + g_object_unref (plugin->priv->manager); + } + + G_OBJECT_CLASS (gsd_media_keys_plugin_parent_class)->finalize (object); +} + +static void +impl_activate (MateSettingsPlugin *plugin) +{ + gboolean res; + GError *error; + + g_debug ("Activating media_keys plugin"); + + error = NULL; + res = gsd_media_keys_manager_start (GSD_MEDIA_KEYS_PLUGIN (plugin)->priv->manager, &error); + if (! res) { + g_warning ("Unable to start media_keys manager: %s", error->message); + g_error_free (error); + } +} + +static void +impl_deactivate (MateSettingsPlugin *plugin) +{ + g_debug ("Deactivating media_keys plugin"); + gsd_media_keys_manager_stop (GSD_MEDIA_KEYS_PLUGIN (plugin)->priv->manager); +} + +static void +gsd_media_keys_plugin_class_init (GsdMediaKeysPluginClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MateSettingsPluginClass *plugin_class = MATE_SETTINGS_PLUGIN_CLASS (klass); + + object_class->finalize = gsd_media_keys_plugin_finalize; + + plugin_class->activate = impl_activate; + plugin_class->deactivate = impl_deactivate; + + g_type_class_add_private (klass, sizeof (GsdMediaKeysPluginPrivate)); +} diff --git a/plugins/media-keys/gsd-media-keys-plugin.h b/plugins/media-keys/gsd-media-keys-plugin.h new file mode 100644 index 0000000..fa092b5 --- /dev/null +++ b/plugins/media-keys/gsd-media-keys-plugin.h @@ -0,0 +1,63 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann + * + * 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, 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 __GSD_MEDIA_KEYS_PLUGIN_H__ +#define __GSD_MEDIA_KEYS_PLUGIN_H__ + +#include +#include +#include + +#include "mate-settings-plugin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_MEDIA_KEYS_PLUGIN (gsd_media_keys_plugin_get_type ()) +#define GSD_MEDIA_KEYS_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_MEDIA_KEYS_PLUGIN, GsdMediaKeysPlugin)) +#define GSD_MEDIA_KEYS_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_MEDIA_KEYS_PLUGIN, GsdMediaKeysPluginClass)) +#define GSD_IS_MEDIA_KEYS_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_MEDIA_KEYS_PLUGIN)) +#define GSD_IS_MEDIA_KEYS_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_MEDIA_KEYS_PLUGIN)) +#define GSD_MEDIA_KEYS_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_MEDIA_KEYS_PLUGIN, GsdMediaKeysPluginClass)) + +typedef struct GsdMediaKeysPluginPrivate GsdMediaKeysPluginPrivate; + +typedef struct +{ + MateSettingsPlugin parent; + GsdMediaKeysPluginPrivate *priv; +} GsdMediaKeysPlugin; + +typedef struct +{ + MateSettingsPluginClass parent_class; +} GsdMediaKeysPluginClass; + +GType gsd_media_keys_plugin_get_type (void) G_GNUC_CONST; + +/* All the plugins must implement this function */ +G_MODULE_EXPORT GType register_mate_settings_plugin (GTypeModule *module); + +#ifdef __cplusplus +} +#endif + +#endif /* __GSD_MEDIA_KEYS_PLUGIN_H__ */ diff --git a/plugins/media-keys/gsd-media-keys-window.c b/plugins/media-keys/gsd-media-keys-window.c new file mode 100644 index 0000000..2547068 --- /dev/null +++ b/plugins/media-keys/gsd-media-keys-window.c @@ -0,0 +1,714 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2006-2007 William Jon McCann + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2, 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 Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser 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 +#include +#include +#include +#include +#include + +#include "gsd-media-keys-window.h" + +#define GSD_MEDIA_KEYS_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_MEDIA_KEYS_WINDOW, GsdMediaKeysWindowPrivate)) + +struct GsdMediaKeysWindowPrivate +{ + GsdMediaKeysWindowAction action; + char *icon_name; + gboolean show_level; + + guint volume_muted : 1; + int volume_level; + + GtkImage *image; + GtkWidget *progress; +}; + +G_DEFINE_TYPE (GsdMediaKeysWindow, gsd_media_keys_window, GSD_TYPE_OSD_WINDOW) + +static void +volume_controls_set_visible (GsdMediaKeysWindow *window, + gboolean visible) +{ + if (window->priv->progress == NULL) + return; + + if (visible) { + gtk_widget_show (window->priv->progress); + } else { + gtk_widget_hide (window->priv->progress); + } +} + +static void +window_set_icon_name (GsdMediaKeysWindow *window, + const char *name) +{ + if (window->priv->image == NULL) + return; + + gtk_image_set_from_icon_name (window->priv->image, + name, GTK_ICON_SIZE_DIALOG); +} + +static void +action_changed (GsdMediaKeysWindow *window) +{ + if (!gsd_osd_window_is_composited (GSD_OSD_WINDOW (window))) { + switch (window->priv->action) { + case GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME: + volume_controls_set_visible (window, TRUE); + + if (window->priv->volume_muted) { + window_set_icon_name (window, "audio-volume-muted"); + } else { + window_set_icon_name (window, "audio-volume-high"); + } + + break; + case GSD_MEDIA_KEYS_WINDOW_ACTION_CUSTOM: + volume_controls_set_visible (window, window->priv->show_level); + window_set_icon_name (window, window->priv->icon_name); + break; + default: + g_assert_not_reached (); + break; + } + } + + gsd_osd_window_update_and_hide (GSD_OSD_WINDOW (window)); +} + +static void +volume_level_changed (GsdMediaKeysWindow *window) +{ + gsd_osd_window_update_and_hide (GSD_OSD_WINDOW (window)); + + if (!gsd_osd_window_is_composited (GSD_OSD_WINDOW (window)) && window->priv->progress != NULL) { + double fraction; + + fraction = (double) window->priv->volume_level / 100.0; + + gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (window->priv->progress), + fraction); + } +} + +static void +volume_muted_changed (GsdMediaKeysWindow *window) +{ + gsd_osd_window_update_and_hide (GSD_OSD_WINDOW (window)); + + if (!gsd_osd_window_is_composited (GSD_OSD_WINDOW (window))) { + if (window->priv->volume_muted) { + window_set_icon_name (window, "audio-volume-muted"); + } else { + window_set_icon_name (window, "audio-volume-high"); + } + } +} + +void +gsd_media_keys_window_set_action (GsdMediaKeysWindow *window, + GsdMediaKeysWindowAction action) +{ + g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window)); + g_return_if_fail (action == GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME); + + if (window->priv->action != action) { + window->priv->action = action; + action_changed (window); + } else { + gsd_osd_window_update_and_hide (GSD_OSD_WINDOW (window)); + } +} + +void +gsd_media_keys_window_set_action_custom (GsdMediaKeysWindow *window, + const char *icon_name, + gboolean show_level) +{ + g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window)); + g_return_if_fail (icon_name != NULL); + + if (window->priv->action != GSD_MEDIA_KEYS_WINDOW_ACTION_CUSTOM || + g_strcmp0 (window->priv->icon_name, icon_name) != 0 || + window->priv->show_level != show_level) { + window->priv->action = GSD_MEDIA_KEYS_WINDOW_ACTION_CUSTOM; + g_free (window->priv->icon_name); + window->priv->icon_name = g_strdup (icon_name); + window->priv->show_level = show_level; + action_changed (window); + } else { + gsd_osd_window_update_and_hide (GSD_OSD_WINDOW (window)); + } +} + +void +gsd_media_keys_window_set_volume_muted (GsdMediaKeysWindow *window, + gboolean muted) +{ + g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window)); + + if (window->priv->volume_muted != muted) { + window->priv->volume_muted = muted; + volume_muted_changed (window); + } +} + +void +gsd_media_keys_window_set_volume_level (GsdMediaKeysWindow *window, + int level) +{ + g_return_if_fail (GSD_IS_MEDIA_KEYS_WINDOW (window)); + + if (window->priv->volume_level != level) { + window->priv->volume_level = level; + volume_level_changed (window); + } +} + +static GdkPixbuf * +load_pixbuf (GsdMediaKeysWindow *window, + const char *name, + int icon_size) +{ + GtkIconTheme *theme; + GdkPixbuf *pixbuf; + + if (window != NULL && gtk_widget_has_screen (GTK_WIDGET (window))) { + theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window))); + } else { + theme = gtk_icon_theme_get_default (); + } + + pixbuf = gtk_icon_theme_load_icon (theme, + name, + icon_size, + GTK_ICON_LOOKUP_FORCE_SIZE, + NULL); + + return pixbuf; +} + +static void +draw_eject (cairo_t *cr, + double _x0, + double _y0, + double width, + double height) +{ + int box_height; + int tri_height; + int separation; + + box_height = height * 0.2; + separation = box_height / 3; + tri_height = height - box_height - separation; + + cairo_rectangle (cr, _x0, _y0 + height - box_height, width, box_height); + + cairo_move_to (cr, _x0, _y0 + tri_height); + cairo_rel_line_to (cr, width, 0); + cairo_rel_line_to (cr, -width / 2, -tri_height); + cairo_rel_line_to (cr, -width / 2, tri_height); + cairo_close_path (cr); + cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, GSD_OSD_WINDOW_FG_ALPHA); + cairo_fill_preserve (cr); + + cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, GSD_OSD_WINDOW_FG_ALPHA / 2); + cairo_set_line_width (cr, 2); + cairo_stroke (cr); +} + +static void +draw_waves (cairo_t *cr, + double cx, + double cy, + double max_radius, + int volume_level) +{ + const int n_waves = 3; + int last_wave; + int i; + + last_wave = n_waves * volume_level / 100; + + for (i = 0; i < n_waves; i++) { + double angle1; + double angle2; + double radius; + double alpha; + + angle1 = -M_PI / 4; + angle2 = M_PI / 4; + + if (i < last_wave) + alpha = 1.0; + else if (i > last_wave) + alpha = 0.1; + else alpha = 0.1 + 0.9 * (n_waves * volume_level % 100) / 100.0; + + radius = (i + 1) * (max_radius / n_waves); + cairo_arc (cr, cx, cy, radius, angle1, angle2); + cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, alpha / 2); + cairo_set_line_width (cr, 14); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); + cairo_stroke_preserve (cr); + + cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, alpha); + cairo_set_line_width (cr, 10); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); + cairo_stroke (cr); + } +} + +static void +draw_cross (cairo_t *cr, + double cx, + double cy, + double size) +{ + cairo_move_to (cr, cx, cy - size/2.0); + cairo_rel_line_to (cr, size, size); + + cairo_move_to (cr, cx, cy + size/2.0); + cairo_rel_line_to (cr, size, -size); + + cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, GSD_OSD_WINDOW_FG_ALPHA / 2); + cairo_set_line_width (cr, 14); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); + cairo_stroke_preserve (cr); + + cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, GSD_OSD_WINDOW_FG_ALPHA); + cairo_set_line_width (cr, 10); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); + cairo_stroke (cr); +} + +static void +draw_speaker (cairo_t *cr, + double cx, + double cy, + double width, + double height) +{ + double box_width; + double box_height; + double _x0; + double _y0; + + box_width = width / 3; + box_height = height / 3; + + _x0 = cx - (width / 2) + box_width; + _y0 = cy - box_height / 2; + + cairo_move_to (cr, _x0, _y0); + cairo_rel_line_to (cr, - box_width, 0); + cairo_rel_line_to (cr, 0, box_height); + cairo_rel_line_to (cr, box_width, 0); + + cairo_line_to (cr, cx + box_width, cy + height / 2); + cairo_rel_line_to (cr, 0, -height); + cairo_line_to (cr, _x0, _y0); + cairo_close_path (cr); + + cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, GSD_OSD_WINDOW_FG_ALPHA); + cairo_fill_preserve (cr); + + cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, GSD_OSD_WINDOW_FG_ALPHA / 2); + cairo_set_line_width (cr, 2); + cairo_stroke (cr); +} + +static gboolean +render_speaker (GsdMediaKeysWindow *window, + cairo_t *cr, + double _x0, + double _y0, + double width, + double height) +{ + GdkPixbuf *pixbuf; + int icon_size; + int n; + static const char *icon_names[] = { + "audio-volume-muted", + "audio-volume-low", + "audio-volume-medium", + "audio-volume-high", + NULL + }; + + if (window->priv->volume_muted) { + n = 0; + } else { + /* select image */ + n = 3 * window->priv->volume_level / 100 + 1; + if (n < 1) { + n = 1; + } else if (n > 3) { + n = 3; + } + } + + icon_size = (int)width; + + pixbuf = load_pixbuf (window, icon_names[n], icon_size); + + if (pixbuf == NULL) { + return FALSE; + } + + gdk_cairo_set_source_pixbuf (cr, pixbuf, _x0, _y0); + cairo_paint_with_alpha (cr, GSD_OSD_WINDOW_FG_ALPHA); + + g_object_unref (pixbuf); + + return TRUE; +} + +static void +draw_volume_boxes (GsdMediaKeysWindow *window, + cairo_t *cr, + double percentage, + double _x0, + double _y0, + double width, + double height) +{ + gdouble x1; + GdkColor color; + double r, g, b; + GtkStyle *style; + + _x0 += 0.5; + _y0 += 0.5; + height = round (height) - 1; + width = round (width) - 1; + x1 = round ((width - 1) * percentage); + style = gtk_widget_get_style (GTK_WIDGET (window)); + + /* bar background */ + gsd_osd_window_color_reverse (&style->dark[GTK_STATE_NORMAL], &color); + r = (float)color.red / 65535.0; + g = (float)color.green / 65535.0; + b = (float)color.blue / 65535.0; + gsd_osd_window_draw_rounded_rectangle (cr, 1.0, _x0, _y0, height / 6, width, height); + cairo_set_source_rgba (cr, r, g, b, GSD_OSD_WINDOW_FG_ALPHA / 2); + cairo_fill_preserve (cr); + + /* bar border */ + gsd_osd_window_color_reverse (&style->light[GTK_STATE_NORMAL], &color); + r = (float)color.red / 65535.0; + g = (float)color.green / 65535.0; + b = (float)color.blue / 65535.0; + cairo_set_source_rgba (cr, r, g, b, GSD_OSD_WINDOW_FG_ALPHA / 2); + cairo_set_line_width (cr, 1); + cairo_stroke (cr); + + /* bar progress */ + if (percentage < 0.01) + return; + color = style->bg[GTK_STATE_NORMAL]; + r = (float)color.red / 65535.0; + g = (float)color.green / 65535.0; + b = (float)color.blue / 65535.0; + gsd_osd_window_draw_rounded_rectangle (cr, 1.0, _x0 + 0.5, _y0 + 0.5, height / 6 - 0.5, x1, height - 1); + cairo_set_source_rgba (cr, r, g, b, GSD_OSD_WINDOW_FG_ALPHA); + cairo_fill (cr); +} + +static void +draw_action_volume (GsdMediaKeysWindow *window, + cairo_t *cr) +{ + int window_width; + int window_height; + double icon_box_width; + double icon_box_height; + double icon_box_x0; + double icon_box_y0; + double volume_box_x0; + double volume_box_y0; + double volume_box_width; + double volume_box_height; + gboolean res; + + gtk_window_get_size (GTK_WINDOW (window), &window_width, &window_height); + + icon_box_width = round (window_width * 0.65); + icon_box_height = round (window_height * 0.65); + volume_box_width = icon_box_width; + volume_box_height = round (window_height * 0.05); + + icon_box_x0 = (window_width - icon_box_width) / 2; + icon_box_y0 = (window_height - icon_box_height - volume_box_height) / 2; + volume_box_x0 = round (icon_box_x0); + volume_box_y0 = round (icon_box_height + icon_box_y0); + +#if 0 + g_message ("icon box: w=%f h=%f _x0=%f _y0=%f", + icon_box_width, + icon_box_height, + icon_box_x0, + icon_box_y0); + g_message ("volume box: w=%f h=%f _x0=%f _y0=%f", + volume_box_width, + volume_box_height, + volume_box_x0, + volume_box_y0); +#endif + + res = render_speaker (window, + cr, + icon_box_x0, icon_box_y0, + icon_box_width, icon_box_height); + if (! res) { + double speaker_width; + double speaker_height; + double speaker_cx; + double speaker_cy; + + speaker_width = icon_box_width * 0.5; + speaker_height = icon_box_height * 0.75; + speaker_cx = icon_box_x0 + speaker_width / 2; + speaker_cy = icon_box_y0 + speaker_height / 2; + +#if 0 + g_message ("speaker box: w=%f h=%f cx=%f cy=%f", + speaker_width, + speaker_height, + speaker_cx, + speaker_cy); +#endif + + /* draw speaker symbol */ + draw_speaker (cr, speaker_cx, speaker_cy, speaker_width, speaker_height); + + if (! window->priv->volume_muted) { + /* draw sound waves */ + double wave_x0; + double wave_y0; + double wave_radius; + + wave_x0 = window_width / 2; + wave_y0 = speaker_cy; + wave_radius = icon_box_width / 2; + + draw_waves (cr, wave_x0, wave_y0, wave_radius, window->priv->volume_level); + } else { + /* draw 'mute' cross */ + double cross_x0; + double cross_y0; + double cross_size; + + cross_size = speaker_width * 3 / 4; + cross_x0 = icon_box_x0 + icon_box_width - cross_size; + cross_y0 = speaker_cy; + + draw_cross (cr, cross_x0, cross_y0, cross_size); + } + } + + /* draw volume meter */ + draw_volume_boxes (window, + cr, + (double)window->priv->volume_level / 100.0, + volume_box_x0, + volume_box_y0, + volume_box_width, + volume_box_height); +} + +static gboolean +render_custom (GsdMediaKeysWindow *window, + cairo_t *cr, + double _x0, + double _y0, + double width, + double height) +{ + GdkPixbuf *pixbuf; + int icon_size; + + icon_size = (int)width; + + pixbuf = load_pixbuf (window, window->priv->icon_name, icon_size); + + if (pixbuf == NULL) { + char *name; + if (gtk_widget_get_direction (GTK_WIDGET (window)) == GTK_TEXT_DIR_RTL) + name = g_strdup_printf ("%s-rtl", window->priv->icon_name); + else + name = g_strdup_printf ("%s-ltr", window->priv->icon_name); + pixbuf = load_pixbuf (window, name, icon_size); + g_free (name); + if (pixbuf == NULL) + return FALSE; + } + + gdk_cairo_set_source_pixbuf (cr, pixbuf, _x0, _y0); + cairo_paint_with_alpha (cr, GSD_OSD_WINDOW_FG_ALPHA); + + g_object_unref (pixbuf); + + return TRUE; +} + +static void +draw_action_custom (GsdMediaKeysWindow *window, + cairo_t *cr) +{ + int window_width; + int window_height; + double icon_box_width; + double icon_box_height; + double icon_box_x0; + double icon_box_y0; + double bright_box_x0; + double bright_box_y0; + double bright_box_width; + double bright_box_height; + gboolean res; + + gtk_window_get_size (GTK_WINDOW (window), &window_width, &window_height); + + icon_box_width = round (window_width * 0.65); + icon_box_height = round (window_height * 0.65); + bright_box_width = round (icon_box_width); + bright_box_height = round (window_height * 0.05); + + icon_box_x0 = (window_width - icon_box_width) / 2; + icon_box_y0 = (window_height - icon_box_height - bright_box_height) / 2; + bright_box_x0 = round (icon_box_x0); + bright_box_y0 = round (icon_box_height + icon_box_y0); + +#if 0 + g_message ("icon box: w=%f h=%f _x0=%f _y0=%f", + icon_box_width, + icon_box_height, + icon_box_x0, + icon_box_y0); + g_message ("brightness box: w=%f h=%f _x0=%f _y0=%f", + bright_box_width, + bright_box_height, + bright_box_x0, + bright_box_y0); +#endif + + res = render_custom (window, + cr, + icon_box_x0, icon_box_y0, + icon_box_width, icon_box_height); + if (! res && g_strcmp0 (window->priv->icon_name, "media-eject") == 0) { + /* draw eject symbol */ + draw_eject (cr, + icon_box_x0, icon_box_y0, + icon_box_width, icon_box_height); + } + + if (window->priv->show_level != FALSE) { + /* draw volume meter */ + draw_volume_boxes (window, + cr, + (double)window->priv->volume_level / 100.0, + bright_box_x0, + bright_box_y0, + bright_box_width, + bright_box_height); + } +} + +static void +gsd_media_keys_window_expose_when_composited (GsdOsdWindow *osd_window, + cairo_t *cr) +{ + GsdMediaKeysWindow *window = GSD_MEDIA_KEYS_WINDOW (osd_window); + + switch (window->priv->action) { + case GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME: + draw_action_volume (window, cr); + break; + case GSD_MEDIA_KEYS_WINDOW_ACTION_CUSTOM: + draw_action_custom (window, cr); + break; + default: + break; + } +} + +static void +gsd_media_keys_window_class_init (GsdMediaKeysWindowClass *klass) +{ + GsdOsdWindowClass *osd_window_class = GSD_OSD_WINDOW_CLASS (klass); + + osd_window_class->expose_when_composited = gsd_media_keys_window_expose_when_composited; + + g_type_class_add_private (klass, sizeof (GsdMediaKeysWindowPrivate)); +} + +static void +gsd_media_keys_window_init (GsdMediaKeysWindow *window) +{ + GdkScreen *screen; + + window->priv = GSD_MEDIA_KEYS_WINDOW_GET_PRIVATE (window); + + screen = gtk_widget_get_screen (GTK_WIDGET (window)); + + if (!gsd_osd_window_is_composited (GSD_OSD_WINDOW (window))) { + GtkBuilder *builder; + const gchar *objects[] = {"acme_box", NULL}; + GtkWidget *box; + + builder = gtk_builder_new (); + gtk_builder_add_objects_from_file (builder, + GTKBUILDERDIR "/acme.ui", + (char **) objects, + NULL); + + window->priv->image = GTK_IMAGE (gtk_builder_get_object (builder, "acme_image")); + window->priv->progress = GTK_WIDGET (gtk_builder_get_object (builder, "acme_volume_progressbar")); + box = GTK_WIDGET (gtk_builder_get_object (builder, "acme_box")); + + if (box != NULL) { + gtk_container_add (GTK_CONTAINER (window), box); + gtk_widget_show_all (box); + } + + /* The builder needs to stay alive until the window + takes ownership of the box (and its children) */ + g_object_unref (builder); + } +} + +GtkWidget * +gsd_media_keys_window_new (void) +{ + return g_object_new (GSD_TYPE_MEDIA_KEYS_WINDOW, NULL); +} diff --git a/plugins/media-keys/gsd-media-keys-window.h b/plugins/media-keys/gsd-media-keys-window.h new file mode 100644 index 0000000..236d011 --- /dev/null +++ b/plugins/media-keys/gsd-media-keys-window.h @@ -0,0 +1,78 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8; tab-width: 8 -*- + * + * Copyright (C) 2006 William Jon McCann + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2, 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 Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser 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 GSD_MEDIA_KEYS_WINDOW_H +#define GSD_MEDIA_KEYS_WINDOW_H + +#include +#include + +#include "gsd-osd-window.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_MEDIA_KEYS_WINDOW (gsd_media_keys_window_get_type ()) +#define GSD_MEDIA_KEYS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSD_TYPE_MEDIA_KEYS_WINDOW, GsdMediaKeysWindow)) +#define GSD_MEDIA_KEYS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSD_TYPE_MEDIA_KEYS_WINDOW, GsdMediaKeysWindowClass)) +#define GSD_IS_MEDIA_KEYS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSD_TYPE_MEDIA_KEYS_WINDOW)) +#define GSD_IS_MEDIA_KEYS_WINDOW_CLASS(klass) (G_TYPE_INSTANCE_GET_CLASS ((klass), GSD_TYPE_MEDIA_KEYS_WINDOW)) + +typedef struct GsdMediaKeysWindow GsdMediaKeysWindow; +typedef struct GsdMediaKeysWindowClass GsdMediaKeysWindowClass; +typedef struct GsdMediaKeysWindowPrivate GsdMediaKeysWindowPrivate; + +struct GsdMediaKeysWindow { + GsdOsdWindow parent; + + GsdMediaKeysWindowPrivate *priv; +}; + +struct GsdMediaKeysWindowClass { + GsdOsdWindowClass parent_class; +}; + +typedef enum { + GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME, + GSD_MEDIA_KEYS_WINDOW_ACTION_CUSTOM +} GsdMediaKeysWindowAction; + +GType gsd_media_keys_window_get_type (void); + +GtkWidget * gsd_media_keys_window_new (void); +void gsd_media_keys_window_set_action (GsdMediaKeysWindow *window, + GsdMediaKeysWindowAction action); +void gsd_media_keys_window_set_action_custom (GsdMediaKeysWindow *window, + const char *icon_name, + gboolean show_level); +void gsd_media_keys_window_set_volume_muted (GsdMediaKeysWindow *window, + gboolean muted); +void gsd_media_keys_window_set_volume_level (GsdMediaKeysWindow *window, + int level); +gboolean gsd_media_keys_window_is_valid (GsdMediaKeysWindow *window); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/plugins/media-keys/libmedia-keys.la b/plugins/media-keys/libmedia-keys.la new file mode 100644 index 0000000..26117f7 --- /dev/null +++ b/plugins/media-keys/libmedia-keys.la @@ -0,0 +1,41 @@ +# libmedia-keys.la - a libtool library file +# Generated by libtool (GNU libtool) 2.4 +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='libmedia-keys.so' + +# Names of this library. +library_names='libmedia-keys.so libmedia-keys.so libmedia-keys.so' + +# The name of the static archive. +old_library='libmedia-keys.a' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags=' -pthread' + +# Libraries that this one depends upon. +dependency_libs=' -lXext -lpulse-mainloop-glib -lpulse /usr/lib/libcanberra-gtk.la -lgobject-2.0 -lgthread-2.0 -lglib-2.0 -lfontconfig /usr/lib/libcanberra.la -lvorbisfile -lvorbis -logg -ltdb -lltdl /usr/lib/libmate-desktop-2.la /usr/lib/libmateconf-2.la /usr/lib/libMateCORBA-2.la -lXrandr /usr/lib/libgtk-x11-2.0.la /usr/lib/libstartup-notification-1.la -lSM -lICE /usr/lib/libgdk-x11-2.0.la /usr/lib/libatk-1.0.la /usr/lib/libpangocairo-1.0.la /usr/lib/libpangoft2-1.0.la /usr/lib/libgdk_pixbuf-2.0.la /usr/lib/libcairo.la -lpixman-1 -lpng14 -lXrender -lX11 /usr/lib/libpango-1.0.la /usr/lib/libfontconfig.la -lfreetype -lexpat /usr/lib/libgio-2.0.la -lresolv -lz /usr/lib/libgmodule-2.0.la -ldl /usr/lib/libdbus-glib-1.la /usr/lib/libdbus-1.la /usr/lib/libgobject-2.0.la /usr/lib/libgthread-2.0.la -lpthread -lrt /usr/lib/libglib-2.0.la -lm' + +# Names of additional weak libraries provided by this library +weak_library_names='' + +# Version information for libmedia-keys. +current=0 +age=0 +revision=0 + +# Is this an already installed library? +installed=no + +# Should we warn about portability when linking against -modules? +shouldnotlink=yes + +# Files to dlopen/dlpreopen +dlopen='' +dlpreopen='' + +# Directory that this library needs to be installed in: +libdir='/usr/lib/mate-settings-daemon-2.0' diff --git a/plugins/media-keys/media-keys.mate-settings-plugin b/plugins/media-keys/media-keys.mate-settings-plugin new file mode 100644 index 0000000..48b62bc --- /dev/null +++ b/plugins/media-keys/media-keys.mate-settings-plugin @@ -0,0 +1,136 @@ +[MATE Settings Plugin] +Module=media-keys +IAge=0 +Name=Media keys +Name[af]=Mediasleutels +Name[ar]=مفاتيح الوسائط +Name[as]=মিডিয়া কি +Name[ast]=Tecles multimedia +Name[be@latin]=Medyja-klavišy +Name[bg]=Мултимедийни клавиши +Name[bn]=মিডিয়া কী +Name[bn_IN]=মিডিয়া কি +Name[br]=Alc'hwezioù ar media +Name[ca]=Tecles multimèdia +Name[ca@valencia]=Tecles multimèdia +Name[crh]=Ortam tuşları +Name[cs]=Multimediální klávesy +Name[da]=Medietaster +Name[de]=Medientasten +Name[el]=Πλήκτρα πολυμέσων +Name[en@shaw]=𐑥𐑰𐑛𐑦𐑩 𐑒𐑰𐑟 +Name[en_GB]=Media keys +Name[es]=Teclas multimedia +Name[et]=Meediaklahvid +Name[eu]=Multimedia-teklak +Name[fi]=Medianäppäimet +Name[fr]=Touches multimédias +Name[ga]=Eochracha meán +Name[gl]=Teclas multimedia +Name[gu]=મીડિયા કીઓ +Name[he]=מקשי מדיה +Name[hi]=मीडिया कुंजी +Name[hu]=Médiabillentyűk +Name[id]=Kunci media +Name[it]=Tasti multimediali +Name[ja]=メディア・キー +Name[kn]=ಮೀಡಿಯಾ ಕೀಲಿಗಳು +Name[ko]=미디어 키 +Name[lt]=Multimedijos klavišai +Name[lv]=Mediju taustiņi +Name[mk]=Музички копчиња +Name[ml]=മാധ്യമ സംയോജകം +Name[mr]=मिडीया कि +Name[nb]=Medietaster +Name[nds]=Medienknöppe +Name[nl]=Mediatoetsen +Name[nn]=Mediatastar +Name[or]=ମେଡିଆ କିଗୁଡ଼ିକ +Name[pa]=ਮੀਡਿਆ ਸਵਿੱਚਾਂ +Name[pl]=Klawisze multimedialne +Name[pt]=Teclas de Media +Name[pt_BR]=Teclas de mídia +Name[ro]=Taste media +Name[ru]=Мультимедийные клавиши +Name[sk]=Multimediálne klávesy +Name[sl]=Večpredstavnostne tipke +Name[sr]=Мултимедијални тастери +Name[sr@latin]=Multimedijalni tasteri +Name[sv]=Mediatangenter +Name[ta]=ஊடக விசைகள் +Name[te]=మాద్యమం కీలు +Name[th]=ปุ่มสั่งการสื่อ +Name[tr]=Ortam tuşları +Name[uk]=Мультимедійний клавіші +Name[vi]=Phím nhạc/phim +Name[zh_CN]=媒体键 +Name[zh_HK]=多媒體按鍵 +Name[zh_TW]=多媒體按鍵 +Description=Media keys plugin +Description[af]=Inprop vir mediasleutels +Description[ar]=ملحق مفاتيح الوسائط +Description[as]=মিডিয়া-কি প্লাগ-ইন +Description[ast]=Complementu de tecles multimedia +Description[be@latin]=Plugin medyja-klavišaŭ +Description[bg]=Приставка за мултимедийни клавиши +Description[bn]=মিডিয়া-কি প্লাগ-ইন +Description[bn_IN]=মিডিয়া-কি প্লাগ-ইন +Description[br]=Enlugellad alc'hwezioù ar media +Description[ca]=Connector de les tecles multimèdia +Description[ca@valencia]=Connector de les tecles multimèdia +Description[crh]=Ortam tuşları eklentisi +Description[cs]=Zásuvný modul multimediálních kláves +Description[da]=Medietastmodul +Description[de]=Medientastenmodul +Description[el]=Πρόσθετη λειτουργία πλήκτρων πολυμέσων +Description[en@shaw]=𐑥𐑰𐑛𐑦𐑩 𐑒𐑰𐑟 𐑐𐑤𐑳𐑜𐑦𐑯 +Description[en_GB]=Media keys plugin +Description[es]=Complemento de teclas multimedia +Description[et]=Meediaklahvide plugin +Description[eu]=Multimedia-teklen plugina +Description[fi]=Medianäppäinten liitännäinen +Description[fr]=Greffon des touches multimédias +Description[ga]=Breiseán eochracha meán +Description[gl]=Engadido das teclas multimedia +Description[gu]=મીડિયા કી પલ્ગઇન +Description[he]=תוסף מקשי מדיה +Description[hi]=मीडिया कुंजी प्लगिन +Description[hu]=Médiabillentyűk bővítmény +Description[id]=Plugin kunci media +Description[it]=Plugin per i tasti multimediali +Description[ja]=メディア・キーのプラグイン +Description[kn]=ಮೀಡಿಯಾ ಕೀಲಿಗಳು ಪ್ಲಗ್ಇನ್ +Description[ko]=미디어 키 플러그인 +Description[lt]=Multimedijos klavišų įskiepis +Description[lv]=Mediju taustiņu spraudnis +Description[mk]=Додаток за копчињата за музика +Description[ml]= സംയോജകം +Description[mr]=मिडीया कि पल्गइन +Description[nb]=Tillegg for medietaster +Description[nds]=Medienknöppeplugin +Description[nl]=Mediatoetsen-plugin +Description[nn]=Tillegg for medietastar +Description[or]=ମେଡ଼ିଆ କିଗୁଡ଼ିକର ପ୍ଲଗଇନ +Description[pa]=ਮੀਡਿਆ ਸਵਿੱਚ ਪਲੱਗਇਨ +Description[pl]=Wtyczka klawiszy multimedialnych +Description[pt]=Plugin de teclas de media +Description[pt_BR]=Plug-in de teclas de mídia +Description[ro]=Modul taste media +Description[ru]=Модуль мультимедийных клавиш +Description[sk]=Modul multimediálnych kláves +Description[sl]=Vstavek večpredstavnostnih tipk +Description[sr]=Додатак за мултимедијалне тастере +Description[sr@latin]=Dodatak za multimedijalne tastere +Description[sv]=Insticksmodul för mediatangenter +Description[ta]=ஊடக விசைகள் சொருகி +Description[te]=మాద్యమం కీల ప్లగ్ఇన్ +Description[th]=ปลั๊กอินจัดการปุ่มสั่งการสื่อ +Description[tr]=Ortam tuşları eklentisi +Description[uk]=Модуль мультимедійних клавіш +Description[vi]=Phần mở rộng phím nhạc/phim +Description[zh_CN]=媒体键插件 +Description[zh_HK]=多媒體按鍵外掛程式 +Description[zh_TW]=多媒體按鍵外掛程式 +Authors= +Copyright=Copyright © 2007 +Website= diff --git a/plugins/media-keys/media-keys.mate-settings-plugin.in b/plugins/media-keys/media-keys.mate-settings-plugin.in new file mode 100644 index 0000000..fdaf931 --- /dev/null +++ b/plugins/media-keys/media-keys.mate-settings-plugin.in @@ -0,0 +1,8 @@ +[MATE Settings Plugin] +Module=media-keys +IAge=0 +_Name=Media keys +_Description=Media keys plugin +Authors= +Copyright=Copyright © 2007 +Website= diff --git a/plugins/media-keys/test-media-keys.c b/plugins/media-keys/test-media-keys.c new file mode 100644 index 0000000..e3345f9 --- /dev/null +++ b/plugins/media-keys/test-media-keys.c @@ -0,0 +1,64 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann + * + * 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 + +#include +#include + +#include "gsd-media-keys-manager.h" + +static GsdMediaKeysManager *manager = NULL; + +int +main (int argc, + char **argv) +{ + GError *error; + gboolean res; + +#ifdef ENABLE_NLS + bindtextdomain (GETTEXT_PACKAGE, MATE_SETTINGS_LOCALEDIR); +# ifdef HAVE_BIND_TEXTDOMAIN_CODESET + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); +# endif + textdomain (GETTEXT_PACKAGE); +#endif + + error = NULL; + if (! gtk_init_with_args (&argc, &argv, NULL, NULL, NULL, &error)) { + fprintf (stderr, "%s", error->message); + g_error_free (error); + exit (1); + } + + manager = gsd_media_keys_manager_new (); + + error = NULL; + res = gsd_media_keys_manager_start (manager, &error); + + gtk_main (); + + return 0; +} diff --git a/plugins/media-keys/test-media-window.c b/plugins/media-keys/test-media-window.c new file mode 100644 index 0000000..c97f3d9 --- /dev/null +++ b/plugins/media-keys/test-media-window.c @@ -0,0 +1,152 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann + * + * 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 + +#include +#include + +#include "gsd-media-keys-window.h" + +static gboolean +update_state (GtkWidget *window) +{ + static int count = 0; + + count++; + + switch (count) { + case 1: + gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (window), + 50); + gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (window), + GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME); + + gtk_widget_show (window); + break; + case 2: + gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (window), + 100); + gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (window), + GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME); + + gtk_widget_show (window); + break; + case 3: + gsd_media_keys_window_set_volume_muted (GSD_MEDIA_KEYS_WINDOW (window), + TRUE); + gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (window), + GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME); + + gtk_widget_show (window); + break; + case 4: + gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (window), + "media-eject", + FALSE); + + gtk_widget_show (window); + break; + case 5: + gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (window), + 0); + gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (window), + "gpm-brightness-lcd", + TRUE); + + gtk_widget_show (window); + break; + case 6: + gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (window), + 50); + gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (window), + "gpm-brightness-lcd", + TRUE); + + gtk_widget_show (window); + break; + case 7: + gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (window), + 100); + gsd_media_keys_window_set_action_custom (GSD_MEDIA_KEYS_WINDOW (window), + "gpm-brightness-lcd", + TRUE); + + gtk_widget_show (window); + break; + default: + gtk_main_quit (); + break; + } + + return TRUE; +} + +static void +test_window (void) +{ + GtkWidget *window; + + window = gsd_media_keys_window_new (); + gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER_ALWAYS); + + gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (window), + 0); + gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (window), + GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME); + + gtk_widget_show (window); + + g_timeout_add (3000, (GSourceFunc) update_state, window); +} + +int +main (int argc, + char **argv) +{ + GError *error = NULL; + +#ifdef ENABLE_NLS + bindtextdomain (GETTEXT_PACKAGE, MATE_SETTINGS_LOCALEDIR); +# ifdef HAVE_BIND_TEXTDOMAIN_CODESET + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); +# endif + textdomain (GETTEXT_PACKAGE); +#endif + + if (! gtk_init_with_args (&argc, &argv, NULL, NULL, NULL, &error)) { + fprintf (stderr, "%s", error->message); + g_error_free (error); + exit (1); + } + + gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), + DATADIR G_DIR_SEPARATOR_S "mate-power-manager" G_DIR_SEPARATOR_S "icons"); + + test_window (); + + gtk_main (); + + return 0; +} diff --git a/plugins/media-keys/touchpad-disabled-16.png b/plugins/media-keys/touchpad-disabled-16.png new file mode 100644 index 0000000..c8355de Binary files /dev/null and b/plugins/media-keys/touchpad-disabled-16.png differ diff --git a/plugins/media-keys/touchpad-disabled-22.png b/plugins/media-keys/touchpad-disabled-22.png new file mode 100644 index 0000000..706fbc7 Binary files /dev/null and b/plugins/media-keys/touchpad-disabled-22.png differ diff --git a/plugins/media-keys/touchpad-disabled-24.png b/plugins/media-keys/touchpad-disabled-24.png new file mode 100644 index 0000000..fc0bac7 Binary files /dev/null and b/plugins/media-keys/touchpad-disabled-24.png differ diff --git a/plugins/media-keys/touchpad-disabled-32.png b/plugins/media-keys/touchpad-disabled-32.png new file mode 100644 index 0000000..1311c60 Binary files /dev/null and b/plugins/media-keys/touchpad-disabled-32.png differ diff --git a/plugins/media-keys/touchpad-disabled-48.png b/plugins/media-keys/touchpad-disabled-48.png new file mode 100644 index 0000000..8f6ee03 Binary files /dev/null and b/plugins/media-keys/touchpad-disabled-48.png differ diff --git a/plugins/media-keys/touchpad-disabled-template.svg b/plugins/media-keys/touchpad-disabled-template.svg new file mode 100644 index 0000000..4d08198 --- /dev/null +++ b/plugins/media-keys/touchpad-disabled-template.svg @@ -0,0 +1,1172 @@ + + + + + Touchpad + + + + image/svg+xml + + Touchpad + + + Lapo Calamandrei + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/media-keys/touchpad-disabled.svg b/plugins/media-keys/touchpad-disabled.svg new file mode 100644 index 0000000..4f1b37f --- /dev/null +++ b/plugins/media-keys/touchpad-disabled.svg @@ -0,0 +1,833 @@ + + + + + Touchpad + + + + image/svg+xml + + Touchpad + + + Lapo Calamandrei + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/media-keys/touchpad-enabled-16.png b/plugins/media-keys/touchpad-enabled-16.png new file mode 100644 index 0000000..58fc1d4 Binary files /dev/null and b/plugins/media-keys/touchpad-enabled-16.png differ diff --git a/plugins/media-keys/touchpad-enabled-22.png b/plugins/media-keys/touchpad-enabled-22.png new file mode 100644 index 0000000..ae23118 Binary files /dev/null and b/plugins/media-keys/touchpad-enabled-22.png differ diff --git a/plugins/media-keys/touchpad-enabled-24.png b/plugins/media-keys/touchpad-enabled-24.png new file mode 100644 index 0000000..b8617e9 Binary files /dev/null and b/plugins/media-keys/touchpad-enabled-24.png differ diff --git a/plugins/media-keys/touchpad-enabled-32.png b/plugins/media-keys/touchpad-enabled-32.png new file mode 100644 index 0000000..7bbfa48 Binary files /dev/null and b/plugins/media-keys/touchpad-enabled-32.png differ diff --git a/plugins/media-keys/touchpad-enabled-48.png b/plugins/media-keys/touchpad-enabled-48.png new file mode 100644 index 0000000..ebad680 Binary files /dev/null and b/plugins/media-keys/touchpad-enabled-48.png differ diff --git a/plugins/media-keys/touchpad-enabled-template.svg b/plugins/media-keys/touchpad-enabled-template.svg new file mode 100644 index 0000000..fe07b68 --- /dev/null +++ b/plugins/media-keys/touchpad-enabled-template.svg @@ -0,0 +1,936 @@ + + + + + Touchpad + + + + image/svg+xml + + Touchpad + + + Lapo Calamandrei + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/media-keys/touchpad-enabled.svg b/plugins/media-keys/touchpad-enabled.svg new file mode 100644 index 0000000..98fa258 --- /dev/null +++ b/plugins/media-keys/touchpad-enabled.svg @@ -0,0 +1,581 @@ + + + + + Touchpad + + + + image/svg+xml + + Touchpad + + + Lapo Calamandrei + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.1