diff options
author | Perberos <[email protected]> | 2011-12-01 23:53:21 -0300 |
---|---|---|
committer | Perberos <[email protected]> | 2011-12-01 23:53:21 -0300 |
commit | 505cabbd3036081f26586cabc64c26e7769c0ec9 (patch) | |
tree | 09e0498bf572128f5c9ab551531cb28d6d75e992 /plugins | |
download | mate-settings-daemon-505cabbd3036081f26586cabc64c26e7769c0ec9.tar.bz2 mate-settings-daemon-505cabbd3036081f26586cabc64c26e7769c0ec9.tar.xz |
moving from https://github.com/perberos/mate-desktop-environment
Diffstat (limited to 'plugins')
233 files changed, 58174 insertions, 0 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am new file mode 100644 index 0000000..f84cdf9 --- /dev/null +++ b/plugins/Makefile.am @@ -0,0 +1,31 @@ +NULL = + +enabled_plugins = \ + a11y-keyboard \ + background \ + clipboard \ + datetime \ + dummy \ + font \ + housekeeping \ + keybindings \ + keyboard \ + media-keys \ + mouse \ + sound \ + typing-break \ + xrandr \ + xrdb \ + xsettings \ + $(NULL) + +disabled_plugins = $(NULL) + +if SMARTCARD_SUPPORT +enabled_plugins += smartcard +else +disabled_plugins += smartcard +endif + +SUBDIRS = common $(enabled_plugins) +DIST_SUBDIRS = $(SUBDIRS) $(disabled_plugins) diff --git a/plugins/Makefile.in b/plugins/Makefile.in new file mode 100644 index 0000000..82b4310 --- /dev/null +++ b/plugins/Makefile.in @@ -0,0 +1,630 @@ +# 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@ +@SMARTCARD_SUPPORT_TRUE@am__append_1 = smartcard +@SMARTCARD_SUPPORT_FALSE@am__append_2 = smartcard +subdir = plugins +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 = +SOURCES = +DIST_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 +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@ +NULL = +enabled_plugins = a11y-keyboard background clipboard datetime dummy \ + font housekeeping keybindings keyboard media-keys mouse sound \ + typing-break xrandr xrdb xsettings $(NULL) $(am__append_1) +disabled_plugins = $(NULL) $(am__append_2) +SUBDIRS = common $(enabled_plugins) +DIST_SUBDIRS = $(SUBDIRS) $(disabled_plugins) +all: all-recursive + +.SUFFIXES: +$(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/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plugins/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): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# 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: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: 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: + +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." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +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 -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + 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 \ + ctags ctags-recursive distclean 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 installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + 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/a11y-keyboard/Makefile.am b/plugins/a11y-keyboard/Makefile.am new file mode 100644 index 0000000..8396513 --- /dev/null +++ b/plugins/a11y-keyboard/Makefile.am @@ -0,0 +1,87 @@ +NULL = + +gtkbuilderdir = $(pkgdatadir) +gtkbuilder_DATA = \ + gsd-a11y-preferences-dialog.ui \ + $(NULL) + +noinst_PROGRAMS = \ + test-a11y-preferences-dialog \ + $(NULL) + +test_a11y_preferences_dialog_SOURCES = \ + gsd-a11y-preferences-dialog.c \ + gsd-a11y-preferences-dialog.h \ + test-a11y-preferences-dialog.c \ + $(NULL) + +test_a11y_preferences_dialog_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DPIXMAPDIR=\""$(pkgdatadir)"\" \ + -DGTKBUILDERDIR=\""$(pkgdatadir)"\" \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +test_a11y_preferences_dialog_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +test_a11y_preferences_dialog_LDADD = \ + $(SETTINGS_DAEMON_LIBS) \ + $(SETTINGS_PLUGIN_LIBS) \ + $(NULL) + +plugin_LTLIBRARIES = \ + liba11y-keyboard.la \ + $(NULL) + +liba11y_keyboard_la_SOURCES = \ + gsd-a11y-keyboard-plugin.h \ + gsd-a11y-keyboard-plugin.c \ + gsd-a11y-keyboard-manager.h \ + gsd-a11y-keyboard-manager.c \ + gsd-a11y-preferences-dialog.h \ + gsd-a11y-preferences-dialog.c \ + $(NULL) + +liba11y_keyboard_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + -DGTKBUILDERDIR=\""$(gtkbuilderdir)"\" \ + $(AM_CPPFLAGS) + +liba11y_keyboard_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(LIBMATENOTIFY_CFLAGS) \ + $(AM_CFLAGS) + +liba11y_keyboard_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) \ + $(NULL) + +liba11y_keyboard_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(XF86MISC_LIBS) \ + $(LIBMATENOTIFY_LIBS) \ + $(NULL) + +plugin_in_files = \ + a11y-keyboard.mate-settings-plugin.in \ + $(NULL) + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) + +EXTRA_DIST = \ + $(plugin_in_files) \ + $(gtkbuilder_DATA) \ + $(NULL) + +CLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +DISTCLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +@GSD_INTLTOOL_PLUGIN_RULE@ diff --git a/plugins/a11y-keyboard/Makefile.in b/plugins/a11y-keyboard/Makefile.in new file mode 100644 index 0000000..e0d9429 --- /dev/null +++ b/plugins/a11y-keyboard/Makefile.in @@ -0,0 +1,809 @@ +# 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@ +noinst_PROGRAMS = test-a11y-preferences-dialog$(EXEEXT) \ + $(am__EXEEXT_1) +subdir = plugins/a11y-keyboard +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 = +liba11y_keyboard_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__objects_1 = +am_liba11y_keyboard_la_OBJECTS = \ + liba11y_keyboard_la-gsd-a11y-keyboard-plugin.lo \ + liba11y_keyboard_la-gsd-a11y-keyboard-manager.lo \ + liba11y_keyboard_la-gsd-a11y-preferences-dialog.lo \ + $(am__objects_1) +liba11y_keyboard_la_OBJECTS = $(am_liba11y_keyboard_la_OBJECTS) +liba11y_keyboard_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(liba11y_keyboard_la_CFLAGS) $(CFLAGS) \ + $(liba11y_keyboard_la_LDFLAGS) $(LDFLAGS) -o $@ +am__EXEEXT_1 = +PROGRAMS = $(noinst_PROGRAMS) +am_test_a11y_preferences_dialog_OBJECTS = test_a11y_preferences_dialog-gsd-a11y-preferences-dialog.$(OBJEXT) \ + test_a11y_preferences_dialog-test-a11y-preferences-dialog.$(OBJEXT) \ + $(am__objects_1) +test_a11y_preferences_dialog_OBJECTS = \ + $(am_test_a11y_preferences_dialog_OBJECTS) +test_a11y_preferences_dialog_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +test_a11y_preferences_dialog_LINK = $(LIBTOOL) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(test_a11y_preferences_dialog_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 = $(liba11y_keyboard_la_SOURCES) \ + $(test_a11y_preferences_dialog_SOURCES) +DIST_SOURCES = $(liba11y_keyboard_la_SOURCES) \ + $(test_a11y_preferences_dialog_SOURCES) +DATA = $(gtkbuilder_DATA) $(plugin_DATA) +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 = +gtkbuilderdir = $(pkgdatadir) +gtkbuilder_DATA = \ + gsd-a11y-preferences-dialog.ui \ + $(NULL) + +test_a11y_preferences_dialog_SOURCES = \ + gsd-a11y-preferences-dialog.c \ + gsd-a11y-preferences-dialog.h \ + test-a11y-preferences-dialog.c \ + $(NULL) + +test_a11y_preferences_dialog_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DPIXMAPDIR=\""$(pkgdatadir)"\" \ + -DGTKBUILDERDIR=\""$(pkgdatadir)"\" \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +test_a11y_preferences_dialog_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +test_a11y_preferences_dialog_LDADD = \ + $(SETTINGS_DAEMON_LIBS) \ + $(SETTINGS_PLUGIN_LIBS) \ + $(NULL) + +plugin_LTLIBRARIES = \ + liba11y-keyboard.la \ + $(NULL) + +liba11y_keyboard_la_SOURCES = \ + gsd-a11y-keyboard-plugin.h \ + gsd-a11y-keyboard-plugin.c \ + gsd-a11y-keyboard-manager.h \ + gsd-a11y-keyboard-manager.c \ + gsd-a11y-preferences-dialog.h \ + gsd-a11y-preferences-dialog.c \ + $(NULL) + +liba11y_keyboard_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + -DGTKBUILDERDIR=\""$(gtkbuilderdir)"\" \ + $(AM_CPPFLAGS) + +liba11y_keyboard_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(LIBMATENOTIFY_CFLAGS) \ + $(AM_CFLAGS) + +liba11y_keyboard_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) \ + $(NULL) + +liba11y_keyboard_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(XF86MISC_LIBS) \ + $(LIBMATENOTIFY_LIBS) \ + $(NULL) + +plugin_in_files = \ + a11y-keyboard.mate-settings-plugin.in \ + $(NULL) + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) +EXTRA_DIST = \ + $(plugin_in_files) \ + $(gtkbuilder_DATA) \ + $(NULL) + +CLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +DISTCLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +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/a11y-keyboard/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plugins/a11y-keyboard/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 +liba11y-keyboard.la: $(liba11y_keyboard_la_OBJECTS) $(liba11y_keyboard_la_DEPENDENCIES) + $(liba11y_keyboard_la_LINK) -rpath $(plugindir) $(liba11y_keyboard_la_OBJECTS) $(liba11y_keyboard_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-a11y-preferences-dialog$(EXEEXT): $(test_a11y_preferences_dialog_OBJECTS) $(test_a11y_preferences_dialog_DEPENDENCIES) + @rm -f test-a11y-preferences-dialog$(EXEEXT) + $(test_a11y_preferences_dialog_LINK) $(test_a11y_preferences_dialog_OBJECTS) $(test_a11y_preferences_dialog_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liba11y_keyboard_la-gsd-a11y-keyboard-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liba11y_keyboard_la-gsd-a11y-keyboard-plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/liba11y_keyboard_la-gsd-a11y-preferences-dialog.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_a11y_preferences_dialog-gsd-a11y-preferences-dialog.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_a11y_preferences_dialog-test-a11y-preferences-dialog.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 $@ $< + +liba11y_keyboard_la-gsd-a11y-keyboard-plugin.lo: gsd-a11y-keyboard-plugin.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liba11y_keyboard_la_CPPFLAGS) $(CPPFLAGS) $(liba11y_keyboard_la_CFLAGS) $(CFLAGS) -MT liba11y_keyboard_la-gsd-a11y-keyboard-plugin.lo -MD -MP -MF $(DEPDIR)/liba11y_keyboard_la-gsd-a11y-keyboard-plugin.Tpo -c -o liba11y_keyboard_la-gsd-a11y-keyboard-plugin.lo `test -f 'gsd-a11y-keyboard-plugin.c' || echo '$(srcdir)/'`gsd-a11y-keyboard-plugin.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liba11y_keyboard_la-gsd-a11y-keyboard-plugin.Tpo $(DEPDIR)/liba11y_keyboard_la-gsd-a11y-keyboard-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-a11y-keyboard-plugin.c' object='liba11y_keyboard_la-gsd-a11y-keyboard-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) $(liba11y_keyboard_la_CPPFLAGS) $(CPPFLAGS) $(liba11y_keyboard_la_CFLAGS) $(CFLAGS) -c -o liba11y_keyboard_la-gsd-a11y-keyboard-plugin.lo `test -f 'gsd-a11y-keyboard-plugin.c' || echo '$(srcdir)/'`gsd-a11y-keyboard-plugin.c + +liba11y_keyboard_la-gsd-a11y-keyboard-manager.lo: gsd-a11y-keyboard-manager.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liba11y_keyboard_la_CPPFLAGS) $(CPPFLAGS) $(liba11y_keyboard_la_CFLAGS) $(CFLAGS) -MT liba11y_keyboard_la-gsd-a11y-keyboard-manager.lo -MD -MP -MF $(DEPDIR)/liba11y_keyboard_la-gsd-a11y-keyboard-manager.Tpo -c -o liba11y_keyboard_la-gsd-a11y-keyboard-manager.lo `test -f 'gsd-a11y-keyboard-manager.c' || echo '$(srcdir)/'`gsd-a11y-keyboard-manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liba11y_keyboard_la-gsd-a11y-keyboard-manager.Tpo $(DEPDIR)/liba11y_keyboard_la-gsd-a11y-keyboard-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-a11y-keyboard-manager.c' object='liba11y_keyboard_la-gsd-a11y-keyboard-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) $(liba11y_keyboard_la_CPPFLAGS) $(CPPFLAGS) $(liba11y_keyboard_la_CFLAGS) $(CFLAGS) -c -o liba11y_keyboard_la-gsd-a11y-keyboard-manager.lo `test -f 'gsd-a11y-keyboard-manager.c' || echo '$(srcdir)/'`gsd-a11y-keyboard-manager.c + +liba11y_keyboard_la-gsd-a11y-preferences-dialog.lo: gsd-a11y-preferences-dialog.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liba11y_keyboard_la_CPPFLAGS) $(CPPFLAGS) $(liba11y_keyboard_la_CFLAGS) $(CFLAGS) -MT liba11y_keyboard_la-gsd-a11y-preferences-dialog.lo -MD -MP -MF $(DEPDIR)/liba11y_keyboard_la-gsd-a11y-preferences-dialog.Tpo -c -o liba11y_keyboard_la-gsd-a11y-preferences-dialog.lo `test -f 'gsd-a11y-preferences-dialog.c' || echo '$(srcdir)/'`gsd-a11y-preferences-dialog.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/liba11y_keyboard_la-gsd-a11y-preferences-dialog.Tpo $(DEPDIR)/liba11y_keyboard_la-gsd-a11y-preferences-dialog.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-a11y-preferences-dialog.c' object='liba11y_keyboard_la-gsd-a11y-preferences-dialog.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) $(liba11y_keyboard_la_CPPFLAGS) $(CPPFLAGS) $(liba11y_keyboard_la_CFLAGS) $(CFLAGS) -c -o liba11y_keyboard_la-gsd-a11y-preferences-dialog.lo `test -f 'gsd-a11y-preferences-dialog.c' || echo '$(srcdir)/'`gsd-a11y-preferences-dialog.c + +test_a11y_preferences_dialog-gsd-a11y-preferences-dialog.o: gsd-a11y-preferences-dialog.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_a11y_preferences_dialog_CPPFLAGS) $(CPPFLAGS) $(test_a11y_preferences_dialog_CFLAGS) $(CFLAGS) -MT test_a11y_preferences_dialog-gsd-a11y-preferences-dialog.o -MD -MP -MF $(DEPDIR)/test_a11y_preferences_dialog-gsd-a11y-preferences-dialog.Tpo -c -o test_a11y_preferences_dialog-gsd-a11y-preferences-dialog.o `test -f 'gsd-a11y-preferences-dialog.c' || echo '$(srcdir)/'`gsd-a11y-preferences-dialog.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_a11y_preferences_dialog-gsd-a11y-preferences-dialog.Tpo $(DEPDIR)/test_a11y_preferences_dialog-gsd-a11y-preferences-dialog.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-a11y-preferences-dialog.c' object='test_a11y_preferences_dialog-gsd-a11y-preferences-dialog.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_a11y_preferences_dialog_CPPFLAGS) $(CPPFLAGS) $(test_a11y_preferences_dialog_CFLAGS) $(CFLAGS) -c -o test_a11y_preferences_dialog-gsd-a11y-preferences-dialog.o `test -f 'gsd-a11y-preferences-dialog.c' || echo '$(srcdir)/'`gsd-a11y-preferences-dialog.c + +test_a11y_preferences_dialog-gsd-a11y-preferences-dialog.obj: gsd-a11y-preferences-dialog.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_a11y_preferences_dialog_CPPFLAGS) $(CPPFLAGS) $(test_a11y_preferences_dialog_CFLAGS) $(CFLAGS) -MT test_a11y_preferences_dialog-gsd-a11y-preferences-dialog.obj -MD -MP -MF $(DEPDIR)/test_a11y_preferences_dialog-gsd-a11y-preferences-dialog.Tpo -c -o test_a11y_preferences_dialog-gsd-a11y-preferences-dialog.obj `if test -f 'gsd-a11y-preferences-dialog.c'; then $(CYGPATH_W) 'gsd-a11y-preferences-dialog.c'; else $(CYGPATH_W) '$(srcdir)/gsd-a11y-preferences-dialog.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_a11y_preferences_dialog-gsd-a11y-preferences-dialog.Tpo $(DEPDIR)/test_a11y_preferences_dialog-gsd-a11y-preferences-dialog.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-a11y-preferences-dialog.c' object='test_a11y_preferences_dialog-gsd-a11y-preferences-dialog.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_a11y_preferences_dialog_CPPFLAGS) $(CPPFLAGS) $(test_a11y_preferences_dialog_CFLAGS) $(CFLAGS) -c -o test_a11y_preferences_dialog-gsd-a11y-preferences-dialog.obj `if test -f 'gsd-a11y-preferences-dialog.c'; then $(CYGPATH_W) 'gsd-a11y-preferences-dialog.c'; else $(CYGPATH_W) '$(srcdir)/gsd-a11y-preferences-dialog.c'; fi` + +test_a11y_preferences_dialog-test-a11y-preferences-dialog.o: test-a11y-preferences-dialog.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_a11y_preferences_dialog_CPPFLAGS) $(CPPFLAGS) $(test_a11y_preferences_dialog_CFLAGS) $(CFLAGS) -MT test_a11y_preferences_dialog-test-a11y-preferences-dialog.o -MD -MP -MF $(DEPDIR)/test_a11y_preferences_dialog-test-a11y-preferences-dialog.Tpo -c -o test_a11y_preferences_dialog-test-a11y-preferences-dialog.o `test -f 'test-a11y-preferences-dialog.c' || echo '$(srcdir)/'`test-a11y-preferences-dialog.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_a11y_preferences_dialog-test-a11y-preferences-dialog.Tpo $(DEPDIR)/test_a11y_preferences_dialog-test-a11y-preferences-dialog.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-a11y-preferences-dialog.c' object='test_a11y_preferences_dialog-test-a11y-preferences-dialog.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_a11y_preferences_dialog_CPPFLAGS) $(CPPFLAGS) $(test_a11y_preferences_dialog_CFLAGS) $(CFLAGS) -c -o test_a11y_preferences_dialog-test-a11y-preferences-dialog.o `test -f 'test-a11y-preferences-dialog.c' || echo '$(srcdir)/'`test-a11y-preferences-dialog.c + +test_a11y_preferences_dialog-test-a11y-preferences-dialog.obj: test-a11y-preferences-dialog.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_a11y_preferences_dialog_CPPFLAGS) $(CPPFLAGS) $(test_a11y_preferences_dialog_CFLAGS) $(CFLAGS) -MT test_a11y_preferences_dialog-test-a11y-preferences-dialog.obj -MD -MP -MF $(DEPDIR)/test_a11y_preferences_dialog-test-a11y-preferences-dialog.Tpo -c -o test_a11y_preferences_dialog-test-a11y-preferences-dialog.obj `if test -f 'test-a11y-preferences-dialog.c'; then $(CYGPATH_W) 'test-a11y-preferences-dialog.c'; else $(CYGPATH_W) '$(srcdir)/test-a11y-preferences-dialog.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_a11y_preferences_dialog-test-a11y-preferences-dialog.Tpo $(DEPDIR)/test_a11y_preferences_dialog-test-a11y-preferences-dialog.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-a11y-preferences-dialog.c' object='test_a11y_preferences_dialog-test-a11y-preferences-dialog.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_a11y_preferences_dialog_CPPFLAGS) $(CPPFLAGS) $(test_a11y_preferences_dialog_CFLAGS) $(CFLAGS) -c -o test_a11y_preferences_dialog-test-a11y-preferences-dialog.obj `if test -f 'test-a11y-preferences-dialog.c'; then $(CYGPATH_W) 'test-a11y-preferences-dialog.c'; else $(CYGPATH_W) '$(srcdir)/test-a11y-preferences-dialog.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 + +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) $(PROGRAMS) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(gtkbuilderdir)" "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -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." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + clean-pluginLTLIBRARIES 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-gtkbuilderDATA install-pluginDATA \ + install-pluginLTLIBRARIES + +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: uninstall-gtkbuilderDATA uninstall-pluginDATA \ + uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstPROGRAMS clean-pluginLTLIBRARIES \ + 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-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 \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-gtkbuilderDATA uninstall-pluginDATA \ + uninstall-pluginLTLIBRARIES + + +@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/a11y-keyboard/a11y-keyboard.mate-settings-plugin.in b/plugins/a11y-keyboard/a11y-keyboard.mate-settings-plugin.in new file mode 100644 index 0000000..4909948 --- /dev/null +++ b/plugins/a11y-keyboard/a11y-keyboard.mate-settings-plugin.in @@ -0,0 +1,8 @@ +[MATE Settings Plugin] +Module=a11y-keyboard +IAge=0 +_Name=Accessibility Keyboard +_Description=Accessibility keyboard plugin +Authors=Jody Goldberg +Copyright=Copyright © 2001 Ximian, Inc. +Website= diff --git a/plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c b/plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c new file mode 100644 index 0000000..ac75491 --- /dev/null +++ b/plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c @@ -0,0 +1,1347 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright © 2001 Ximian, Inc. + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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 <sys/types.h> +#include <sys/wait.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> + +#include <locale.h> + +#include <glib.h> +#include <glib/gi18n.h> +#include <gdk/gdk.h> +#include <gdk/gdkx.h> +#include <gtk/gtk.h> +#include <mateconf/mateconf-client.h> + +#include <X11/XKBlib.h> +#include <X11/extensions/XKBstr.h> + +#ifdef HAVE_X11_EXTENSIONS_XINPUT_H +#include <X11/extensions/XInput.h> +#include <X11/extensions/XIproto.h> +#endif + +#ifdef HAVE_LIBMATENOTIFY +#include <libmatenotify/notify.h> +#endif /* HAVE_LIBMATENOTIFY */ + +#include "mate-settings-profile.h" +#include "gsd-a11y-keyboard-manager.h" +#include "gsd-a11y-preferences-dialog.h" + +#define CONFIG_ROOT "/desktop/mate/accessibility/keyboard" +#define NOTIFICATION_TIMEOUT 30 + +#define GSD_A11Y_KEYBOARD_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_A11Y_KEYBOARD_MANAGER, GsdA11yKeyboardManagerPrivate)) + +struct GsdA11yKeyboardManagerPrivate +{ + int xkbEventBase; + gboolean stickykeys_shortcut_val; + gboolean slowkeys_shortcut_val; + GtkWidget *stickykeys_alert; + GtkWidget *slowkeys_alert; + GtkWidget *preferences_dialog; + GtkStatusIcon *status_icon; + XkbDescRec *original_xkb_desc; + + guint mateconf_notify; + +#ifdef HAVE_LIBMATENOTIFY + NotifyNotification *notification; +#endif /* HAVE_LIBMATENOTIFY */ +}; + +static void gsd_a11y_keyboard_manager_class_init (GsdA11yKeyboardManagerClass *klass); +static void gsd_a11y_keyboard_manager_init (GsdA11yKeyboardManager *a11y_keyboard_manager); +static void gsd_a11y_keyboard_manager_finalize (GObject *object); +static void gsd_a11y_keyboard_manager_ensure_status_icon (GsdA11yKeyboardManager *manager); +static void set_server_from_mateconf (GsdA11yKeyboardManager *manager, + MateConfClient *client); + +G_DEFINE_TYPE (GsdA11yKeyboardManager, gsd_a11y_keyboard_manager, G_TYPE_OBJECT) + +static gpointer manager_object = NULL; + +#undef DEBUG_ACCESSIBILITY +#ifdef DEBUG_ACCESSIBILITY +#define d(str) g_debug (str) +#else +#define d(str) do { } while (0) +#endif + +#ifdef HAVE_X11_EXTENSIONS_XINPUT_H +static GdkFilterReturn +devicepresence_filter (GdkXEvent *xevent, + GdkEvent *event, + gpointer data) +{ + XEvent *xev = (XEvent *) xevent; + XEventClass class_presence; + int xi_presence; + + DevicePresence (gdk_x11_get_default_xdisplay (), xi_presence, class_presence); + + if (xev->type == xi_presence) + { + XDevicePresenceNotifyEvent *dpn = (XDevicePresenceNotifyEvent *) xev; + if (dpn->devchange == DeviceEnabled) { + MateConfClient *client; + client = mateconf_client_get_default (); + set_server_from_mateconf (data, client); + g_object_unref (client); + } + } + return GDK_FILTER_CONTINUE; +} + +static gboolean +supports_xinput_devices (void) +{ + gint op_code, event, error; + + return XQueryExtension (GDK_DISPLAY (), + "XInputExtension", + &op_code, + &event, + &error); +} + +static void +set_devicepresence_handler (GsdA11yKeyboardManager *manager) +{ + Display *display; + XEventClass class_presence; + int xi_presence; + + if (!supports_xinput_devices ()) + return; + + display = gdk_x11_get_default_xdisplay (); + + gdk_error_trap_push (); + DevicePresence (display, xi_presence, class_presence); + /* FIXME: + * Note that this might overwrite other events, see: + * https://bugzilla.gnome.org/show_bug.cgi?id=610245#c2 + **/ + XSelectExtensionEvent (display, + RootWindow (display, DefaultScreen (display)), + &class_presence, 1); + + gdk_flush (); + if (!gdk_error_trap_pop ()) + gdk_window_add_filter (NULL, devicepresence_filter, manager); +} +#endif + +static gboolean +xkb_enabled (GsdA11yKeyboardManager *manager) +{ + gboolean have_xkb; + int opcode, errorBase, major, minor; + + have_xkb = XkbQueryExtension (GDK_DISPLAY (), + &opcode, + &manager->priv->xkbEventBase, + &errorBase, + &major, + &minor) + && XkbUseExtension (GDK_DISPLAY (), &major, &minor); + + return have_xkb; +} + +static XkbDescRec * +get_xkb_desc_rec (GsdA11yKeyboardManager *manager) +{ + XkbDescRec *desc; + Status status = Success; + + gdk_error_trap_push (); + desc = XkbGetMap (GDK_DISPLAY (), XkbAllMapComponentsMask, XkbUseCoreKbd); + if (desc != NULL) { + desc->ctrls = NULL; + status = XkbGetControls (GDK_DISPLAY (), XkbAllControlsMask, desc); + } + gdk_error_trap_pop (); + + g_return_val_if_fail (desc != NULL, NULL); + g_return_val_if_fail (desc->ctrls != NULL, NULL); + g_return_val_if_fail (status == Success, NULL); + + return desc; +} + +static int +get_int (MateConfClient *client, + char const *key) +{ + int res = mateconf_client_get_int (client, key, NULL); + if (res <= 0) { + res = 1; + } + return res; +} + +static gboolean +set_int (MateConfClient *client, + MateConfChangeSet *cs, + char const *key, + int val) +{ + mateconf_change_set_set_int (cs, key, val); +#ifdef DEBUG_ACCESSIBILITY + if (val != mateconf_client_get_int (client, key, NULL)) { + g_warning ("%s changed", key); + } +#endif + return val != mateconf_client_get_int (client, key, NULL); +} + +static gboolean +set_bool (MateConfClient *client, + MateConfChangeSet *cs, + char const *key, + int val) +{ + gboolean bval = (val != 0); + + mateconf_change_set_set_bool (cs, key, bval ? TRUE : FALSE); +#ifdef DEBUG_ACCESSIBILITY + if (bval != mateconf_client_get_bool (client, key, NULL)) { + d ("%s changed", key); + return TRUE; + } +#endif + return (bval != mateconf_client_get_bool (client, key, NULL)); +} + +static unsigned long +set_clear (gboolean flag, + unsigned long value, + unsigned long mask) +{ + if (flag) { + return value | mask; + } + return value & ~mask; +} + +static gboolean +set_ctrl_from_mateconf (XkbDescRec *desc, + MateConfClient *client, + char const *key, + unsigned long mask) +{ + gboolean result = mateconf_client_get_bool (client, key, NULL); + desc->ctrls->enabled_ctrls = set_clear (result, desc->ctrls->enabled_ctrls, mask); + return result; +} + +static void +set_server_from_mateconf (GsdA11yKeyboardManager *manager, + MateConfClient *client) +{ + XkbDescRec *desc; + gboolean enable_accessX; + + mate_settings_profile_start (NULL); + + desc = get_xkb_desc_rec (manager); + if (!desc) { + return; + } + + /* general */ + enable_accessX = mateconf_client_get_bool (client, CONFIG_ROOT "/enable", NULL); + + desc->ctrls->enabled_ctrls = set_clear (enable_accessX, + desc->ctrls->enabled_ctrls, + XkbAccessXKeysMask); + + if (set_ctrl_from_mateconf (desc, client, CONFIG_ROOT "/timeout_enable", + XkbAccessXTimeoutMask)) { + desc->ctrls->ax_timeout = get_int (client, + CONFIG_ROOT "/timeout"); + /* disable only the master flag via the server we will disable + * the rest on the rebound without affecting mateconf state + * don't change the option flags at all. + */ + desc->ctrls->axt_ctrls_mask = XkbAccessXKeysMask | XkbAccessXFeedbackMask; + desc->ctrls->axt_ctrls_values = 0; + desc->ctrls->axt_opts_mask = 0; + } + + desc->ctrls->ax_options = set_clear (mateconf_client_get_bool (client, CONFIG_ROOT "/feature_state_change_beep", NULL), + desc->ctrls->ax_options, + XkbAccessXFeedbackMask | XkbAX_FeatureFBMask | XkbAX_SlowWarnFBMask); + + /* bounce keys */ + if (set_ctrl_from_mateconf (desc, + client, + CONFIG_ROOT "/bouncekeys_enable", + XkbBounceKeysMask)) { + desc->ctrls->debounce_delay = get_int (client, + CONFIG_ROOT "/bouncekeys_delay"); + desc->ctrls->ax_options = set_clear (mateconf_client_get_bool (client, CONFIG_ROOT "/bouncekeys_beep_reject", NULL), + desc->ctrls->ax_options, + XkbAccessXFeedbackMask | XkbAX_BKRejectFBMask); + } + + /* mouse keys */ + if (set_ctrl_from_mateconf (desc, + client, + CONFIG_ROOT "/mousekeys_enable", + XkbMouseKeysMask | XkbMouseKeysAccelMask)) { + desc->ctrls->mk_interval = 100; /* msec between mousekey events */ + desc->ctrls->mk_curve = 50; + + /* We store pixels / sec, XKB wants pixels / event */ + desc->ctrls->mk_max_speed = get_int (client, + CONFIG_ROOT "/mousekeys_max_speed") / (1000 / desc->ctrls->mk_interval); + if (desc->ctrls->mk_max_speed <= 0) + desc->ctrls->mk_max_speed = 1; + + desc->ctrls->mk_time_to_max = get_int (client, /* events before max */ + CONFIG_ROOT "/mousekeys_accel_time") / desc->ctrls->mk_interval; + if (desc->ctrls->mk_time_to_max <= 0) + desc->ctrls->mk_time_to_max = 1; + + desc->ctrls->mk_delay = get_int (client, /* ms before 1st event */ + CONFIG_ROOT "/mousekeys_init_delay"); + } + + /* slow keys */ + if (set_ctrl_from_mateconf (desc, + client, + CONFIG_ROOT "/slowkeys_enable", + XkbSlowKeysMask)) { + desc->ctrls->ax_options = set_clear (mateconf_client_get_bool (client, CONFIG_ROOT "/slowkeys_beep_press", NULL), + desc->ctrls->ax_options, + XkbAccessXFeedbackMask | XkbAX_SKPressFBMask); + desc->ctrls->ax_options = set_clear (mateconf_client_get_bool (client, CONFIG_ROOT "/slowkeys_beep_accept", NULL), + desc->ctrls->ax_options, + XkbAccessXFeedbackMask | XkbAX_SKAcceptFBMask); + desc->ctrls->ax_options = set_clear (mateconf_client_get_bool (client, CONFIG_ROOT "/slowkeys_beep_reject", NULL), + desc->ctrls->ax_options, + XkbAccessXFeedbackMask | XkbAX_SKRejectFBMask); + desc->ctrls->slow_keys_delay = get_int (client, + CONFIG_ROOT "/slowkeys_delay"); + /* anything larger than 500 seems to loose all keyboard input */ + if (desc->ctrls->slow_keys_delay > 500) + desc->ctrls->slow_keys_delay = 500; + } + + /* sticky keys */ + if (set_ctrl_from_mateconf (desc, + client, + CONFIG_ROOT "/stickykeys_enable", + XkbStickyKeysMask)) { + desc->ctrls->ax_options |= XkbAX_LatchToLockMask; + desc->ctrls->ax_options = set_clear (mateconf_client_get_bool (client, CONFIG_ROOT "/stickykeys_two_key_off", NULL), + desc->ctrls->ax_options, + XkbAccessXFeedbackMask | XkbAX_TwoKeysMask); + desc->ctrls->ax_options = set_clear (mateconf_client_get_bool (client, CONFIG_ROOT "/stickykeys_modifier_beep", NULL), + desc->ctrls->ax_options, + XkbAccessXFeedbackMask | XkbAX_StickyKeysFBMask); + } + + /* toggle keys */ + desc->ctrls->ax_options = set_clear (mateconf_client_get_bool (client, CONFIG_ROOT "/togglekeys_enable", NULL), + desc->ctrls->ax_options, + XkbAccessXFeedbackMask | XkbAX_IndicatorFBMask); + + /* + g_debug ("CHANGE to : 0x%x", desc->ctrls->enabled_ctrls); + g_debug ("CHANGE to : 0x%x (2)", desc->ctrls->ax_options); + */ + + gdk_error_trap_push (); + XkbSetControls (GDK_DISPLAY (), + XkbSlowKeysMask | + XkbBounceKeysMask | + XkbStickyKeysMask | + XkbMouseKeysMask | + XkbMouseKeysAccelMask | + XkbAccessXKeysMask | + XkbAccessXTimeoutMask | + XkbAccessXFeedbackMask | + XkbControlsEnabledMask, + desc); + + XkbFreeKeyboard (desc, XkbAllComponentsMask, True); + + XSync (GDK_DISPLAY (), FALSE); + gdk_error_trap_pop (); + + mate_settings_profile_end (NULL); +} + +static gboolean +ax_response_callback (GsdA11yKeyboardManager *manager, + GtkWindow *parent, + gint response_id, + guint revert_controls_mask, + gboolean enabled) +{ + MateConfClient *client; + GdkScreen *screen; + GError *err; + + switch (response_id) { + case GTK_RESPONSE_DELETE_EVENT: + case GTK_RESPONSE_REJECT: + case GTK_RESPONSE_CANCEL: + + client = mateconf_client_get_default (); + + /* we're reverting, so we invert sense of 'enabled' flag */ + d ("cancelling AccessX request"); + if (revert_controls_mask == XkbStickyKeysMask) { + mateconf_client_set_bool (client, + CONFIG_ROOT "/stickykeys_enable", + !enabled, + NULL); + } + else if (revert_controls_mask == XkbSlowKeysMask) { + mateconf_client_set_bool (client, + CONFIG_ROOT "/slowkeys_enable", + !enabled, + NULL); + } + mateconf_client_suggest_sync (client, NULL); + set_server_from_mateconf (manager, client); + + g_object_unref (client); + + break; + + case GTK_RESPONSE_HELP: + if (!parent) + screen = gdk_screen_get_default (); + else + screen = gtk_widget_get_screen (GTK_WIDGET (parent)); + + err = NULL; + if (!gtk_show_uri (screen, + "ghelp:user-guide#goscustaccess-6", + gtk_get_current_event_time(), + &err)) { + GtkWidget *error_dialog = gtk_message_dialog_new (parent, + 0, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + _("There was an error displaying help: %s"), + err->message); + g_signal_connect (error_dialog, "response", + G_CALLBACK (gtk_widget_destroy), NULL); + gtk_window_set_resizable (GTK_WINDOW (error_dialog), FALSE); + gtk_widget_show (error_dialog); + g_error_free (err); + } + return FALSE; + default: + break; + } + return TRUE; +} + +static void +ax_stickykeys_response (GtkDialog *dialog, + gint response_id, + GsdA11yKeyboardManager *manager) +{ + if (ax_response_callback (manager, GTK_WINDOW (dialog), + response_id, XkbStickyKeysMask, + manager->priv->stickykeys_shortcut_val)) { + gtk_widget_destroy (GTK_WIDGET (dialog)); + } +} + +static void +ax_slowkeys_response (GtkDialog *dialog, + gint response_id, + GsdA11yKeyboardManager *manager) +{ + if (ax_response_callback (manager, GTK_WINDOW (dialog), + response_id, XkbSlowKeysMask, + manager->priv->slowkeys_shortcut_val)) { + gtk_widget_destroy (GTK_WIDGET (dialog)); + } +} + +static void +maybe_show_status_icon (GsdA11yKeyboardManager *manager) +{ + gboolean show; + MateConfClient *client; + + /* for now, show if accessx is enabled */ + client = mateconf_client_get_default (); + show = mateconf_client_get_bool (client, CONFIG_ROOT "/enable", NULL); + g_object_unref (client); + + if (!show && manager->priv->status_icon == NULL) + return; + + gsd_a11y_keyboard_manager_ensure_status_icon (manager); + gtk_status_icon_set_visible (manager->priv->status_icon, show); +} + +#ifdef HAVE_LIBMATENOTIFY +static void +on_notification_closed (NotifyNotification *notification, + GsdA11yKeyboardManager *manager) +{ + g_object_unref (manager->priv->notification); + manager->priv->notification = NULL; +} + +static void +on_slow_keys_action (NotifyNotification *notification, + const char *action, + GsdA11yKeyboardManager *manager) +{ + gboolean res; + int response_id; + + g_assert (action != NULL); + + if (strcmp (action, "accept") == 0) { + response_id = GTK_RESPONSE_ACCEPT; + } else if (strcmp (action, "reject") == 0) { + response_id = GTK_RESPONSE_REJECT; + } else { + return; + } + + res = ax_response_callback (manager, NULL, + response_id, XkbSlowKeysMask, + manager->priv->slowkeys_shortcut_val); + if (res) { + notify_notification_close (manager->priv->notification, NULL); + } +} + +static void +on_sticky_keys_action (NotifyNotification *notification, + const char *action, + GsdA11yKeyboardManager *manager) +{ + gboolean res; + int response_id; + + g_assert (action != NULL); + + if (strcmp (action, "accept") == 0) { + response_id = GTK_RESPONSE_ACCEPT; + } else if (strcmp (action, "reject") == 0) { + response_id = GTK_RESPONSE_REJECT; + } else { + return; + } + + res = ax_response_callback (manager, NULL, + response_id, XkbStickyKeysMask, + manager->priv->stickykeys_shortcut_val); + if (res) { + notify_notification_close (manager->priv->notification, NULL); + } +} + +#endif /* HAVE_LIBMATENOTIFY */ + +static gboolean +ax_slowkeys_warning_post_bubble (GsdA11yKeyboardManager *manager, + gboolean enabled) +{ +#ifdef HAVE_LIBMATENOTIFY + gboolean res; + const char *title; + const char *message; + GError *error; + + title = enabled ? + _("Do you want to activate Slow Keys?") : + _("Do you want to deactivate Slow Keys?"); + message = _("You just held down the Shift key for 8 seconds. This is the shortcut " + "for the Slow Keys feature, which affects the way your keyboard works."); + + if (manager->priv->status_icon == NULL || ! gtk_status_icon_is_embedded (manager->priv->status_icon)) { + return FALSE; + } + + if (manager->priv->slowkeys_alert != NULL) { + gtk_widget_destroy (manager->priv->slowkeys_alert); + } + + if (manager->priv->notification != NULL) { + notify_notification_close (manager->priv->notification, NULL); + } + + gsd_a11y_keyboard_manager_ensure_status_icon (manager); + manager->priv->notification = notify_notification_new (title, + message, + "preferences-desktop-accessibility", + NULL); + notify_notification_attach_to_status_icon (manager->priv->notification, manager->priv->status_icon); + notify_notification_set_timeout (manager->priv->notification, NOTIFICATION_TIMEOUT * 1000); + + notify_notification_add_action (manager->priv->notification, + "reject", + enabled ? _("Don't activate") : _("Don't deactivate"), + (NotifyActionCallback) on_slow_keys_action, + manager, + NULL); + notify_notification_add_action (manager->priv->notification, + "accept", + enabled ? _("Activate") : _("Deactivate"), + (NotifyActionCallback) on_slow_keys_action, + manager, + NULL); + + g_signal_connect (manager->priv->notification, + "closed", + G_CALLBACK (on_notification_closed), + manager); + + error = NULL; + res = notify_notification_show (manager->priv->notification, &error); + if (! res) { + g_warning ("GsdA11yKeyboardManager: unable to show notification: %s", error->message); + g_error_free (error); + notify_notification_close (manager->priv->notification, NULL); + } + + return res; +#else + return FALSE; +#endif /* HAVE_LIBMATENOTIFY */ +} + + +static void +ax_slowkeys_warning_post_dialog (GsdA11yKeyboardManager *manager, + gboolean enabled) +{ + const char *title; + const char *message; + + title = enabled ? + _("Do you want to activate Slow Keys?") : + _("Do you want to deactivate Slow Keys?"); + message = _("You just held down the Shift key for 8 seconds. This is the shortcut " + "for the Slow Keys feature, which affects the way your keyboard works."); + + if (manager->priv->slowkeys_alert != NULL) { + gtk_widget_show (manager->priv->slowkeys_alert); + return; + } + + manager->priv->slowkeys_alert = gtk_message_dialog_new (NULL, + 0, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_NONE, + "%s", title); + + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (manager->priv->slowkeys_alert), + "%s", message); + + gtk_dialog_add_button (GTK_DIALOG (manager->priv->slowkeys_alert), + GTK_STOCK_HELP, + GTK_RESPONSE_HELP); + gtk_dialog_add_button (GTK_DIALOG (manager->priv->slowkeys_alert), + enabled ? _("Do_n't activate") : _("Do_n't deactivate"), + GTK_RESPONSE_REJECT); + gtk_dialog_add_button (GTK_DIALOG (manager->priv->slowkeys_alert), + enabled ? _("_Activate") : _("_Deactivate"), + GTK_RESPONSE_ACCEPT); + + gtk_window_set_title (GTK_WINDOW (manager->priv->slowkeys_alert), + _("Slow Keys Alert")); + gtk_window_set_icon_name (GTK_WINDOW (manager->priv->slowkeys_alert), + "input-keyboard"); + gtk_dialog_set_default_response (GTK_DIALOG (manager->priv->slowkeys_alert), + GTK_RESPONSE_ACCEPT); + + g_signal_connect (manager->priv->slowkeys_alert, + "response", + G_CALLBACK (ax_slowkeys_response), + manager); + gtk_widget_show (manager->priv->slowkeys_alert); + + g_object_add_weak_pointer (G_OBJECT (manager->priv->slowkeys_alert), + (gpointer*) &manager->priv->slowkeys_alert); +} + +static void +ax_slowkeys_warning_post (GsdA11yKeyboardManager *manager, + gboolean enabled) +{ + + manager->priv->slowkeys_shortcut_val = enabled; + + /* alway try to show something */ + if (! ax_slowkeys_warning_post_bubble (manager, enabled)) { + ax_slowkeys_warning_post_dialog (manager, enabled); + } +} + +static gboolean +ax_stickykeys_warning_post_bubble (GsdA11yKeyboardManager *manager, + gboolean enabled) +{ +#ifdef HAVE_LIBMATENOTIFY + gboolean res; + const char *title; + const char *message; + GError *error; + + title = enabled ? + _("Do you want to activate Sticky Keys?") : + _("Do you want to deactivate Sticky Keys?"); + message = enabled ? + _("You just pressed the Shift key 5 times in a row. This is the shortcut " + "for the Sticky Keys feature, which affects the way your keyboard works.") : + _("You just pressed two keys at once, or pressed the Shift key 5 times in a row. " + "This turns off the Sticky Keys feature, which affects the way your keyboard works."); + + if (manager->priv->status_icon == NULL || ! gtk_status_icon_is_embedded (manager->priv->status_icon)) { + return FALSE; + } + + if (manager->priv->slowkeys_alert != NULL) { + gtk_widget_destroy (manager->priv->slowkeys_alert); + } + + if (manager->priv->notification != NULL) { + notify_notification_close (manager->priv->notification, NULL); + } + + gsd_a11y_keyboard_manager_ensure_status_icon (manager); + manager->priv->notification = notify_notification_new (title, + message, + "preferences-desktop-accessibility", + NULL); + notify_notification_attach_to_status_icon (manager->priv->notification, manager->priv->status_icon); + notify_notification_set_timeout (manager->priv->notification, NOTIFICATION_TIMEOUT * 1000); + + notify_notification_add_action (manager->priv->notification, + "reject", + enabled ? _("Don't activate") : _("Don't deactivate"), + (NotifyActionCallback) on_sticky_keys_action, + manager, + NULL); + notify_notification_add_action (manager->priv->notification, + "accept", + enabled ? _("Activate") : _("Deactivate"), + (NotifyActionCallback) on_sticky_keys_action, + manager, + NULL); + + g_signal_connect (manager->priv->notification, + "closed", + G_CALLBACK (on_notification_closed), + manager); + + error = NULL; + res = notify_notification_show (manager->priv->notification, &error); + if (! res) { + g_warning ("GsdA11yKeyboardManager: unable to show notification: %s", error->message); + g_error_free (error); + notify_notification_close (manager->priv->notification, NULL); + } + + return res; +#else + return FALSE; +#endif /* HAVE_LIBMATENOTIFY */ +} + +static void +ax_stickykeys_warning_post_dialog (GsdA11yKeyboardManager *manager, + gboolean enabled) +{ + const char *title; + const char *message; + + title = enabled ? + _("Do you want to activate Sticky Keys?") : + _("Do you want to deactivate Sticky Keys?"); + message = enabled ? + _("You just pressed the Shift key 5 times in a row. This is the shortcut " + "for the Sticky Keys feature, which affects the way your keyboard works.") : + _("You just pressed two keys at once, or pressed the Shift key 5 times in a row. " + "This turns off the Sticky Keys feature, which affects the way your keyboard works."); + + if (manager->priv->stickykeys_alert != NULL) { + gtk_widget_show (manager->priv->stickykeys_alert); + return; + } + + manager->priv->stickykeys_alert = gtk_message_dialog_new (NULL, + 0, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_NONE, + "%s", title); + + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (manager->priv->stickykeys_alert), + "%s", message); + + gtk_dialog_add_button (GTK_DIALOG (manager->priv->stickykeys_alert), + GTK_STOCK_HELP, + GTK_RESPONSE_HELP); + gtk_dialog_add_button (GTK_DIALOG (manager->priv->stickykeys_alert), + enabled ? _("Do_n't activate") : _("Do_n't deactivate"), + GTK_RESPONSE_REJECT); + gtk_dialog_add_button (GTK_DIALOG (manager->priv->stickykeys_alert), + enabled ? _("_Activate") : _("_Deactivate"), + GTK_RESPONSE_ACCEPT); + + gtk_window_set_title (GTK_WINDOW (manager->priv->stickykeys_alert), + _("Sticky Keys Alert")); + gtk_window_set_icon_name (GTK_WINDOW (manager->priv->stickykeys_alert), + "input-keyboard"); + gtk_dialog_set_default_response (GTK_DIALOG (manager->priv->stickykeys_alert), + GTK_RESPONSE_ACCEPT); + + g_signal_connect (manager->priv->stickykeys_alert, + "response", + G_CALLBACK (ax_stickykeys_response), + manager); + gtk_widget_show (manager->priv->stickykeys_alert); + + g_object_add_weak_pointer (G_OBJECT (manager->priv->stickykeys_alert), + (gpointer*) &manager->priv->stickykeys_alert); +} + +static void +ax_stickykeys_warning_post (GsdA11yKeyboardManager *manager, + gboolean enabled) +{ + + manager->priv->stickykeys_shortcut_val = enabled; + + /* alway try to show something */ + if (! ax_stickykeys_warning_post_bubble (manager, enabled)) { + ax_stickykeys_warning_post_dialog (manager, enabled); + } +} + +static void +set_mateconf_from_server (GsdA11yKeyboardManager *manager) +{ + MateConfClient *client; + MateConfChangeSet *cs; + XkbDescRec *desc; + gboolean changed = FALSE; + gboolean slowkeys_changed; + gboolean stickykeys_changed; + + cs = mateconf_change_set_new (); + desc = get_xkb_desc_rec (manager); + if (! desc) { + return; + } + + client = mateconf_client_get_default (); + + /* + fprintf (stderr, "changed to : 0x%x\n", desc->ctrls->enabled_ctrls); + fprintf (stderr, "changed to : 0x%x (2)\n", desc->ctrls->ax_options); + */ + + changed |= set_bool (client, + cs, + CONFIG_ROOT "/enable", + desc->ctrls->enabled_ctrls & XkbAccessXKeysMask); + + changed |= set_bool (client, + cs, + CONFIG_ROOT "/feature_state_change_beep", + desc->ctrls->ax_options & (XkbAX_FeatureFBMask | XkbAX_SlowWarnFBMask)); + changed |= set_bool (client, + cs, + CONFIG_ROOT "/timeout_enable", + desc->ctrls->enabled_ctrls & XkbAccessXTimeoutMask); + changed |= set_int (client, + cs, + CONFIG_ROOT "/timeout", + desc->ctrls->ax_timeout); + + changed |= set_bool (client, + cs, + CONFIG_ROOT "/bouncekeys_enable", + desc->ctrls->enabled_ctrls & XkbBounceKeysMask); + changed |= set_int (client, + cs, + CONFIG_ROOT "/bouncekeys_delay", + desc->ctrls->debounce_delay); + changed |= set_bool (client, + cs, + CONFIG_ROOT "/bouncekeys_beep_reject", + desc->ctrls->ax_options & XkbAX_BKRejectFBMask); + + changed |= set_bool (client, + cs, + CONFIG_ROOT "/mousekeys_enable", + desc->ctrls->enabled_ctrls & XkbMouseKeysMask); + changed |= set_int (client, + cs, + CONFIG_ROOT "/mousekeys_max_speed", + desc->ctrls->mk_max_speed * (1000 / desc->ctrls->mk_interval)); + /* NOTE : mk_time_to_max is measured in events not time */ + changed |= set_int (client, + cs, + CONFIG_ROOT "/mousekeys_accel_time", + desc->ctrls->mk_time_to_max * desc->ctrls->mk_interval); + changed |= set_int (client, + cs, + CONFIG_ROOT "/mousekeys_init_delay", + desc->ctrls->mk_delay); + + slowkeys_changed = set_bool (client, + cs, + CONFIG_ROOT "/slowkeys_enable", + desc->ctrls->enabled_ctrls & XkbSlowKeysMask); + changed |= set_bool (client, + cs, + CONFIG_ROOT "/slowkeys_beep_press", + desc->ctrls->ax_options & XkbAX_SKPressFBMask); + changed |= set_bool (client, + cs, + CONFIG_ROOT "/slowkeys_beep_accept", + desc->ctrls->ax_options & XkbAX_SKAcceptFBMask); + changed |= set_bool (client, + cs, + CONFIG_ROOT "/slowkeys_beep_reject", + desc->ctrls->ax_options & XkbAX_SKRejectFBMask); + changed |= set_int (client, + cs, + CONFIG_ROOT "/slowkeys_delay", + desc->ctrls->slow_keys_delay); + + stickykeys_changed = set_bool (client, + cs, + CONFIG_ROOT "/stickykeys_enable", + desc->ctrls->enabled_ctrls & XkbStickyKeysMask); + changed |= set_bool (client, + cs, + CONFIG_ROOT "/stickykeys_two_key_off", + desc->ctrls->ax_options & XkbAX_TwoKeysMask); + changed |= set_bool (client, + cs, + CONFIG_ROOT "/stickykeys_modifier_beep", + desc->ctrls->ax_options & XkbAX_StickyKeysFBMask); + + changed |= set_bool (client, + cs, + CONFIG_ROOT "/togglekeys_enable", + desc->ctrls->ax_options & XkbAX_IndicatorFBMask); + + if (!changed && stickykeys_changed ^ slowkeys_changed) { + /* + * sticky or slowkeys has changed, singly, without our intervention. + * 99% chance this is due to a keyboard shortcut being used. + * we need to detect via this hack until we get + * XkbAXN_AXKWarning notifications working (probable XKB bug), + * at which time we can directly intercept such shortcuts instead. + * See cb_xkb_event_filter () below. + */ + + /* sanity check: are keyboard shortcuts available? */ + if (desc->ctrls->enabled_ctrls & XkbAccessXKeysMask) { + if (slowkeys_changed) { + ax_slowkeys_warning_post (manager, + desc->ctrls->enabled_ctrls & XkbSlowKeysMask); + } else { + ax_stickykeys_warning_post (manager, + desc->ctrls->enabled_ctrls & XkbStickyKeysMask); + } + } + } + + XkbFreeKeyboard (desc, XkbAllComponentsMask, True); + + changed |= (stickykeys_changed | slowkeys_changed); + + if (changed) { + mateconf_client_commit_change_set (client, cs, FALSE, NULL); + mateconf_client_suggest_sync (client, NULL); + } + mateconf_change_set_unref (cs); + + g_object_unref (client); +} + +static GdkFilterReturn +cb_xkb_event_filter (GdkXEvent *xevent, + GdkEvent *ignored1, + GsdA11yKeyboardManager *manager) +{ + XEvent *xev = (XEvent *) xevent; + XkbEvent *xkbEv = (XkbEvent *) xevent; + + if (xev->xany.type == (manager->priv->xkbEventBase + XkbEventCode) && + xkbEv->any.xkb_type == XkbControlsNotify) { + d ("XKB state changed"); + set_mateconf_from_server (manager); + } else if (xev->xany.type == (manager->priv->xkbEventBase + XkbEventCode) && + xkbEv->any.xkb_type == XkbAccessXNotify) { + if (xkbEv->accessx.detail == XkbAXN_AXKWarning) { + d ("About to turn on an AccessX feature from the keyboard!"); + /* + * TODO: when XkbAXN_AXKWarnings start working, we need to + * invoke ax_keys_warning_dialog_run here instead of in + * set_mateconf_from_server(). + */ + } + } + + return GDK_FILTER_CONTINUE; +} + +static void +keyboard_callback (MateConfClient *client, + guint cnxn_id, + MateConfEntry *entry, + GsdA11yKeyboardManager *manager) +{ + set_server_from_mateconf (manager, client); + maybe_show_status_icon (manager); +} + +static void +register_config_callback (GsdA11yKeyboardManager *manager, + MateConfClient *client, + const char *path, + MateConfClientNotifyFunc func, + guint *notify) +{ + mateconf_client_add_dir (client, path, MATECONF_CLIENT_PRELOAD_ONELEVEL, NULL); + *notify = mateconf_client_notify_add (client, path, func, manager, NULL, NULL); +} + +static gboolean +start_a11y_keyboard_idle_cb (GsdA11yKeyboardManager *manager) +{ + guint event_mask; + MateConfClient *client; + + g_debug ("Starting a11y_keyboard manager"); + mate_settings_profile_start (NULL); + + if (!xkb_enabled (manager)) + goto out; + + client = mateconf_client_get_default (); + + register_config_callback (manager, + client, + CONFIG_ROOT, + (MateConfClientNotifyFunc) keyboard_callback, + &manager->priv->mateconf_notify); + +#ifdef HAVE_X11_EXTENSIONS_XINPUT_H + set_devicepresence_handler (manager); +#endif + + /* Save current xkb state so we can restore it on exit + */ + manager->priv->original_xkb_desc = get_xkb_desc_rec (manager); + + event_mask = XkbControlsNotifyMask; +#ifdef DEBUG_ACCESSIBILITY + event_mask |= XkbAccessXNotifyMask; /* make default when AXN_AXKWarning works */ +#endif + + /* be sure to init before starting to monitor the server */ + set_server_from_mateconf (manager, client); + g_object_unref (client); + + XkbSelectEvents (GDK_DISPLAY (), + XkbUseCoreKbd, + event_mask, + event_mask); + + gdk_window_add_filter (NULL, + (GdkFilterFunc) cb_xkb_event_filter, + manager); + + maybe_show_status_icon (manager); + + out: + mate_settings_profile_end (NULL); + + return FALSE; +} + + +gboolean +gsd_a11y_keyboard_manager_start (GsdA11yKeyboardManager *manager, + GError **error) +{ + mate_settings_profile_start (NULL); + + g_idle_add ((GSourceFunc) start_a11y_keyboard_idle_cb, manager); + + mate_settings_profile_end (NULL); + + return TRUE; +} + +static void +restore_server_xkb_config (GsdA11yKeyboardManager *manager) +{ + gdk_error_trap_push (); + XkbSetControls (GDK_DISPLAY (), + XkbSlowKeysMask | + XkbBounceKeysMask | + XkbStickyKeysMask | + XkbMouseKeysMask | + XkbMouseKeysAccelMask | + XkbAccessXKeysMask | + XkbAccessXTimeoutMask | + XkbAccessXFeedbackMask | + XkbControlsEnabledMask, + manager->priv->original_xkb_desc); + + XkbFreeKeyboard (manager->priv->original_xkb_desc, + XkbAllComponentsMask, True); + + XSync (GDK_DISPLAY (), FALSE); + gdk_error_trap_pop (); + + manager->priv->original_xkb_desc = NULL; +} + +void +gsd_a11y_keyboard_manager_stop (GsdA11yKeyboardManager *manager) +{ + GsdA11yKeyboardManagerPrivate *p = manager->priv; + + g_debug ("Stopping a11y_keyboard manager"); + +#ifdef HAVE_X11_EXTENSIONS_XINPUT_H + gdk_window_remove_filter (NULL, devicepresence_filter, manager); +#endif + + if (p->status_icon) + gtk_status_icon_set_visible (p->status_icon, FALSE); + + if (p->mateconf_notify != 0) { + MateConfClient *client = mateconf_client_get_default (); + mateconf_client_remove_dir (client, CONFIG_ROOT, NULL); + mateconf_client_notify_remove (client, p->mateconf_notify); + g_object_unref (client); + p->mateconf_notify = 0; + } + + gdk_window_remove_filter (NULL, + (GdkFilterFunc) cb_xkb_event_filter, + manager); + + /* Disable all the AccessX bits + */ + restore_server_xkb_config (manager); + + if (p->slowkeys_alert != NULL) + gtk_widget_destroy (p->slowkeys_alert); + + if (p->stickykeys_alert != NULL) + gtk_widget_destroy (p->stickykeys_alert); + + p->slowkeys_shortcut_val = FALSE; + p->stickykeys_shortcut_val = FALSE; +} + +static void +gsd_a11y_keyboard_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GsdA11yKeyboardManager *self; + + self = GSD_A11Y_KEYBOARD_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gsd_a11y_keyboard_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GsdA11yKeyboardManager *self; + + self = GSD_A11Y_KEYBOARD_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +gsd_a11y_keyboard_manager_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GsdA11yKeyboardManager *a11y_keyboard_manager; + GsdA11yKeyboardManagerClass *klass; + + klass = GSD_A11Y_KEYBOARD_MANAGER_CLASS (g_type_class_peek (GSD_TYPE_A11Y_KEYBOARD_MANAGER)); + + a11y_keyboard_manager = GSD_A11Y_KEYBOARD_MANAGER (G_OBJECT_CLASS (gsd_a11y_keyboard_manager_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + + return G_OBJECT (a11y_keyboard_manager); +} + +static void +gsd_a11y_keyboard_manager_dispose (GObject *object) +{ + GsdA11yKeyboardManager *a11y_keyboard_manager; + + a11y_keyboard_manager = GSD_A11Y_KEYBOARD_MANAGER (object); + + G_OBJECT_CLASS (gsd_a11y_keyboard_manager_parent_class)->dispose (object); +} + +static void +gsd_a11y_keyboard_manager_class_init (GsdA11yKeyboardManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gsd_a11y_keyboard_manager_get_property; + object_class->set_property = gsd_a11y_keyboard_manager_set_property; + object_class->constructor = gsd_a11y_keyboard_manager_constructor; + object_class->dispose = gsd_a11y_keyboard_manager_dispose; + object_class->finalize = gsd_a11y_keyboard_manager_finalize; + + g_type_class_add_private (klass, sizeof (GsdA11yKeyboardManagerPrivate)); +} + +static void +on_preferences_dialog_response (GtkDialog *dialog, + int response, + GsdA11yKeyboardManager *manager) +{ + g_signal_handlers_disconnect_by_func (dialog, + on_preferences_dialog_response, + manager); + + gtk_widget_destroy (GTK_WIDGET (dialog)); + manager->priv->preferences_dialog = NULL; +} + +static void +on_status_icon_activate (GtkStatusIcon *status_icon, + GsdA11yKeyboardManager *manager) +{ + if (manager->priv->preferences_dialog == NULL) { + manager->priv->preferences_dialog = gsd_a11y_preferences_dialog_new (); + g_signal_connect (manager->priv->preferences_dialog, + "response", + G_CALLBACK (on_preferences_dialog_response), + manager); + + gtk_window_present (GTK_WINDOW (manager->priv->preferences_dialog)); + } else { + g_signal_handlers_disconnect_by_func (manager->priv->preferences_dialog, + on_preferences_dialog_response, + manager); + gtk_widget_destroy (GTK_WIDGET (manager->priv->preferences_dialog)); + manager->priv->preferences_dialog = NULL; + } +} + +static void +gsd_a11y_keyboard_manager_ensure_status_icon (GsdA11yKeyboardManager *manager) +{ + mate_settings_profile_start (NULL); + + if (!manager->priv->status_icon) { + + manager->priv->status_icon = gtk_status_icon_new_from_icon_name ("preferences-desktop-accessibility"); + g_signal_connect (manager->priv->status_icon, + "activate", + G_CALLBACK (on_status_icon_activate), + manager); + } + + mate_settings_profile_end (NULL); +} + +static void +gsd_a11y_keyboard_manager_init (GsdA11yKeyboardManager *manager) +{ + manager->priv = GSD_A11Y_KEYBOARD_MANAGER_GET_PRIVATE (manager); + +#ifdef HAVE_LIBMATENOTIFY + notify_init ("mate-settings-daemon"); +#endif /* HAVE_LIBMATENOTIFY */ +} + +static void +gsd_a11y_keyboard_manager_finalize (GObject *object) +{ + GsdA11yKeyboardManager *a11y_keyboard_manager; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_A11Y_KEYBOARD_MANAGER (object)); + + a11y_keyboard_manager = GSD_A11Y_KEYBOARD_MANAGER (object); + + g_return_if_fail (a11y_keyboard_manager->priv != NULL); + + G_OBJECT_CLASS (gsd_a11y_keyboard_manager_parent_class)->finalize (object); +} + +GsdA11yKeyboardManager * +gsd_a11y_keyboard_manager_new (void) +{ + if (manager_object != NULL) { + g_object_ref (manager_object); + } else { + manager_object = g_object_new (GSD_TYPE_A11Y_KEYBOARD_MANAGER, NULL); + g_object_add_weak_pointer (manager_object, + (gpointer *) &manager_object); + } + + return GSD_A11Y_KEYBOARD_MANAGER (manager_object); +} diff --git a/plugins/a11y-keyboard/gsd-a11y-keyboard-manager.h b/plugins/a11y-keyboard/gsd-a11y-keyboard-manager.h new file mode 100644 index 0000000..4fb817f --- /dev/null +++ b/plugins/a11y-keyboard/gsd-a11y-keyboard-manager.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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_A11Y_KEYBOARD_MANAGER_H +#define __GSD_A11Y_KEYBOARD_MANAGER_H + +#include <glib-object.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_A11Y_KEYBOARD_MANAGER (gsd_a11y_keyboard_manager_get_type ()) +#define GSD_A11Y_KEYBOARD_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_A11Y_KEYBOARD_MANAGER, GsdA11yKeyboardManager)) +#define GSD_A11Y_KEYBOARD_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_A11Y_KEYBOARD_MANAGER, GsdA11yKeyboardManagerClass)) +#define GSD_IS_A11Y_KEYBOARD_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_A11Y_KEYBOARD_MANAGER)) +#define GSD_IS_A11Y_KEYBOARD_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_A11Y_KEYBOARD_MANAGER)) +#define GSD_A11Y_KEYBOARD_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_A11Y_KEYBOARD_MANAGER, GsdA11yKeyboardManagerClass)) + +typedef struct GsdA11yKeyboardManagerPrivate GsdA11yKeyboardManagerPrivate; + +typedef struct +{ + GObject parent; + GsdA11yKeyboardManagerPrivate *priv; +} GsdA11yKeyboardManager; + +typedef struct +{ + GObjectClass parent_class; +} GsdA11yKeyboardManagerClass; + +GType gsd_a11y_keyboard_manager_get_type (void); + +GsdA11yKeyboardManager *gsd_a11y_keyboard_manager_new (void); +gboolean gsd_a11y_keyboard_manager_start (GsdA11yKeyboardManager *manager, + GError **error); +void gsd_a11y_keyboard_manager_stop (GsdA11yKeyboardManager *manager); + +#ifdef __cplusplus +} +#endif + +#endif /* __GSD_A11Y_KEYBOARD_MANAGER_H */ diff --git a/plugins/a11y-keyboard/gsd-a11y-keyboard-plugin.c b/plugins/a11y-keyboard/gsd-a11y-keyboard-plugin.c new file mode 100644 index 0000000..7846ba6 --- /dev/null +++ b/plugins/a11y-keyboard/gsd-a11y-keyboard-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 <[email protected]> + * + * 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 <glib/gi18n-lib.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" +#include "gsd-a11y-keyboard-plugin.h" +#include "gsd-a11y-keyboard-manager.h" + +struct GsdA11yKeyboardPluginPrivate { + GsdA11yKeyboardManager *manager; +}; + +#define GSD_A11Y_KEYBOARD_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSD_TYPE_A11Y_KEYBOARD_PLUGIN, GsdA11yKeyboardPluginPrivate)) + +MATE_SETTINGS_PLUGIN_REGISTER (GsdA11yKeyboardPlugin, gsd_a11y_keyboard_plugin) + +static void +gsd_a11y_keyboard_plugin_init (GsdA11yKeyboardPlugin *plugin) +{ + plugin->priv = GSD_A11Y_KEYBOARD_PLUGIN_GET_PRIVATE (plugin); + + g_debug ("GsdA11yKeyboardPlugin initializing"); + + plugin->priv->manager = gsd_a11y_keyboard_manager_new (); +} + +static void +gsd_a11y_keyboard_plugin_finalize (GObject *object) +{ + GsdA11yKeyboardPlugin *plugin; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_A11Y_KEYBOARD_PLUGIN (object)); + + g_debug ("GsdA11yKeyboardPlugin finalizing"); + + plugin = GSD_A11Y_KEYBOARD_PLUGIN (object); + + g_return_if_fail (plugin->priv != NULL); + + if (plugin->priv->manager != NULL) { + g_object_unref (plugin->priv->manager); + } + + G_OBJECT_CLASS (gsd_a11y_keyboard_plugin_parent_class)->finalize (object); +} + +static void +impl_activate (MateSettingsPlugin *plugin) +{ + gboolean res; + GError *error; + + g_debug ("Activating a11y_keyboard plugin"); + + error = NULL; + res = gsd_a11y_keyboard_manager_start (GSD_A11Y_KEYBOARD_PLUGIN (plugin)->priv->manager, &error); + if (! res) { + g_warning ("Unable to start a11y_keyboard manager: %s", error->message); + g_error_free (error); + } +} + +static void +impl_deactivate (MateSettingsPlugin *plugin) +{ + g_debug ("Deactivating a11y_keyboard plugin"); + gsd_a11y_keyboard_manager_stop (GSD_A11Y_KEYBOARD_PLUGIN (plugin)->priv->manager); +} + +static void +gsd_a11y_keyboard_plugin_class_init (GsdA11yKeyboardPluginClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MateSettingsPluginClass *plugin_class = MATE_SETTINGS_PLUGIN_CLASS (klass); + + object_class->finalize = gsd_a11y_keyboard_plugin_finalize; + + plugin_class->activate = impl_activate; + plugin_class->deactivate = impl_deactivate; + + g_type_class_add_private (klass, sizeof (GsdA11yKeyboardPluginPrivate)); +} diff --git a/plugins/a11y-keyboard/gsd-a11y-keyboard-plugin.h b/plugins/a11y-keyboard/gsd-a11y-keyboard-plugin.h new file mode 100644 index 0000000..ebf246c --- /dev/null +++ b/plugins/a11y-keyboard/gsd-a11y-keyboard-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 <[email protected]> + * + * 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_A11Y_KEYBOARD_PLUGIN_H__ +#define __GSD_A11Y_KEYBOARD_PLUGIN_H__ + +#include <glib.h> +#include <glib-object.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_A11Y_KEYBOARD_PLUGIN (gsd_a11y_keyboard_plugin_get_type ()) +#define GSD_A11Y_KEYBOARD_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_A11Y_KEYBOARD_PLUGIN, GsdA11yKeyboardPlugin)) +#define GSD_A11Y_KEYBOARD_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_A11Y_KEYBOARD_PLUGIN, GsdA11yKeyboardPluginClass)) +#define GSD_IS_A11Y_KEYBOARD_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_A11Y_KEYBOARD_PLUGIN)) +#define GSD_IS_A11Y_KEYBOARD_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_A11Y_KEYBOARD_PLUGIN)) +#define GSD_A11Y_KEYBOARD_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_A11Y_KEYBOARD_PLUGIN, GsdA11yKeyboardPluginClass)) + +typedef struct GsdA11yKeyboardPluginPrivate GsdA11yKeyboardPluginPrivate; + +typedef struct +{ + MateSettingsPlugin parent; + GsdA11yKeyboardPluginPrivate *priv; +} GsdA11yKeyboardPlugin; + +typedef struct +{ + MateSettingsPluginClass parent_class; +} GsdA11yKeyboardPluginClass; + +GType gsd_a11y_keyboard_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_A11Y_KEYBOARD_PLUGIN_H__ */ diff --git a/plugins/a11y-keyboard/gsd-a11y-preferences-dialog.c b/plugins/a11y-keyboard/gsd-a11y-preferences-dialog.c new file mode 100644 index 0000000..752ee18 --- /dev/null +++ b/plugins/a11y-keyboard/gsd-a11y-preferences-dialog.c @@ -0,0 +1,975 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 William Jon McCann <[email protected]> + * + * 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 <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> + +#include <glib.h> +#include <glib/gi18n.h> +#include <glib-object.h> +#include <gtk/gtk.h> + +#include <dbus/dbus-glib.h> + +#include <mateconf/mateconf-client.h> + +#include "gsd-a11y-preferences-dialog.h" + +#define SM_DBUS_NAME "org.mate.SessionManager" +#define SM_DBUS_PATH "/org/mate/SessionManager" +#define SM_DBUS_INTERFACE "org.mate.SessionManager" + + +#define GSD_A11Y_PREFERENCES_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_A11Y_PREFERENCES_DIALOG, GsdA11yPreferencesDialogPrivate)) + +#define GTKBUILDER_UI_FILE "gsd-a11y-preferences-dialog.ui" + +#define KEY_A11Y_DIR "/desktop/mate/accessibility" +#define KEY_STICKY_KEYS_ENABLED KEY_A11Y_DIR "/keyboard/stickykeys_enable" +#define KEY_BOUNCE_KEYS_ENABLED KEY_A11Y_DIR "/keyboard/bouncekeys_enable" +#define KEY_SLOW_KEYS_ENABLED KEY_A11Y_DIR "/keyboard/slowkeys_enable" +#define KEY_MOUSE_KEYS_ENABLED KEY_A11Y_DIR "/keyboard/mousekeys_enable" + +#define KEY_AT_DIR "/desktop/mate/applications/at" +#define KEY_AT_SCREEN_KEYBOARD_ENABLED KEY_AT_DIR "/screen_keyboard_enabled" +#define KEY_AT_SCREEN_MAGNIFIER_ENABLED KEY_AT_DIR "/screen_magnifier_enabled" +#define KEY_AT_SCREEN_READER_ENABLED KEY_AT_DIR "/screen_reader_enabled" + +#define FONT_RENDER_DIR "/desktop/mate/font_rendering" +#define KEY_FONT_DPI FONT_RENDER_DIR "/dpi" +/* X servers sometimes lie about the screen's physical dimensions, so we cannot + * compute an accurate DPI value. When this happens, the user gets fonts that + * are too huge or too tiny. So, we see what the server returns: if it reports + * something outside of the range [DPI_LOW_REASONABLE_VALUE, + * DPI_HIGH_REASONABLE_VALUE], then we assume that it is lying and we use + * DPI_FALLBACK instead. + * + * See get_dpi_from_mateconf_or_server() below, and also + * https://bugzilla.novell.com/show_bug.cgi?id=217790 + */ +#define DPI_LOW_REASONABLE_VALUE 50 +#define DPI_HIGH_REASONABLE_VALUE 500 + +#define DPI_FACTOR_LARGE 1.25 +#define DPI_FACTOR_LARGER 1.5 +#define DPI_FACTOR_LARGEST 2.0 +#define DPI_DEFAULT 96 + +#define KEY_GTK_THEME "/desktop/mate/interface/gtk_theme" +#define KEY_COLOR_SCHEME "/desktop/mate/interface/gtk_color_scheme" +#define KEY_MARCO_THEME "/apps/marco/general/theme" +#define KEY_ICON_THEME "/desktop/mate/interface/icon_theme" + +#define HIGH_CONTRAST_THEME "HighContrast" + +struct GsdA11yPreferencesDialogPrivate +{ + GtkWidget *sticky_keys_checkbutton; + GtkWidget *slow_keys_checkbutton; + GtkWidget *bounce_keys_checkbutton; + + GtkWidget *large_print_checkbutton; + GtkWidget *high_contrast_checkbutton; + + GtkWidget *screen_reader_checkbutton; + GtkWidget *screen_keyboard_checkbutton; + GtkWidget *screen_magnifier_checkbutton; + + guint a11y_dir_cnxn; + guint gsd_a11y_dir_cnxn; +}; + +enum { + PROP_0, +}; + +static void gsd_a11y_preferences_dialog_class_init (GsdA11yPreferencesDialogClass *klass); +static void gsd_a11y_preferences_dialog_init (GsdA11yPreferencesDialog *a11y_preferences_dialog); +static void gsd_a11y_preferences_dialog_finalize (GObject *object); + +G_DEFINE_TYPE (GsdA11yPreferencesDialog, gsd_a11y_preferences_dialog, GTK_TYPE_DIALOG) + +static void +gsd_a11y_preferences_dialog_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gsd_a11y_preferences_dialog_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +gsd_a11y_preferences_dialog_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GsdA11yPreferencesDialog *a11y_preferences_dialog; + + a11y_preferences_dialog = GSD_A11Y_PREFERENCES_DIALOG (G_OBJECT_CLASS (gsd_a11y_preferences_dialog_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + + return G_OBJECT (a11y_preferences_dialog); +} + +static void +gsd_a11y_preferences_dialog_dispose (GObject *object) +{ + G_OBJECT_CLASS (gsd_a11y_preferences_dialog_parent_class)->dispose (object); +} + +static void +gsd_a11y_preferences_dialog_class_init (GsdA11yPreferencesDialogClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gsd_a11y_preferences_dialog_get_property; + object_class->set_property = gsd_a11y_preferences_dialog_set_property; + object_class->constructor = gsd_a11y_preferences_dialog_constructor; + object_class->dispose = gsd_a11y_preferences_dialog_dispose; + object_class->finalize = gsd_a11y_preferences_dialog_finalize; + + g_type_class_add_private (klass, sizeof (GsdA11yPreferencesDialogPrivate)); +} + +static void +on_response (GsdA11yPreferencesDialog *dialog, + gint response_id) +{ + switch (response_id) { + default: + break; + } +} + +static char * +config_get_string (const char *key, + gboolean *is_writable) +{ + char *str; + MateConfClient *client; + + client = mateconf_client_get_default (); + + if (is_writable) { + *is_writable = mateconf_client_key_is_writable (client, + key, + NULL); + } + + str = mateconf_client_get_string (client, key, NULL); + + g_object_unref (client); + + return str; +} + +static gboolean +config_get_bool (const char *key, + gboolean *is_writable) +{ + int enabled; + MateConfClient *client; + + client = mateconf_client_get_default (); + + if (is_writable) { + *is_writable = mateconf_client_key_is_writable (client, + key, + NULL); + } + + enabled = mateconf_client_get_bool (client, key, NULL); + + g_object_unref (client); + + return enabled; +} + +static double +dpi_from_pixels_and_mm (int pixels, + int mm) +{ + double dpi; + + if (mm >= 1) { + dpi = pixels / (mm / 25.4); + } else { + dpi = 0; + } + + return dpi; +} + +static double +get_dpi_from_x_server (void) +{ + GdkScreen *screen; + double dpi; + + screen = gdk_screen_get_default (); + if (screen != NULL) { + double width_dpi; + double height_dpi; + + width_dpi = dpi_from_pixels_and_mm (gdk_screen_get_width (screen), + gdk_screen_get_width_mm (screen)); + height_dpi = dpi_from_pixels_and_mm (gdk_screen_get_height (screen), + gdk_screen_get_height_mm (screen)); + if (width_dpi < DPI_LOW_REASONABLE_VALUE + || width_dpi > DPI_HIGH_REASONABLE_VALUE + || height_dpi < DPI_LOW_REASONABLE_VALUE + || height_dpi > DPI_HIGH_REASONABLE_VALUE) { + dpi = DPI_DEFAULT; + } else { + dpi = (width_dpi + height_dpi) / 2.0; + } + } else { + /* Huh!? No screen? */ + dpi = DPI_DEFAULT; + } + + return dpi; +} + +static gboolean +config_get_large_print (gboolean *is_writable) +{ + gboolean ret; + MateConfClient *client; + MateConfValue *value; + gdouble x_dpi; + gdouble u_dpi; + + client = mateconf_client_get_default (); + value = mateconf_client_get_without_default (client, KEY_FONT_DPI, NULL); + + if (value != NULL) { + u_dpi = mateconf_value_get_float (value); + mateconf_value_free (value); + } else { + u_dpi = DPI_DEFAULT; + } + + x_dpi = get_dpi_from_x_server (); + + g_object_unref (client); + + g_debug ("GsdA11yPreferences: got x-dpi=%f user-dpi=%f", x_dpi, u_dpi); + + ret = (((double)DPI_FACTOR_LARGE * x_dpi) < u_dpi); + + return ret; +} + +static void +config_set_large_print (gboolean enabled) +{ + MateConfClient *client; + + client = mateconf_client_get_default (); + + if (enabled) { + gdouble x_dpi; + gdouble u_dpi; + + x_dpi = get_dpi_from_x_server (); + u_dpi = (double)DPI_FACTOR_LARGER * x_dpi; + + g_debug ("GsdA11yPreferences: setting x-dpi=%f user-dpi=%f", x_dpi, u_dpi); + + mateconf_client_set_float (client, KEY_FONT_DPI, u_dpi, NULL); + } else { + mateconf_client_unset (client, KEY_FONT_DPI, NULL); + } + + g_object_unref (client); +} + +static gboolean +config_get_high_contrast (gboolean *is_writable) +{ + gboolean ret; + char *gtk_theme; + + ret = FALSE; + + gtk_theme = config_get_string (KEY_GTK_THEME, is_writable); + if (gtk_theme != NULL && strcmp (gtk_theme, HIGH_CONTRAST_THEME) == 0) { + ret = TRUE; + } + g_free (gtk_theme); + + return ret; +} + +static void +config_set_high_contrast (gboolean enabled) +{ + MateConfClient *client; + + client = mateconf_client_get_default (); + + if (enabled) { + mateconf_client_set_string (client, KEY_GTK_THEME, HIGH_CONTRAST_THEME, NULL); + mateconf_client_set_string (client, KEY_ICON_THEME, HIGH_CONTRAST_THEME, NULL); + /* there isn't a high contrast marco theme afaik */ + } else { + mateconf_client_unset (client, KEY_GTK_THEME, NULL); + mateconf_client_unset (client, KEY_ICON_THEME, NULL); + mateconf_client_unset (client, KEY_MARCO_THEME, NULL); + } + + g_object_unref (client); +} + +static gboolean +config_get_sticky_keys (gboolean *is_writable) +{ + return config_get_bool (KEY_STICKY_KEYS_ENABLED, is_writable); +} + +static void +config_set_sticky_keys (gboolean enabled) +{ + MateConfClient *client; + + client = mateconf_client_get_default (); + mateconf_client_set_bool (client, KEY_STICKY_KEYS_ENABLED, enabled, NULL); + g_object_unref (client); +} + +static gboolean +config_get_bounce_keys (gboolean *is_writable) +{ + return config_get_bool (KEY_BOUNCE_KEYS_ENABLED, is_writable); +} + +static void +config_set_bounce_keys (gboolean enabled) +{ + MateConfClient *client; + + client = mateconf_client_get_default (); + mateconf_client_set_bool (client, KEY_BOUNCE_KEYS_ENABLED, enabled, NULL); + g_object_unref (client); +} + +static gboolean +config_get_slow_keys (gboolean *is_writable) +{ + return config_get_bool (KEY_SLOW_KEYS_ENABLED, is_writable); +} + +static void +config_set_slow_keys (gboolean enabled) +{ + MateConfClient *client; + + client = mateconf_client_get_default (); + mateconf_client_set_bool (client, KEY_SLOW_KEYS_ENABLED, enabled, NULL); + g_object_unref (client); +} + +static gboolean +config_have_at_mateconf_condition (const char *condition) +{ + DBusGProxy *sm_proxy; + DBusGConnection *connection; + GError *error; + gboolean res; + gboolean is_handled; + + error = NULL; + connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + if (connection == NULL) { + g_warning ("Unable to connect to session bus: %s", error->message); + return FALSE; + } + sm_proxy = dbus_g_proxy_new_for_name (connection, + SM_DBUS_NAME, + SM_DBUS_PATH, + SM_DBUS_INTERFACE); + if (sm_proxy == NULL) { + return FALSE; + } + + is_handled = FALSE; + res = dbus_g_proxy_call (sm_proxy, + "IsAutostartConditionHandled", + &error, + G_TYPE_STRING, condition, + G_TYPE_INVALID, + G_TYPE_BOOLEAN, &is_handled, + G_TYPE_INVALID); + if (! res) { + g_warning ("Unable to call IsAutostartConditionHandled (%s): %s", + condition, + error->message); + } + + g_object_unref (sm_proxy); + + return is_handled; +} + +static gboolean +config_get_at_screen_reader (gboolean *is_writable) +{ + return config_get_bool (KEY_AT_SCREEN_READER_ENABLED, is_writable); +} + +static gboolean +config_get_at_screen_keyboard (gboolean *is_writable) +{ + return config_get_bool (KEY_AT_SCREEN_KEYBOARD_ENABLED, is_writable); +} + +static gboolean +config_get_at_screen_magnifier (gboolean *is_writable) +{ + return config_get_bool (KEY_AT_SCREEN_MAGNIFIER_ENABLED, is_writable); +} + +static void +config_set_at_screen_reader (gboolean enabled) +{ + MateConfClient *client; + + client = mateconf_client_get_default (); + mateconf_client_set_bool (client, KEY_AT_SCREEN_READER_ENABLED, enabled, NULL); + g_object_unref (client); +} + +static void +config_set_at_screen_keyboard (gboolean enabled) +{ + MateConfClient *client; + + client = mateconf_client_get_default (); + mateconf_client_set_bool (client, KEY_AT_SCREEN_KEYBOARD_ENABLED, enabled, NULL); + g_object_unref (client); +} + +static void +config_set_at_screen_magnifier (gboolean enabled) +{ + MateConfClient *client; + + client = mateconf_client_get_default (); + mateconf_client_set_bool (client, KEY_AT_SCREEN_MAGNIFIER_ENABLED, enabled, NULL); + g_object_unref (client); +} + +static void +on_sticky_keys_checkbutton_toggled (GtkToggleButton *button, + GsdA11yPreferencesDialog *dialog) +{ + config_set_sticky_keys (gtk_toggle_button_get_active (button)); +} + +static void +on_bounce_keys_checkbutton_toggled (GtkToggleButton *button, + GsdA11yPreferencesDialog *dialog) +{ + config_set_bounce_keys (gtk_toggle_button_get_active (button)); +} + +static void +on_slow_keys_checkbutton_toggled (GtkToggleButton *button, + GsdA11yPreferencesDialog *dialog) +{ + config_set_slow_keys (gtk_toggle_button_get_active (button)); +} + +static void +on_high_contrast_checkbutton_toggled (GtkToggleButton *button, + GsdA11yPreferencesDialog *dialog) +{ + config_set_high_contrast (gtk_toggle_button_get_active (button)); +} + +static void +on_at_screen_reader_checkbutton_toggled (GtkToggleButton *button, + GsdA11yPreferencesDialog *dialog) +{ + config_set_at_screen_reader (gtk_toggle_button_get_active (button)); +} + +static void +on_at_screen_keyboard_checkbutton_toggled (GtkToggleButton *button, + GsdA11yPreferencesDialog *dialog) +{ + config_set_at_screen_keyboard (gtk_toggle_button_get_active (button)); +} + +static void +on_at_screen_magnifier_checkbutton_toggled (GtkToggleButton *button, + GsdA11yPreferencesDialog *dialog) +{ + config_set_at_screen_magnifier (gtk_toggle_button_get_active (button)); +} + +static void +on_large_print_checkbutton_toggled (GtkToggleButton *button, + GsdA11yPreferencesDialog *dialog) +{ + config_set_large_print (gtk_toggle_button_get_active (button)); +} + +static void +ui_set_sticky_keys (GsdA11yPreferencesDialog *dialog, + gboolean enabled) +{ + gboolean active; + + active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->sticky_keys_checkbutton)); + if (active != enabled) { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->sticky_keys_checkbutton), enabled); + } +} + +static void +ui_set_bounce_keys (GsdA11yPreferencesDialog *dialog, + gboolean enabled) +{ + gboolean active; + + active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->bounce_keys_checkbutton)); + if (active != enabled) { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->bounce_keys_checkbutton), enabled); + } +} + +static void +ui_set_slow_keys (GsdA11yPreferencesDialog *dialog, + gboolean enabled) +{ + gboolean active; + + active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->slow_keys_checkbutton)); + if (active != enabled) { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->slow_keys_checkbutton), enabled); + } +} + +static void +ui_set_high_contrast (GsdA11yPreferencesDialog *dialog, + gboolean enabled) +{ + gboolean active; + + active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->high_contrast_checkbutton)); + if (active != enabled) { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->high_contrast_checkbutton), enabled); + } +} + +static void +ui_set_at_screen_reader (GsdA11yPreferencesDialog *dialog, + gboolean enabled) +{ + gboolean active; + + active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->screen_reader_checkbutton)); + if (active != enabled) { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->screen_reader_checkbutton), enabled); + } +} + +static void +ui_set_at_screen_keyboard (GsdA11yPreferencesDialog *dialog, + gboolean enabled) +{ + gboolean active; + + active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->screen_keyboard_checkbutton)); + if (active != enabled) { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->screen_keyboard_checkbutton), enabled); + } +} + +static void +ui_set_at_screen_magnifier (GsdA11yPreferencesDialog *dialog, + gboolean enabled) +{ + gboolean active; + + active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->screen_magnifier_checkbutton)); + if (active != enabled) { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->screen_magnifier_checkbutton), enabled); + } +} + +static void +ui_set_large_print (GsdA11yPreferencesDialog *dialog, + gboolean enabled) +{ + gboolean active; + + active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->large_print_checkbutton)); + if (active != enabled) { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->large_print_checkbutton), enabled); + } +} + +static void +key_changed_cb (MateConfClient *client, + guint cnxn_id, + MateConfEntry *entry, + GsdA11yPreferencesDialog *dialog) +{ + const char *key; + MateConfValue *value; + + key = mateconf_entry_get_key (entry); + value = mateconf_entry_get_value (entry); + + if (strcmp (key, KEY_STICKY_KEYS_ENABLED) == 0) { + if (value->type == MATECONF_VALUE_BOOL) { + gboolean enabled; + + enabled = mateconf_value_get_bool (value); + ui_set_sticky_keys (dialog, enabled); + } else { + g_warning ("Error retrieving configuration key '%s': Invalid type", + key); + } + } else if (strcmp (key, KEY_BOUNCE_KEYS_ENABLED) == 0) { + if (value->type == MATECONF_VALUE_BOOL) { + gboolean enabled; + + enabled = mateconf_value_get_bool (value); + ui_set_bounce_keys (dialog, enabled); + } else { + g_warning ("Error retrieving configuration key '%s': Invalid type", + key); + } + } else if (strcmp (key, KEY_SLOW_KEYS_ENABLED) == 0) { + if (value->type == MATECONF_VALUE_BOOL) { + gboolean enabled; + + enabled = mateconf_value_get_bool (value); + ui_set_slow_keys (dialog, enabled); + } else { + g_warning ("Error retrieving configuration key '%s': Invalid type", + key); + } + } else if (strcmp (key, KEY_AT_SCREEN_READER_ENABLED) == 0) { + if (value->type == MATECONF_VALUE_BOOL) { + gboolean enabled; + + enabled = mateconf_value_get_bool (value); + ui_set_at_screen_reader (dialog, enabled); + } else { + g_warning ("Error retrieving configuration key '%s': Invalid type", + key); + } + } else if (strcmp (key, KEY_AT_SCREEN_KEYBOARD_ENABLED) == 0) { + if (value->type == MATECONF_VALUE_BOOL) { + gboolean enabled; + + enabled = mateconf_value_get_bool (value); + ui_set_at_screen_keyboard (dialog, enabled); + } else { + g_warning ("Error retrieving configuration key '%s': Invalid type", + key); + } + } else if (strcmp (key, KEY_AT_SCREEN_MAGNIFIER_ENABLED) == 0) { + if (value->type == MATECONF_VALUE_BOOL) { + gboolean enabled; + + enabled = mateconf_value_get_bool (value); + ui_set_at_screen_magnifier (dialog, enabled); + } else { + g_warning ("Error retrieving configuration key '%s': Invalid type", + key); + } + } else { + g_debug ("Config key not handled: %s", key); + } +} + +static void +setup_dialog (GsdA11yPreferencesDialog *dialog, + GtkBuilder *builder) +{ + GtkWidget *widget; + gboolean enabled; + gboolean is_writable; + MateConfClient *client; + + widget = GTK_WIDGET (gtk_builder_get_object (builder, + "sticky_keys_checkbutton")); + dialog->priv->sticky_keys_checkbutton = widget; + g_signal_connect (widget, + "toggled", + G_CALLBACK (on_sticky_keys_checkbutton_toggled), + NULL); + enabled = config_get_sticky_keys (&is_writable); + ui_set_sticky_keys (dialog, enabled); + if (! is_writable) { + gtk_widget_set_sensitive (widget, FALSE); + } + + widget = GTK_WIDGET (gtk_builder_get_object (builder, + "bounce_keys_checkbutton")); + dialog->priv->bounce_keys_checkbutton = widget; + g_signal_connect (widget, + "toggled", + G_CALLBACK (on_bounce_keys_checkbutton_toggled), + NULL); + enabled = config_get_bounce_keys (&is_writable); + ui_set_bounce_keys (dialog, enabled); + if (! is_writable) { + gtk_widget_set_sensitive (widget, FALSE); + } + + widget = GTK_WIDGET (gtk_builder_get_object (builder, + "slow_keys_checkbutton")); + dialog->priv->slow_keys_checkbutton = widget; + g_signal_connect (widget, + "toggled", + G_CALLBACK (on_slow_keys_checkbutton_toggled), + NULL); + enabled = config_get_slow_keys (&is_writable); + ui_set_slow_keys (dialog, enabled); + if (! is_writable) { + gtk_widget_set_sensitive (widget, FALSE); + } + + widget = GTK_WIDGET (gtk_builder_get_object (builder, + "high_contrast_checkbutton")); + dialog->priv->high_contrast_checkbutton = widget; + g_signal_connect (widget, + "toggled", + G_CALLBACK (on_high_contrast_checkbutton_toggled), + NULL); + enabled = config_get_high_contrast (&is_writable); + ui_set_high_contrast (dialog, enabled); + if (! is_writable) { + gtk_widget_set_sensitive (widget, FALSE); + } + + widget = GTK_WIDGET (gtk_builder_get_object (builder, + "at_screen_keyboard_checkbutton")); + dialog->priv->screen_keyboard_checkbutton = widget; + g_signal_connect (widget, + "toggled", + G_CALLBACK (on_at_screen_keyboard_checkbutton_toggled), + NULL); + enabled = config_get_at_screen_keyboard (&is_writable); + ui_set_at_screen_keyboard (dialog, enabled); + if (! is_writable) { + gtk_widget_set_sensitive (widget, FALSE); + } + gtk_widget_set_no_show_all (widget, TRUE); + if (config_have_at_mateconf_condition ("MATE " KEY_AT_SCREEN_KEYBOARD_ENABLED)) { + gtk_widget_show_all (widget); + } else { + gtk_widget_hide (widget); + } + + widget = GTK_WIDGET (gtk_builder_get_object (builder, + "at_screen_reader_checkbutton")); + dialog->priv->screen_reader_checkbutton = widget; + g_signal_connect (widget, + "toggled", + G_CALLBACK (on_at_screen_reader_checkbutton_toggled), + NULL); + enabled = config_get_at_screen_reader (&is_writable); + ui_set_at_screen_reader (dialog, enabled); + if (! is_writable) { + gtk_widget_set_sensitive (widget, FALSE); + } + gtk_widget_set_no_show_all (widget, TRUE); + if (config_have_at_mateconf_condition ("MATE " KEY_AT_SCREEN_READER_ENABLED)) { + gtk_widget_show_all (widget); + } else { + gtk_widget_hide (widget); + } + + widget = GTK_WIDGET (gtk_builder_get_object (builder, + "at_screen_magnifier_checkbutton")); + dialog->priv->screen_magnifier_checkbutton = widget; + g_signal_connect (widget, + "toggled", + G_CALLBACK (on_at_screen_magnifier_checkbutton_toggled), + NULL); + enabled = config_get_at_screen_magnifier (&is_writable); + ui_set_at_screen_magnifier (dialog, enabled); + if (! is_writable) { + gtk_widget_set_sensitive (widget, FALSE); + } + gtk_widget_set_no_show_all (widget, TRUE); + if (config_have_at_mateconf_condition ("MATE " KEY_AT_SCREEN_MAGNIFIER_ENABLED)) { + gtk_widget_show_all (widget); + } else { + gtk_widget_hide (widget); + } + + widget = GTK_WIDGET (gtk_builder_get_object (builder, + "large_print_checkbutton")); + dialog->priv->large_print_checkbutton = widget; + g_signal_connect (widget, + "toggled", + G_CALLBACK (on_large_print_checkbutton_toggled), + NULL); + enabled = config_get_large_print (&is_writable); + ui_set_large_print (dialog, enabled); + if (! is_writable) { + gtk_widget_set_sensitive (widget, FALSE); + } + + + client = mateconf_client_get_default (); + mateconf_client_add_dir (client, + KEY_A11Y_DIR, + MATECONF_CLIENT_PRELOAD_ONELEVEL, + NULL); + dialog->priv->a11y_dir_cnxn = mateconf_client_notify_add (client, + KEY_A11Y_DIR, + (MateConfClientNotifyFunc)key_changed_cb, + dialog, + NULL, + NULL); + + mateconf_client_add_dir (client, + KEY_AT_DIR, + MATECONF_CLIENT_PRELOAD_ONELEVEL, + NULL); + dialog->priv->gsd_a11y_dir_cnxn = mateconf_client_notify_add (client, + KEY_AT_DIR, + (MateConfClientNotifyFunc)key_changed_cb, + dialog, + NULL, + NULL); + + g_object_unref (client); +} + +static void +gsd_a11y_preferences_dialog_init (GsdA11yPreferencesDialog *dialog) +{ + static const gchar *ui_file_path = GTKBUILDERDIR "/" GTKBUILDER_UI_FILE; + gchar *objects[] = {"main_box", NULL}; + GError *error = NULL; + GtkBuilder *builder; + + dialog->priv = GSD_A11Y_PREFERENCES_DIALOG_GET_PRIVATE (dialog); + + builder = gtk_builder_new (); + gtk_builder_set_translation_domain (builder, PACKAGE); + if (gtk_builder_add_objects_from_file (builder, ui_file_path, objects, + &error) == 0) { + g_warning ("Could not load A11Y-UI: %s", error->message); + g_error_free (error); + } else { + GtkWidget *widget; + + widget = GTK_WIDGET (gtk_builder_get_object (builder, + "main_box")); + gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), + widget); + gtk_container_set_border_width (GTK_CONTAINER (widget), 12); + setup_dialog (dialog, builder); + } + + g_object_unref (builder); + + gtk_container_set_border_width (GTK_CONTAINER (dialog), 12); + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); + gtk_window_set_title (GTK_WINDOW (dialog), _("Universal Access Preferences")); + gtk_window_set_icon_name (GTK_WINDOW (dialog), "preferences-desktop-accessibility"); + g_object_set (dialog, + "allow-shrink", FALSE, + "allow-grow", FALSE, + NULL); + + gtk_dialog_add_buttons (GTK_DIALOG (dialog), + GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, + NULL); + g_signal_connect (dialog, + "response", + G_CALLBACK (on_response), + dialog); + + + gtk_widget_show_all (GTK_WIDGET (dialog)); +} + +static void +gsd_a11y_preferences_dialog_finalize (GObject *object) +{ + GsdA11yPreferencesDialog *dialog; + MateConfClient *client; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_A11Y_PREFERENCES_DIALOG (object)); + + dialog = GSD_A11Y_PREFERENCES_DIALOG (object); + + g_return_if_fail (dialog->priv != NULL); + + client = mateconf_client_get_default (); + + if (dialog->priv->a11y_dir_cnxn > 0) { + mateconf_client_notify_remove (client, dialog->priv->a11y_dir_cnxn); + } + if (dialog->priv->gsd_a11y_dir_cnxn > 0) { + mateconf_client_notify_remove (client, dialog->priv->gsd_a11y_dir_cnxn); + } + + g_object_unref (client); + + G_OBJECT_CLASS (gsd_a11y_preferences_dialog_parent_class)->finalize (object); +} + +GtkWidget * +gsd_a11y_preferences_dialog_new (void) +{ + GObject *object; + + object = g_object_new (GSD_TYPE_A11Y_PREFERENCES_DIALOG, + NULL); + + return GTK_WIDGET (object); +} diff --git a/plugins/a11y-keyboard/gsd-a11y-preferences-dialog.h b/plugins/a11y-keyboard/gsd-a11y-preferences-dialog.h new file mode 100644 index 0000000..2be096a --- /dev/null +++ b/plugins/a11y-keyboard/gsd-a11y-preferences-dialog.h @@ -0,0 +1,59 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 William Jon McCann <[email protected]> + * + * 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_A11Y_PREFERENCES_DIALOG_H +#define __GSD_A11Y_PREFERENCES_DIALOG_H + +#include <glib-object.h> +#include <gtk/gtk.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_A11Y_PREFERENCES_DIALOG (gsd_a11y_preferences_dialog_get_type ()) +#define GSD_A11Y_PREFERENCES_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_A11Y_PREFERENCES_DIALOG, GsdA11yPreferencesDialog)) +#define GSD_A11Y_PREFERENCES_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_A11Y_PREFERENCES_DIALOG, GsdA11yPreferencesDialogClass)) +#define GSD_IS_A11Y_PREFERENCES_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_A11Y_PREFERENCES_DIALOG)) +#define GSD_IS_A11Y_PREFERENCES_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_A11Y_PREFERENCES_DIALOG)) +#define GSD_A11Y_PREFERENCES_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_A11Y_PREFERENCES_DIALOG, GsdA11yPreferencesDialogClass)) + +typedef struct GsdA11yPreferencesDialogPrivate GsdA11yPreferencesDialogPrivate; + +typedef struct +{ + GtkDialog parent; + GsdA11yPreferencesDialogPrivate *priv; +} GsdA11yPreferencesDialog; + +typedef struct +{ + GtkDialogClass parent_class; +} GsdA11yPreferencesDialogClass; + +GType gsd_a11y_preferences_dialog_get_type (void); + +GtkWidget * gsd_a11y_preferences_dialog_new (void); + +#ifdef __cplusplus +} +#endif + +#endif /* __GSD_A11Y_PREFERENCES_DIALOG_H */ diff --git a/plugins/a11y-keyboard/gsd-a11y-preferences-dialog.ui b/plugins/a11y-keyboard/gsd-a11y-preferences-dialog.ui new file mode 100644 index 0000000..6a0fcb0 --- /dev/null +++ b/plugins/a11y-keyboard/gsd-a11y-preferences-dialog.ui @@ -0,0 +1,199 @@ +<?xml version="1.0"?> +<interface> + <!-- interface-requires gtk+ 2.6 --> + <!-- interface-naming-policy toplevel-contextual --> + <object class="GtkDialog" id="dialog1"> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="border_width">5</property> + <property name="title" translatable="yes">Universal Access Preferences</property> + <property name="window_position">center-on-parent</property> + <property name="icon_name">preferences-desktop-accessibility</property> + <property name="type_hint">dialog</property> + <property name="has_separator">False</property> + <child internal-child="vbox"> + <object class="GtkVBox" id="dialog-vbox1"> + <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="spacing">2</property> + <child> + <object class="GtkHBox" id="main_box"> + <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="border_width">5</property> + <property name="spacing">10</property> + <child> + <object class="GtkImage" id="image1"> + <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="yalign">0</property> + <property name="icon_name">preferences-desktop-accessibility</property> + <property name="icon-size">6</property> + </object> + <packing> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkVBox" id="vbox1"> + <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="border_width">5</property> + <property name="spacing">6</property> + <child> + <object class="GtkCheckButton" id="at_screen_keyboard_checkbutton"> + <property name="label" translatable="yes">Use on-screen _keyboard</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="at_screen_reader_checkbutton"> + <property name="label" translatable="yes">Use screen _reader</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="at_screen_magnifier_checkbutton"> + <property name="label" translatable="yes">Use screen _magnifier</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="high_contrast_checkbutton"> + <property name="label" translatable="yes">Enhance _contrast in colors</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="position">3</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="large_print_checkbutton"> + <property name="label" translatable="yes">Make _text larger and easier to read</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="position">4</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="sticky_keys_checkbutton"> + <property name="label" translatable="yes">_Press keyboard shortcuts one key at a time (Sticky Keys)</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="position">5</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="bounce_keys_checkbutton"> + <property name="label" translatable="yes">_Ignore duplicate keypresses (Bounce Keys)</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="position">6</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="slow_keys_checkbutton"> + <property name="label" translatable="yes">Press and _hold keys to accept them (Slow Keys)</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="position">7</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="position">1</property> + </packing> + </child> + <child internal-child="action_area"> + <object class="GtkHButtonBox" id="dialog-action_area1"> + <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="layout_style">end</property> + <child> + <object class="GtkButton" id="button1"> + <property name="label">gtk-close</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="pack_type">end</property> + <property name="position">0</property> + </packing> + </child> + </object> + </child> + <action-widgets> + <action-widget response="0">button1</action-widget> + </action-widgets> + </object> +</interface> diff --git a/plugins/a11y-keyboard/test-a11y-preferences-dialog.c b/plugins/a11y-keyboard/test-a11y-preferences-dialog.c new file mode 100644 index 0000000..343f61c --- /dev/null +++ b/plugins/a11y-keyboard/test-a11y-preferences-dialog.c @@ -0,0 +1,64 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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 <stdlib.h> + +#include <glib/gi18n.h> +#include <gtk/gtk.h> + +#include "gsd-a11y-preferences-dialog.h" + +static void +test_window (void) +{ + GtkWidget *window; + + window = gsd_a11y_preferences_dialog_new (); + gtk_dialog_run (GTK_DIALOG (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); + } + + test_window (); + + return 0; +} diff --git a/plugins/background/Makefile.am b/plugins/background/Makefile.am new file mode 100644 index 0000000..f773144 --- /dev/null +++ b/plugins/background/Makefile.am @@ -0,0 +1,75 @@ +NULL = + +noinst_PROGRAMS = \ + test-background \ + $(NULL) + +test_background_SOURCES = \ + test-background.c \ + gsd-background-manager.h \ + gsd-background-manager.c \ + $(NULL) + +test_background_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +test_background_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +test_background_LDADD = \ + $(top_builddir)/mate-settings-daemon/libgsd-profile.la \ + $(SETTINGS_PLUGIN_LIBS) \ + $(X11_LIBS) \ + $(NULL) + +plugin_LTLIBRARIES = \ + libbackground.la \ + $(NULL) + +libbackground_la_SOURCES = \ + gsd-background-plugin.h \ + gsd-background-plugin.c \ + gsd-background-manager.h \ + gsd-background-manager.c \ + $(NULL) + +libbackground_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -I$(top_srcdir)/plugins/background/libbackground \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libbackground_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libbackground_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) \ + $(NULL) + +libbackground_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(NULL) + +plugin_in_files = \ + background.mate-settings-plugin.in \ + $(NULL) + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) + +EXTRA_DIST = \ + $(plugin_in_files) \ + $(NULL) + +CLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +DISTCLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +@GSD_INTLTOOL_PLUGIN_RULE@ diff --git a/plugins/background/Makefile.in b/plugins/background/Makefile.in new file mode 100644 index 0000000..33c5b46 --- /dev/null +++ b/plugins/background/Makefile.in @@ -0,0 +1,758 @@ +# 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@ +noinst_PROGRAMS = test-background$(EXEEXT) $(am__EXEEXT_1) +subdir = plugins/background +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)$(plugindir)" +LTLIBRARIES = $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +libbackground_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__objects_1 = +am_libbackground_la_OBJECTS = \ + libbackground_la-gsd-background-plugin.lo \ + libbackground_la-gsd-background-manager.lo $(am__objects_1) +libbackground_la_OBJECTS = $(am_libbackground_la_OBJECTS) +libbackground_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libbackground_la_CFLAGS) \ + $(CFLAGS) $(libbackground_la_LDFLAGS) $(LDFLAGS) -o $@ +am__EXEEXT_1 = +PROGRAMS = $(noinst_PROGRAMS) +am_test_background_OBJECTS = \ + test_background-test-background.$(OBJEXT) \ + test_background-gsd-background-manager.$(OBJEXT) \ + $(am__objects_1) +test_background_OBJECTS = $(am_test_background_OBJECTS) +test_background_DEPENDENCIES = \ + $(top_builddir)/mate-settings-daemon/libgsd-profile.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +test_background_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_background_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 = $(libbackground_la_SOURCES) $(test_background_SOURCES) +DIST_SOURCES = $(libbackground_la_SOURCES) $(test_background_SOURCES) +DATA = $(plugin_DATA) +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 = +test_background_SOURCES = \ + test-background.c \ + gsd-background-manager.h \ + gsd-background-manager.c \ + $(NULL) + +test_background_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +test_background_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +test_background_LDADD = \ + $(top_builddir)/mate-settings-daemon/libgsd-profile.la \ + $(SETTINGS_PLUGIN_LIBS) \ + $(X11_LIBS) \ + $(NULL) + +plugin_LTLIBRARIES = \ + libbackground.la \ + $(NULL) + +libbackground_la_SOURCES = \ + gsd-background-plugin.h \ + gsd-background-plugin.c \ + gsd-background-manager.h \ + gsd-background-manager.c \ + $(NULL) + +libbackground_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -I$(top_srcdir)/plugins/background/libbackground \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libbackground_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libbackground_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) \ + $(NULL) + +libbackground_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(NULL) + +plugin_in_files = \ + background.mate-settings-plugin.in \ + $(NULL) + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) +EXTRA_DIST = \ + $(plugin_in_files) \ + $(NULL) + +CLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +DISTCLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +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/background/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plugins/background/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 +libbackground.la: $(libbackground_la_OBJECTS) $(libbackground_la_DEPENDENCIES) + $(libbackground_la_LINK) -rpath $(plugindir) $(libbackground_la_OBJECTS) $(libbackground_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-background$(EXEEXT): $(test_background_OBJECTS) $(test_background_DEPENDENCIES) + @rm -f test-background$(EXEEXT) + $(test_background_LINK) $(test_background_OBJECTS) $(test_background_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libbackground_la-gsd-background-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libbackground_la-gsd-background-plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_background-gsd-background-manager.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_background-test-background.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 $@ $< + +libbackground_la-gsd-background-plugin.lo: gsd-background-plugin.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libbackground_la_CPPFLAGS) $(CPPFLAGS) $(libbackground_la_CFLAGS) $(CFLAGS) -MT libbackground_la-gsd-background-plugin.lo -MD -MP -MF $(DEPDIR)/libbackground_la-gsd-background-plugin.Tpo -c -o libbackground_la-gsd-background-plugin.lo `test -f 'gsd-background-plugin.c' || echo '$(srcdir)/'`gsd-background-plugin.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libbackground_la-gsd-background-plugin.Tpo $(DEPDIR)/libbackground_la-gsd-background-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-background-plugin.c' object='libbackground_la-gsd-background-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) $(libbackground_la_CPPFLAGS) $(CPPFLAGS) $(libbackground_la_CFLAGS) $(CFLAGS) -c -o libbackground_la-gsd-background-plugin.lo `test -f 'gsd-background-plugin.c' || echo '$(srcdir)/'`gsd-background-plugin.c + +libbackground_la-gsd-background-manager.lo: gsd-background-manager.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libbackground_la_CPPFLAGS) $(CPPFLAGS) $(libbackground_la_CFLAGS) $(CFLAGS) -MT libbackground_la-gsd-background-manager.lo -MD -MP -MF $(DEPDIR)/libbackground_la-gsd-background-manager.Tpo -c -o libbackground_la-gsd-background-manager.lo `test -f 'gsd-background-manager.c' || echo '$(srcdir)/'`gsd-background-manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libbackground_la-gsd-background-manager.Tpo $(DEPDIR)/libbackground_la-gsd-background-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-background-manager.c' object='libbackground_la-gsd-background-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) $(libbackground_la_CPPFLAGS) $(CPPFLAGS) $(libbackground_la_CFLAGS) $(CFLAGS) -c -o libbackground_la-gsd-background-manager.lo `test -f 'gsd-background-manager.c' || echo '$(srcdir)/'`gsd-background-manager.c + +test_background-test-background.o: test-background.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_background_CPPFLAGS) $(CPPFLAGS) $(test_background_CFLAGS) $(CFLAGS) -MT test_background-test-background.o -MD -MP -MF $(DEPDIR)/test_background-test-background.Tpo -c -o test_background-test-background.o `test -f 'test-background.c' || echo '$(srcdir)/'`test-background.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_background-test-background.Tpo $(DEPDIR)/test_background-test-background.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-background.c' object='test_background-test-background.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_background_CPPFLAGS) $(CPPFLAGS) $(test_background_CFLAGS) $(CFLAGS) -c -o test_background-test-background.o `test -f 'test-background.c' || echo '$(srcdir)/'`test-background.c + +test_background-test-background.obj: test-background.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_background_CPPFLAGS) $(CPPFLAGS) $(test_background_CFLAGS) $(CFLAGS) -MT test_background-test-background.obj -MD -MP -MF $(DEPDIR)/test_background-test-background.Tpo -c -o test_background-test-background.obj `if test -f 'test-background.c'; then $(CYGPATH_W) 'test-background.c'; else $(CYGPATH_W) '$(srcdir)/test-background.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_background-test-background.Tpo $(DEPDIR)/test_background-test-background.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test-background.c' object='test_background-test-background.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_background_CPPFLAGS) $(CPPFLAGS) $(test_background_CFLAGS) $(CFLAGS) -c -o test_background-test-background.obj `if test -f 'test-background.c'; then $(CYGPATH_W) 'test-background.c'; else $(CYGPATH_W) '$(srcdir)/test-background.c'; fi` + +test_background-gsd-background-manager.o: gsd-background-manager.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_background_CPPFLAGS) $(CPPFLAGS) $(test_background_CFLAGS) $(CFLAGS) -MT test_background-gsd-background-manager.o -MD -MP -MF $(DEPDIR)/test_background-gsd-background-manager.Tpo -c -o test_background-gsd-background-manager.o `test -f 'gsd-background-manager.c' || echo '$(srcdir)/'`gsd-background-manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_background-gsd-background-manager.Tpo $(DEPDIR)/test_background-gsd-background-manager.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-background-manager.c' object='test_background-gsd-background-manager.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_background_CPPFLAGS) $(CPPFLAGS) $(test_background_CFLAGS) $(CFLAGS) -c -o test_background-gsd-background-manager.o `test -f 'gsd-background-manager.c' || echo '$(srcdir)/'`gsd-background-manager.c + +test_background-gsd-background-manager.obj: gsd-background-manager.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_background_CPPFLAGS) $(CPPFLAGS) $(test_background_CFLAGS) $(CFLAGS) -MT test_background-gsd-background-manager.obj -MD -MP -MF $(DEPDIR)/test_background-gsd-background-manager.Tpo -c -o test_background-gsd-background-manager.obj `if test -f 'gsd-background-manager.c'; then $(CYGPATH_W) 'gsd-background-manager.c'; else $(CYGPATH_W) '$(srcdir)/gsd-background-manager.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/test_background-gsd-background-manager.Tpo $(DEPDIR)/test_background-gsd-background-manager.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-background-manager.c' object='test_background-gsd-background-manager.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_background_CPPFLAGS) $(CPPFLAGS) $(test_background_CFLAGS) $(CFLAGS) -c -o test_background-gsd-background-manager.obj `if test -f 'gsd-background-manager.c'; then $(CYGPATH_W) 'gsd-background-manager.c'; else $(CYGPATH_W) '$(srcdir)/gsd-background-manager.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +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 + +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) $(PROGRAMS) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -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." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + clean-pluginLTLIBRARIES 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-pluginDATA install-pluginLTLIBRARIES + +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: uninstall-pluginDATA uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstPROGRAMS clean-pluginLTLIBRARIES \ + 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-pluginDATA install-pluginLTLIBRARIES 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 uninstall-pluginDATA uninstall-pluginLTLIBRARIES + + +@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/background/background.mate-settings-plugin.in b/plugins/background/background.mate-settings-plugin.in new file mode 100644 index 0000000..73d27b4 --- /dev/null +++ b/plugins/background/background.mate-settings-plugin.in @@ -0,0 +1,8 @@ +[MATE Settings Plugin] +Module=background +IAge=0 +_Name=Background +_Description=Background plugin +Authors= +Copyright=Copyright © 2007 +Website= diff --git a/plugins/background/gsd-background-manager.c b/plugins/background/gsd-background-manager.c new file mode 100644 index 0000000..8c42445 --- /dev/null +++ b/plugins/background/gsd-background-manager.c @@ -0,0 +1,579 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright © 2001 Ximian, Inc. + * Copyright (C) 2007 William Jon McCann <[email protected]> + * Copyright 2007 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include "config.h" + +#include <sys/types.h> +#include <sys/wait.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> + +#include <locale.h> + +#include <dbus/dbus.h> + +#include <glib.h> +#include <glib/gi18n.h> +#include <gdk/gdk.h> +#include <gdk/gdkx.h> +#include <mateconf/mateconf-client.h> + +#define MATE_DESKTOP_USE_UNSTABLE_API +#include <libmateui/mate-bg.h> +#include <X11/Xatom.h> + +#include "mate-settings-profile.h" +#include "gsd-background-manager.h" + +#define CAJA_SHOW_DESKTOP_KEY "/apps/caja/preferences/show_desktop" + +#define GSD_BACKGROUND_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_BACKGROUND_MANAGER, GsdBackgroundManagerPrivate)) + +struct GsdBackgroundManagerPrivate +{ + MateConfClient *client; + MateBG *bg; + guint bg_notify_id; + guint timeout_id; + + DBusConnection *dbus_connection; +}; + +static void gsd_background_manager_class_init (GsdBackgroundManagerClass *klass); +static void gsd_background_manager_init (GsdBackgroundManager *background_manager); +static void gsd_background_manager_finalize (GObject *object); + +G_DEFINE_TYPE (GsdBackgroundManager, gsd_background_manager, G_TYPE_OBJECT) + +static gpointer manager_object = NULL; + +static gboolean +caja_is_running (void) +{ + Atom window_id_atom; + Window caja_xid; + Atom actual_type; + int actual_format; + unsigned long nitems; + unsigned long bytes_after; + unsigned char *data; + int retval; + Atom wmclass_atom; + gboolean running; + gint error; + + window_id_atom = XInternAtom (GDK_DISPLAY (), + "CAJA_DESKTOP_WINDOW_ID", True); + + if (window_id_atom == None) { + return FALSE; + } + + retval = XGetWindowProperty (GDK_DISPLAY (), + GDK_ROOT_WINDOW (), + window_id_atom, + 0, + 1, + False, + XA_WINDOW, + &actual_type, + &actual_format, + &nitems, + &bytes_after, + &data); + + if (data != NULL) { + caja_xid = *(Window *) data; + XFree (data); + } else { + return FALSE; + } + + if (actual_type != XA_WINDOW) { + return FALSE; + } + if (actual_format != 32) { + return FALSE; + } + + wmclass_atom = XInternAtom (GDK_DISPLAY (), "WM_CLASS", False); + + gdk_error_trap_push (); + + retval = XGetWindowProperty (GDK_DISPLAY (), + caja_xid, + wmclass_atom, + 0, + 24, + False, + XA_STRING, + &actual_type, + &actual_format, + &nitems, + &bytes_after, + &data); + + error = gdk_error_trap_pop (); + + if (error == BadWindow) { + return FALSE; + } + + if (actual_type == XA_STRING && + nitems == 24 && + bytes_after == 0 && + actual_format == 8 && + data != NULL && + !strcmp ((char *)data, "desktop_window") && + !strcmp ((char *)data + strlen ((char *)data) + 1, "Caja")) { + running = TRUE; + } else { + running = FALSE; + } + + if (data != NULL) { + XFree (data); + } + + return running; +} + +static void +draw_background (GsdBackgroundManager *manager, + gboolean use_crossfade) +{ + GdkDisplay *display; + int n_screens; + int i; + + if (caja_is_running ()) { + return; + } + + mate_settings_profile_start (NULL); + + display = gdk_display_get_default (); + n_screens = gdk_display_get_n_screens (display); + + for (i = 0; i < n_screens; ++i) { + GdkScreen *screen; + GdkWindow *root_window; + GdkPixmap *pixmap; + + screen = gdk_display_get_screen (display, i); + + root_window = gdk_screen_get_root_window (screen); + + pixmap = mate_bg_create_pixmap (manager->priv->bg, + root_window, + gdk_screen_get_width (screen), + gdk_screen_get_height (screen), + TRUE); + + if (use_crossfade) { + MateBGCrossfade *fade; + + fade = mate_bg_set_pixmap_as_root_with_crossfade (screen, pixmap); + g_signal_connect (fade, "finished", + G_CALLBACK (g_object_unref), NULL); + } else { + mate_bg_set_pixmap_as_root (screen, pixmap); + } + + g_object_unref (pixmap); + } + + mate_settings_profile_end (NULL); +} + +static void +on_bg_changed (MateBG *bg, + GsdBackgroundManager *manager) +{ + draw_background (manager, TRUE); +} + +static void +on_bg_transitioned (MateBG *bg, + GsdBackgroundManager *manager) +{ + draw_background (manager, FALSE); +} + +static void +mateconf_changed_callback (MateConfClient *client, + guint cnxn_id, + MateConfEntry *entry, + GsdBackgroundManager *manager) +{ + mate_bg_load_from_preferences (manager->priv->bg, + manager->priv->client); +} + +static void +watch_bg_preferences (GsdBackgroundManager *manager) +{ + g_assert (manager->priv->bg_notify_id == 0); + + mateconf_client_add_dir (manager->priv->client, + MATE_BG_KEY_DIR, + MATECONF_CLIENT_PRELOAD_NONE, + NULL); + manager->priv->bg_notify_id = mateconf_client_notify_add (manager->priv->client, + MATE_BG_KEY_DIR, + (MateConfClientNotifyFunc)mateconf_changed_callback, + manager, + NULL, + NULL); +} + +static void +setup_bg (GsdBackgroundManager *manager) +{ + g_return_if_fail (manager->priv->bg == NULL); + + manager->priv->bg = mate_bg_new (); + + g_signal_connect (manager->priv->bg, + "changed", + G_CALLBACK (on_bg_changed), + manager); + + g_signal_connect (manager->priv->bg, + "transitioned", + G_CALLBACK (on_bg_transitioned), + manager); + + watch_bg_preferences (manager); + mate_bg_load_from_preferences (manager->priv->bg, + manager->priv->client); +} + +static gboolean +queue_draw_background (GsdBackgroundManager *manager) +{ + manager->priv->timeout_id = 0; + if (caja_is_running ()) { + return FALSE; + } + setup_bg (manager); + draw_background (manager, FALSE); + return FALSE; +} + +static DBusHandlerResult +on_bus_message (DBusConnection *connection, + DBusMessage *message, + void *user_data) +{ + GsdBackgroundManager *manager = user_data; + + if (dbus_message_is_signal (message, + "org.mate.SessionManager", + "SessionRunning")) { + /* If the session finishes then check if caja is + * running and if not, set the background. + * + * We wait a few seconds after the session is up + * because caja tells the session manager that its + * ready before it sets the background. + */ + manager->priv->timeout_id = g_timeout_add_seconds (8, + (GSourceFunc) + queue_draw_background, + manager); + dbus_connection_remove_filter (connection, + on_bus_message, + manager); + + manager->priv->dbus_connection = NULL; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static void +draw_background_after_session_loads (GsdBackgroundManager *manager) +{ + DBusConnection *connection; + + connection = dbus_bus_get (DBUS_BUS_SESSION, NULL); + + if (connection == NULL) { + return; + } + + if (!dbus_connection_add_filter (connection, on_bus_message, manager, NULL)) { + return; + }; + + manager->priv->dbus_connection = connection; +} + +static void +on_screen_size_changed (GdkScreen *screen, + GsdBackgroundManager *manager) +{ + gboolean caja_show_desktop; + + caja_show_desktop = mateconf_client_get_bool (manager->priv->client, + CAJA_SHOW_DESKTOP_KEY, + NULL); + + if (!caja_is_running () || !caja_show_desktop) { + if (manager->priv->bg == NULL) { + setup_bg (manager); + } + draw_background (manager, FALSE); + } +} + +static void +disconnect_screen_signals (GsdBackgroundManager *manager) +{ + GdkDisplay *display; + int i; + int n_screens; + + display = gdk_display_get_default (); + n_screens = gdk_display_get_n_screens (display); + + for (i = 0; i < n_screens; ++i) { + GdkScreen *screen; + screen = gdk_display_get_screen (display, i); + g_signal_handlers_disconnect_by_func (screen, + G_CALLBACK (on_screen_size_changed), + manager); + } +} + +static void +connect_screen_signals (GsdBackgroundManager *manager) +{ + GdkDisplay *display; + int i; + int n_screens; + + display = gdk_display_get_default (); + n_screens = gdk_display_get_n_screens (display); + + for (i = 0; i < n_screens; ++i) { + GdkScreen *screen; + screen = gdk_display_get_screen (display, i); + g_signal_connect (screen, + "monitors-changed", + G_CALLBACK (on_screen_size_changed), + manager); + g_signal_connect (screen, + "size-changed", + G_CALLBACK (on_screen_size_changed), + manager); + } +} + +gboolean +gsd_background_manager_start (GsdBackgroundManager *manager, + GError **error) +{ + gboolean caja_show_desktop; + + g_debug ("Starting background manager"); + mate_settings_profile_start (NULL); + + manager->priv->client = mateconf_client_get_default (); + + /* If this is set, caja will draw the background and is + * almost definitely in our session. however, it may not be + * running yet (so is_caja_running() will fail). so, on + * startup, just don't do anything if this key is set so we + * don't waste time setting the background only to have + * caja overwrite it. + */ + caja_show_desktop = mateconf_client_get_bool (manager->priv->client, + CAJA_SHOW_DESKTOP_KEY, + NULL); + + if (!caja_show_desktop) { + setup_bg (manager); + } else { + draw_background_after_session_loads (manager); + } + + connect_screen_signals (manager); + + mate_settings_profile_end (NULL); + + return TRUE; +} + +void +gsd_background_manager_stop (GsdBackgroundManager *manager) +{ + GsdBackgroundManagerPrivate *p = manager->priv; + + g_debug ("Stopping background manager"); + + disconnect_screen_signals (manager); + + if (manager->priv->dbus_connection != NULL) { + dbus_connection_remove_filter (manager->priv->dbus_connection, + on_bus_message, + manager); + } + + if (manager->priv->bg_notify_id != 0) { + mateconf_client_remove_dir (manager->priv->client, + MATE_BG_KEY_DIR, + NULL); + mateconf_client_notify_remove (manager->priv->client, + manager->priv->bg_notify_id); + manager->priv->bg_notify_id = 0; + } + + if (p->client != NULL) { + g_object_unref (p->client); + p->client = NULL; + } + + if (p->timeout_id != 0) { + g_source_remove (p->timeout_id); + p->timeout_id = 0; + } + + if (p->bg != NULL) { + g_object_unref (p->bg); + p->bg = NULL; + } +} + +static void +gsd_background_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GsdBackgroundManager *self; + + self = GSD_BACKGROUND_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gsd_background_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GsdBackgroundManager *self; + + self = GSD_BACKGROUND_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +gsd_background_manager_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GsdBackgroundManager *background_manager; + GsdBackgroundManagerClass *klass; + + klass = GSD_BACKGROUND_MANAGER_CLASS (g_type_class_peek (GSD_TYPE_BACKGROUND_MANAGER)); + + background_manager = GSD_BACKGROUND_MANAGER (G_OBJECT_CLASS (gsd_background_manager_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + + return G_OBJECT (background_manager); +} + +static void +gsd_background_manager_dispose (GObject *object) +{ + GsdBackgroundManager *background_manager; + + background_manager = GSD_BACKGROUND_MANAGER (object); + + G_OBJECT_CLASS (gsd_background_manager_parent_class)->dispose (object); +} + +static void +gsd_background_manager_class_init (GsdBackgroundManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gsd_background_manager_get_property; + object_class->set_property = gsd_background_manager_set_property; + object_class->constructor = gsd_background_manager_constructor; + object_class->dispose = gsd_background_manager_dispose; + object_class->finalize = gsd_background_manager_finalize; + + g_type_class_add_private (klass, sizeof (GsdBackgroundManagerPrivate)); +} + +static void +gsd_background_manager_init (GsdBackgroundManager *manager) +{ + manager->priv = GSD_BACKGROUND_MANAGER_GET_PRIVATE (manager); +} + +static void +gsd_background_manager_finalize (GObject *object) +{ + GsdBackgroundManager *background_manager; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_BACKGROUND_MANAGER (object)); + + background_manager = GSD_BACKGROUND_MANAGER (object); + + g_return_if_fail (background_manager->priv != NULL); + + G_OBJECT_CLASS (gsd_background_manager_parent_class)->finalize (object); +} + +GsdBackgroundManager * +gsd_background_manager_new (void) +{ + if (manager_object != NULL) { + g_object_ref (manager_object); + } else { + manager_object = g_object_new (GSD_TYPE_BACKGROUND_MANAGER, NULL); + g_object_add_weak_pointer (manager_object, + (gpointer *) &manager_object); + } + + return GSD_BACKGROUND_MANAGER (manager_object); +} diff --git a/plugins/background/gsd-background-manager.h b/plugins/background/gsd-background-manager.h new file mode 100644 index 0000000..27c900a --- /dev/null +++ b/plugins/background/gsd-background-manager.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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_BACKGROUND_MANAGER_H +#define __GSD_BACKGROUND_MANAGER_H + +#include <glib-object.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_BACKGROUND_MANAGER (gsd_background_manager_get_type ()) +#define GSD_BACKGROUND_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_BACKGROUND_MANAGER, GsdBackgroundManager)) +#define GSD_BACKGROUND_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_BACKGROUND_MANAGER, GsdBackgroundManagerClass)) +#define GSD_IS_BACKGROUND_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_BACKGROUND_MANAGER)) +#define GSD_IS_BACKGROUND_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_BACKGROUND_MANAGER)) +#define GSD_BACKGROUND_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_BACKGROUND_MANAGER, GsdBackgroundManagerClass)) + +typedef struct GsdBackgroundManagerPrivate GsdBackgroundManagerPrivate; + +typedef struct +{ + GObject parent; + GsdBackgroundManagerPrivate *priv; +} GsdBackgroundManager; + +typedef struct +{ + GObjectClass parent_class; +} GsdBackgroundManagerClass; + +GType gsd_background_manager_get_type (void); + +GsdBackgroundManager * gsd_background_manager_new (void); +gboolean gsd_background_manager_start (GsdBackgroundManager *manager, + GError **error); +void gsd_background_manager_stop (GsdBackgroundManager *manager); + +#ifdef __cplusplus +} +#endif + +#endif /* __GSD_BACKGROUND_MANAGER_H */ diff --git a/plugins/background/gsd-background-plugin.c b/plugins/background/gsd-background-plugin.c new file mode 100644 index 0000000..e001f39 --- /dev/null +++ b/plugins/background/gsd-background-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 <[email protected]> + * + * 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 <glib/gi18n-lib.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" +#include "gsd-background-plugin.h" +#include "gsd-background-manager.h" + +struct GsdBackgroundPluginPrivate { + GsdBackgroundManager *manager; +}; + +#define GSD_BACKGROUND_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSD_TYPE_BACKGROUND_PLUGIN, GsdBackgroundPluginPrivate)) + +MATE_SETTINGS_PLUGIN_REGISTER (GsdBackgroundPlugin, gsd_background_plugin) + +static void +gsd_background_plugin_init (GsdBackgroundPlugin *plugin) +{ + plugin->priv = GSD_BACKGROUND_PLUGIN_GET_PRIVATE (plugin); + + g_debug ("GsdBackgroundPlugin initializing"); + + plugin->priv->manager = gsd_background_manager_new (); +} + +static void +gsd_background_plugin_finalize (GObject *object) +{ + GsdBackgroundPlugin *plugin; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_BACKGROUND_PLUGIN (object)); + + g_debug ("GsdBackgroundPlugin finalizing"); + + plugin = GSD_BACKGROUND_PLUGIN (object); + + g_return_if_fail (plugin->priv != NULL); + + if (plugin->priv->manager != NULL) { + g_object_unref (plugin->priv->manager); + } + + G_OBJECT_CLASS (gsd_background_plugin_parent_class)->finalize (object); +} + +static void +impl_activate (MateSettingsPlugin *plugin) +{ + gboolean res; + GError *error; + + g_debug ("Activating background plugin"); + + error = NULL; + res = gsd_background_manager_start (GSD_BACKGROUND_PLUGIN (plugin)->priv->manager, &error); + if (! res) { + g_warning ("Unable to start background manager: %s", error->message); + g_error_free (error); + } +} + +static void +impl_deactivate (MateSettingsPlugin *plugin) +{ + g_debug ("Deactivating background plugin"); + gsd_background_manager_stop (GSD_BACKGROUND_PLUGIN (plugin)->priv->manager); +} + +static void +gsd_background_plugin_class_init (GsdBackgroundPluginClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MateSettingsPluginClass *plugin_class = MATE_SETTINGS_PLUGIN_CLASS (klass); + + object_class->finalize = gsd_background_plugin_finalize; + + plugin_class->activate = impl_activate; + plugin_class->deactivate = impl_deactivate; + + g_type_class_add_private (klass, sizeof (GsdBackgroundPluginPrivate)); +} diff --git a/plugins/background/gsd-background-plugin.h b/plugins/background/gsd-background-plugin.h new file mode 100644 index 0000000..1acaf9f --- /dev/null +++ b/plugins/background/gsd-background-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 <[email protected]> + * + * 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_BACKGROUND_PLUGIN_H__ +#define __GSD_BACKGROUND_PLUGIN_H__ + +#include <glib.h> +#include <glib-object.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_BACKGROUND_PLUGIN (gsd_background_plugin_get_type ()) +#define GSD_BACKGROUND_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_BACKGROUND_PLUGIN, GsdBackgroundPlugin)) +#define GSD_BACKGROUND_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_BACKGROUND_PLUGIN, GsdBackgroundPluginClass)) +#define GSD_IS_BACKGROUND_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_BACKGROUND_PLUGIN)) +#define GSD_IS_BACKGROUND_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_BACKGROUND_PLUGIN)) +#define GSD_BACKGROUND_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_BACKGROUND_PLUGIN, GsdBackgroundPluginClass)) + +typedef struct GsdBackgroundPluginPrivate GsdBackgroundPluginPrivate; + +typedef struct +{ + MateSettingsPlugin parent; + GsdBackgroundPluginPrivate *priv; +} GsdBackgroundPlugin; + +typedef struct +{ + MateSettingsPluginClass parent_class; +} GsdBackgroundPluginClass; + +GType gsd_background_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_BACKGROUND_PLUGIN_H__ */ diff --git a/plugins/background/test-background.c b/plugins/background/test-background.c new file mode 100644 index 0000000..a7b5ef7 --- /dev/null +++ b/plugins/background/test-background.c @@ -0,0 +1,59 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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 <stdlib.h> +#include <libintl.h> +#include <locale.h> +#include <string.h> +#include <unistd.h> + +#include <glib/gi18n.h> +#include <gtk/gtk.h> + +#include "gsd-background-manager.h" + +static gboolean +idle (GsdBackgroundManager *manager) +{ + gsd_background_manager_start (manager, NULL); + return FALSE; +} + +int +main (int argc, char *argv[]) +{ + GsdBackgroundManager *manager; + + bindtextdomain (GETTEXT_PACKAGE, MATE_SETTINGS_LOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + + setlocale (LC_ALL, ""); + + gtk_init (&argc, &argv); + + manager = gsd_background_manager_new (); + g_idle_add ((GSourceFunc)idle, manager); + + gtk_main (); + + return 0; +} diff --git a/plugins/clipboard/Makefile.am b/plugins/clipboard/Makefile.am new file mode 100644 index 0000000..f50a86e --- /dev/null +++ b/plugins/clipboard/Makefile.am @@ -0,0 +1,53 @@ +NULL = + +plugin_LTLIBRARIES = \ + libclipboard.la \ + $(NULL) + +libclipboard_la_SOURCES = \ + gsd-clipboard-plugin.h \ + gsd-clipboard-plugin.c \ + gsd-clipboard-manager.h \ + gsd-clipboard-manager.c \ + xutils.h \ + xutils.c \ + list.h \ + list.c \ + $(NULL) + +libclipboard_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libclipboard_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libclipboard_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) \ + $(NULL) + +libclipboard_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(NULL) + +plugin_in_files = \ + clipboard.mate-settings-plugin.in \ + $(NULL) + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) + +EXTRA_DIST = \ + $(plugin_in_files) \ + $(NULL) + +CLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +DISTCLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +@GSD_INTLTOOL_PLUGIN_RULE@ diff --git a/plugins/clipboard/Makefile.in b/plugins/clipboard/Makefile.in new file mode 100644 index 0000000..3516b51 --- /dev/null +++ b/plugins/clipboard/Makefile.in @@ -0,0 +1,699 @@ +# 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/clipboard +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)$(plugindir)" +LTLIBRARIES = $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +libclipboard_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__objects_1 = +am_libclipboard_la_OBJECTS = libclipboard_la-gsd-clipboard-plugin.lo \ + libclipboard_la-gsd-clipboard-manager.lo \ + libclipboard_la-xutils.lo libclipboard_la-list.lo \ + $(am__objects_1) +libclipboard_la_OBJECTS = $(am_libclipboard_la_OBJECTS) +libclipboard_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libclipboard_la_CFLAGS) \ + $(CFLAGS) $(libclipboard_la_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 = $(libclipboard_la_SOURCES) +DIST_SOURCES = $(libclipboard_la_SOURCES) +DATA = $(plugin_DATA) +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 = +plugin_LTLIBRARIES = \ + libclipboard.la \ + $(NULL) + +libclipboard_la_SOURCES = \ + gsd-clipboard-plugin.h \ + gsd-clipboard-plugin.c \ + gsd-clipboard-manager.h \ + gsd-clipboard-manager.c \ + xutils.h \ + xutils.c \ + list.h \ + list.c \ + $(NULL) + +libclipboard_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libclipboard_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libclipboard_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) \ + $(NULL) + +libclipboard_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(NULL) + +plugin_in_files = \ + clipboard.mate-settings-plugin.in \ + $(NULL) + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) +EXTRA_DIST = \ + $(plugin_in_files) \ + $(NULL) + +CLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +DISTCLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +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/clipboard/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plugins/clipboard/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 +libclipboard.la: $(libclipboard_la_OBJECTS) $(libclipboard_la_DEPENDENCIES) + $(libclipboard_la_LINK) -rpath $(plugindir) $(libclipboard_la_OBJECTS) $(libclipboard_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclipboard_la-gsd-clipboard-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclipboard_la-gsd-clipboard-plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclipboard_la-list.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclipboard_la-xutils.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 $@ $< + +libclipboard_la-gsd-clipboard-plugin.lo: gsd-clipboard-plugin.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libclipboard_la_CPPFLAGS) $(CPPFLAGS) $(libclipboard_la_CFLAGS) $(CFLAGS) -MT libclipboard_la-gsd-clipboard-plugin.lo -MD -MP -MF $(DEPDIR)/libclipboard_la-gsd-clipboard-plugin.Tpo -c -o libclipboard_la-gsd-clipboard-plugin.lo `test -f 'gsd-clipboard-plugin.c' || echo '$(srcdir)/'`gsd-clipboard-plugin.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libclipboard_la-gsd-clipboard-plugin.Tpo $(DEPDIR)/libclipboard_la-gsd-clipboard-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-clipboard-plugin.c' object='libclipboard_la-gsd-clipboard-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) $(libclipboard_la_CPPFLAGS) $(CPPFLAGS) $(libclipboard_la_CFLAGS) $(CFLAGS) -c -o libclipboard_la-gsd-clipboard-plugin.lo `test -f 'gsd-clipboard-plugin.c' || echo '$(srcdir)/'`gsd-clipboard-plugin.c + +libclipboard_la-gsd-clipboard-manager.lo: gsd-clipboard-manager.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libclipboard_la_CPPFLAGS) $(CPPFLAGS) $(libclipboard_la_CFLAGS) $(CFLAGS) -MT libclipboard_la-gsd-clipboard-manager.lo -MD -MP -MF $(DEPDIR)/libclipboard_la-gsd-clipboard-manager.Tpo -c -o libclipboard_la-gsd-clipboard-manager.lo `test -f 'gsd-clipboard-manager.c' || echo '$(srcdir)/'`gsd-clipboard-manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libclipboard_la-gsd-clipboard-manager.Tpo $(DEPDIR)/libclipboard_la-gsd-clipboard-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-clipboard-manager.c' object='libclipboard_la-gsd-clipboard-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) $(libclipboard_la_CPPFLAGS) $(CPPFLAGS) $(libclipboard_la_CFLAGS) $(CFLAGS) -c -o libclipboard_la-gsd-clipboard-manager.lo `test -f 'gsd-clipboard-manager.c' || echo '$(srcdir)/'`gsd-clipboard-manager.c + +libclipboard_la-xutils.lo: xutils.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libclipboard_la_CPPFLAGS) $(CPPFLAGS) $(libclipboard_la_CFLAGS) $(CFLAGS) -MT libclipboard_la-xutils.lo -MD -MP -MF $(DEPDIR)/libclipboard_la-xutils.Tpo -c -o libclipboard_la-xutils.lo `test -f 'xutils.c' || echo '$(srcdir)/'`xutils.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libclipboard_la-xutils.Tpo $(DEPDIR)/libclipboard_la-xutils.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='xutils.c' object='libclipboard_la-xutils.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) $(libclipboard_la_CPPFLAGS) $(CPPFLAGS) $(libclipboard_la_CFLAGS) $(CFLAGS) -c -o libclipboard_la-xutils.lo `test -f 'xutils.c' || echo '$(srcdir)/'`xutils.c + +libclipboard_la-list.lo: list.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libclipboard_la_CPPFLAGS) $(CPPFLAGS) $(libclipboard_la_CFLAGS) $(CFLAGS) -MT libclipboard_la-list.lo -MD -MP -MF $(DEPDIR)/libclipboard_la-list.Tpo -c -o libclipboard_la-list.lo `test -f 'list.c' || echo '$(srcdir)/'`list.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libclipboard_la-list.Tpo $(DEPDIR)/libclipboard_la-list.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='list.c' object='libclipboard_la-list.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) $(libclipboard_la_CPPFLAGS) $(CPPFLAGS) $(libclipboard_la_CFLAGS) $(CFLAGS) -c -o libclipboard_la-list.lo `test -f 'list.c' || echo '$(srcdir)/'`list.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +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 + +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) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -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." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ + 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-pluginDATA install-pluginLTLIBRARIES + +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: uninstall-pluginDATA uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-pluginLTLIBRARIES 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-pluginDATA \ + install-pluginLTLIBRARIES 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 \ + uninstall-pluginDATA uninstall-pluginLTLIBRARIES + + +@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/clipboard/clipboard.mate-settings-plugin.in b/plugins/clipboard/clipboard.mate-settings-plugin.in new file mode 100644 index 0000000..3a5536f --- /dev/null +++ b/plugins/clipboard/clipboard.mate-settings-plugin.in @@ -0,0 +1,8 @@ +[MATE Settings Plugin] +Module=clipboard +IAge=0 +_Name=Clipboard +_Description=Clipboard plugin +Authors=Matthias Clasen +Copyright=Copyright © 2007 Matthias Clasen +Website= diff --git a/plugins/clipboard/gsd-clipboard-manager.c b/plugins/clipboard/gsd-clipboard-manager.c new file mode 100644 index 0000000..fcbc839 --- /dev/null +++ b/plugins/clipboard/gsd-clipboard-manager.c @@ -0,0 +1,1069 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 Matthias Clasen + * Copyright (C) 2007 Anders Carlsson + * Copyright (C) 2007 Rodrigo Moya + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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 <sys/types.h> +#include <sys/wait.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> + +#include <locale.h> + +#include <glib.h> +#include <glib/gi18n.h> +#include <gdk/gdk.h> +#include <gdk/gdkx.h> +#include <gtk/gtk.h> +#include <X11/Xlib.h> +#include <X11/Xatom.h> + +#include "xutils.h" +#include "list.h" + +#include "mate-settings-profile.h" +#include "gsd-clipboard-manager.h" + +#define GSD_CLIPBOARD_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_CLIPBOARD_MANAGER, GsdClipboardManagerPrivate)) + +struct GsdClipboardManagerPrivate +{ + Display *display; + Window window; + Time timestamp; + + List *contents; + List *conversions; + + Window requestor; + Atom property; + Time time; +}; + +typedef struct +{ + unsigned char *data; + int length; + Atom target; + Atom type; + int format; + int refcount; +} TargetData; + +typedef struct +{ + Atom target; + TargetData *data; + Atom property; + Window requestor; + int offset; +} IncrConversion; + +static void gsd_clipboard_manager_class_init (GsdClipboardManagerClass *klass); +static void gsd_clipboard_manager_init (GsdClipboardManager *clipboard_manager); +static void gsd_clipboard_manager_finalize (GObject *object); + +static void clipboard_manager_watch_cb (GsdClipboardManager *manager, + Window window, + Bool is_start, + long mask, + void *cb_data); + +G_DEFINE_TYPE (GsdClipboardManager, gsd_clipboard_manager, G_TYPE_OBJECT) + +static gpointer manager_object = NULL; + +/* We need to use reference counting for the target data, since we may + * need to keep the data around after loosing the CLIPBOARD ownership + * to complete incremental transfers. + */ +static TargetData * +target_data_ref (TargetData *data) +{ + data->refcount++; + return data; +} + +static void +target_data_unref (TargetData *data) +{ + data->refcount--; + if (data->refcount == 0) { + free (data->data); + free (data); + } +} + +static void +conversion_free (IncrConversion *rdata) +{ + if (rdata->data) { + target_data_unref (rdata->data); + } + free (rdata); +} + +static void +send_selection_notify (GsdClipboardManager *manager, + Bool success) +{ + XSelectionEvent notify; + + notify.type = SelectionNotify; + notify.serial = 0; + notify.send_event = True; + notify.display = manager->priv->display; + notify.requestor = manager->priv->requestor; + notify.selection = XA_CLIPBOARD_MANAGER; + notify.target = XA_SAVE_TARGETS; + notify.property = success ? manager->priv->property : None; + notify.time = manager->priv->time; + + gdk_error_trap_push (); + + XSendEvent (manager->priv->display, + manager->priv->requestor, + False, + NoEventMask, + (XEvent *)¬ify); + XSync (manager->priv->display, False); + + gdk_error_trap_pop (); +} + +static void +finish_selection_request (GsdClipboardManager *manager, + XEvent *xev, + Bool success) +{ + XSelectionEvent notify; + + notify.type = SelectionNotify; + notify.serial = 0; + notify.send_event = True; + notify.display = xev->xselectionrequest.display; + notify.requestor = xev->xselectionrequest.requestor; + notify.selection = xev->xselectionrequest.selection; + notify.target = xev->xselectionrequest.target; + notify.property = success ? xev->xselectionrequest.property : None; + notify.time = xev->xselectionrequest.time; + + gdk_error_trap_push (); + + XSendEvent (xev->xselectionrequest.display, + xev->xselectionrequest.requestor, + False, NoEventMask, (XEvent *) ¬ify); + XSync (manager->priv->display, False); + + gdk_error_trap_pop (); +} + +static int +clipboard_bytes_per_item (int format) +{ + switch (format) { + case 8: return sizeof (char); + case 16: return sizeof (short); + case 32: return sizeof (long); + default: ; + } + + return 0; +} + +static void +save_targets (GsdClipboardManager *manager, + Atom *save_targets, + int nitems) +{ + int nout, i; + Atom *multiple; + TargetData *tdata; + + multiple = (Atom *) malloc (2 * nitems * sizeof (Atom)); + + nout = 0; + for (i = 0; i < nitems; i++) { + if (save_targets[i] != XA_TARGETS && + save_targets[i] != XA_MULTIPLE && + save_targets[i] != XA_DELETE && + save_targets[i] != XA_INSERT_PROPERTY && + save_targets[i] != XA_INSERT_SELECTION && + save_targets[i] != XA_PIXMAP) { + tdata = (TargetData *) malloc (sizeof (TargetData)); + tdata->data = NULL; + tdata->length = 0; + tdata->target = save_targets[i]; + tdata->type = None; + tdata->format = 0; + tdata->refcount = 1; + manager->priv->contents = list_prepend (manager->priv->contents, tdata); + + multiple[nout++] = save_targets[i]; + multiple[nout++] = save_targets[i]; + } + } + + XFree (save_targets); + + XChangeProperty (manager->priv->display, manager->priv->window, + XA_MULTIPLE, XA_ATOM_PAIR, + 32, PropModeReplace, (const unsigned char *) multiple, nout); + free (multiple); + + XConvertSelection (manager->priv->display, XA_CLIPBOARD, + XA_MULTIPLE, XA_MULTIPLE, + manager->priv->window, manager->priv->time); +} + +static int +find_content_target (TargetData *tdata, + Atom target) +{ + return tdata->target == target; +} + +static int +find_content_type (TargetData *tdata, + Atom type) +{ + return tdata->type == type; +} + +static int +find_conversion_requestor (IncrConversion *rdata, + XEvent *xev) +{ + return (rdata->requestor == xev->xproperty.window && + rdata->property == xev->xproperty.atom); +} + +static void +get_property (TargetData *tdata, + GsdClipboardManager *manager) +{ + Atom type; + int format; + unsigned long length; + unsigned long remaining; + unsigned char *data; + + XGetWindowProperty (manager->priv->display, + manager->priv->window, + tdata->target, + 0, + 0x1FFFFFFF, + True, + AnyPropertyType, + &type, + &format, + &length, + &remaining, + &data); + + if (type == None) { + manager->priv->contents = list_remove (manager->priv->contents, tdata); + free (tdata); + } else if (type == XA_INCR) { + tdata->type = type; + tdata->length = 0; + XFree (data); + } else { + tdata->type = type; + tdata->data = data; + tdata->length = length * clipboard_bytes_per_item (format); + tdata->format = format; + } +} + +static Bool +receive_incrementally (GsdClipboardManager *manager, + XEvent *xev) +{ + List *list; + TargetData *tdata; + Atom type; + int format; + unsigned long length, nitems, remaining; + unsigned char *data; + + if (xev->xproperty.window != manager->priv->window) + return False; + + list = list_find (manager->priv->contents, + (ListFindFunc) find_content_target, (void *) xev->xproperty.atom); + + if (!list) + return False; + + tdata = (TargetData *) list->data; + + if (tdata->type != XA_INCR) + return False; + + XGetWindowProperty (xev->xproperty.display, + xev->xproperty.window, + xev->xproperty.atom, + 0, 0x1FFFFFFF, True, AnyPropertyType, + &type, &format, &nitems, &remaining, &data); + + length = nitems * clipboard_bytes_per_item (format); + if (length == 0) { + tdata->type = type; + tdata->format = format; + + if (!list_find (manager->priv->contents, + (ListFindFunc) find_content_type, (void *)XA_INCR)) { + /* all incremental transfers done */ + send_selection_notify (manager, True); + manager->priv->requestor = None; + } + + XFree (data); + } else { + if (!tdata->data) { + tdata->data = data; + tdata->length = length; + } else { + tdata->data = realloc (tdata->data, tdata->length + length + 1); + memcpy (tdata->data + tdata->length, data, length + 1); + tdata->length += length; + XFree (data); + } + } + + return True; +} + +static Bool +send_incrementally (GsdClipboardManager *manager, + XEvent *xev) +{ + List *list; + IncrConversion *rdata; + unsigned long length; + unsigned long items; + unsigned char *data; + + list = list_find (manager->priv->conversions, + (ListFindFunc) find_conversion_requestor, xev); + if (list == NULL) + return False; + + rdata = (IncrConversion *) list->data; + + data = rdata->data->data + rdata->offset; + length = rdata->data->length - rdata->offset; + if (length > SELECTION_MAX_SIZE) + length = SELECTION_MAX_SIZE; + + rdata->offset += length; + + items = length / clipboard_bytes_per_item (rdata->data->format); + XChangeProperty (manager->priv->display, rdata->requestor, + rdata->property, rdata->data->type, + rdata->data->format, PropModeAppend, + data, items); + + if (length == 0) { + manager->priv->conversions = list_remove (manager->priv->conversions, rdata); + conversion_free (rdata); + } + + return True; +} + +static void +convert_clipboard_manager (GsdClipboardManager *manager, + XEvent *xev) +{ + Atom type = None; + int format; + unsigned long nitems; + unsigned long remaining; + Atom *targets = NULL; + + if (xev->xselectionrequest.target == XA_SAVE_TARGETS) { + if (manager->priv->requestor != None || manager->priv->contents != NULL) { + /* We're in the middle of a conversion request, or own + * the CLIPBOARD already + */ + finish_selection_request (manager, xev, False); + } else { + gdk_error_trap_push (); + + clipboard_manager_watch_cb (manager, + xev->xselectionrequest.requestor, + True, + StructureNotifyMask, + NULL); + XSelectInput (manager->priv->display, + xev->xselectionrequest.requestor, + StructureNotifyMask); + XSync (manager->priv->display, False); + + if (gdk_error_trap_pop () != Success) + return; + + gdk_error_trap_push (); + + if (xev->xselectionrequest.property != None) { + XGetWindowProperty (manager->priv->display, + xev->xselectionrequest.requestor, + xev->xselectionrequest.property, + 0, 0x1FFFFFFF, False, XA_ATOM, + &type, &format, &nitems, &remaining, + (unsigned char **) &targets); + + if (gdk_error_trap_pop () != Success) { + if (targets) + XFree (targets); + + return; + } + } + + manager->priv->requestor = xev->xselectionrequest.requestor; + manager->priv->property = xev->xselectionrequest.property; + manager->priv->time = xev->xselectionrequest.time; + + if (type == None) + XConvertSelection (manager->priv->display, XA_CLIPBOARD, + XA_TARGETS, XA_TARGETS, + manager->priv->window, manager->priv->time); + else + save_targets (manager, targets, nitems); + } + } else if (xev->xselectionrequest.target == XA_TIMESTAMP) { + XChangeProperty (manager->priv->display, + xev->xselectionrequest.requestor, + xev->xselectionrequest.property, + XA_INTEGER, 32, PropModeReplace, + (unsigned char *) &manager->priv->timestamp, 1); + + finish_selection_request (manager, xev, True); + } else if (xev->xselectionrequest.target == XA_TARGETS) { + int n_targets = 0; + Atom targets[3]; + + targets[n_targets++] = XA_TARGETS; + targets[n_targets++] = XA_TIMESTAMP; + targets[n_targets++] = XA_SAVE_TARGETS; + + XChangeProperty (manager->priv->display, + xev->xselectionrequest.requestor, + xev->xselectionrequest.property, + XA_ATOM, 32, PropModeReplace, + (unsigned char *) targets, n_targets); + + finish_selection_request (manager, xev, True); + } else + finish_selection_request (manager, xev, False); +} + +static void +convert_clipboard_target (IncrConversion *rdata, + GsdClipboardManager *manager) +{ + TargetData *tdata; + Atom *targets; + int n_targets; + List *list; + unsigned long items; + XWindowAttributes atts; + + if (rdata->target == XA_TARGETS) { + n_targets = list_length (manager->priv->contents) + 2; + targets = (Atom *) malloc (n_targets * sizeof (Atom)); + + n_targets = 0; + + targets[n_targets++] = XA_TARGETS; + targets[n_targets++] = XA_MULTIPLE; + + for (list = manager->priv->contents; list; list = list->next) { + tdata = (TargetData *) list->data; + targets[n_targets++] = tdata->target; + } + + XChangeProperty (manager->priv->display, rdata->requestor, + rdata->property, + XA_ATOM, 32, PropModeReplace, + (unsigned char *) targets, n_targets); + free (targets); + } else { + /* Convert from stored CLIPBOARD data */ + list = list_find (manager->priv->contents, + (ListFindFunc) find_content_target, (void *) rdata->target); + + /* We got a target that we don't support */ + if (!list) + return; + + tdata = (TargetData *)list->data; + if (tdata->type == XA_INCR) { + /* we haven't completely received this target yet */ + rdata->property = None; + return; + } + + rdata->data = target_data_ref (tdata); + items = tdata->length / clipboard_bytes_per_item (tdata->format); + if (tdata->length <= SELECTION_MAX_SIZE) + XChangeProperty (manager->priv->display, rdata->requestor, + rdata->property, + tdata->type, tdata->format, PropModeReplace, + tdata->data, items); + else { + /* start incremental transfer */ + rdata->offset = 0; + + gdk_error_trap_push (); + + XGetWindowAttributes (manager->priv->display, rdata->requestor, &atts); + XSelectInput (manager->priv->display, rdata->requestor, + atts.your_event_mask | PropertyChangeMask); + + XChangeProperty (manager->priv->display, rdata->requestor, + rdata->property, + XA_INCR, 32, PropModeReplace, + (unsigned char *) &items, 1); + + XSync (manager->priv->display, False); + + gdk_error_trap_pop (); + } + } +} + +static void +collect_incremental (IncrConversion *rdata, + GsdClipboardManager *manager) +{ + if (rdata->offset >= 0) + manager->priv->conversions = list_prepend (manager->priv->conversions, rdata); + else { + if (rdata->data) { + target_data_unref (rdata->data); + rdata->data = NULL; + } + free (rdata); + } +} + +static void +convert_clipboard (GsdClipboardManager *manager, + XEvent *xev) +{ + List *list; + List *conversions; + IncrConversion *rdata; + Atom type; + int i; + int format; + unsigned long nitems; + unsigned long remaining; + Atom *multiple; + + conversions = NULL; + type = None; + + if (xev->xselectionrequest.target == XA_MULTIPLE) { + XGetWindowProperty (xev->xselectionrequest.display, + xev->xselectionrequest.requestor, + xev->xselectionrequest.property, + 0, 0x1FFFFFFF, False, XA_ATOM_PAIR, + &type, &format, &nitems, &remaining, + (unsigned char **) &multiple); + + if (type != XA_ATOM_PAIR || nitems == 0) { + if (multiple) + free (multiple); + return; + } + + for (i = 0; i < nitems; i += 2) { + rdata = (IncrConversion *) malloc (sizeof (IncrConversion)); + rdata->requestor = xev->xselectionrequest.requestor; + rdata->target = multiple[i]; + rdata->property = multiple[i+1]; + rdata->data = NULL; + rdata->offset = -1; + conversions = list_prepend (conversions, rdata); + } + } else { + multiple = NULL; + + rdata = (IncrConversion *) malloc (sizeof (IncrConversion)); + rdata->requestor = xev->xselectionrequest.requestor; + rdata->target = xev->xselectionrequest.target; + rdata->property = xev->xselectionrequest.property; + rdata->data = NULL; + rdata->offset = -1; + conversions = list_prepend (conversions, rdata); + } + + list_foreach (conversions, (Callback) convert_clipboard_target, manager); + + if (conversions->next == NULL && + ((IncrConversion *) conversions->data)->property == None) { + finish_selection_request (manager, xev, False); + } else { + if (multiple) { + i = 0; + for (list = conversions; list; list = list->next) { + rdata = (IncrConversion *)list->data; + multiple[i++] = rdata->target; + multiple[i++] = rdata->property; + } + XChangeProperty (xev->xselectionrequest.display, + xev->xselectionrequest.requestor, + xev->xselectionrequest.property, + XA_ATOM_PAIR, 32, PropModeReplace, + (unsigned char *) multiple, nitems); + } + finish_selection_request (manager, xev, True); + } + + list_foreach (conversions, (Callback) collect_incremental, manager); + list_free (conversions); + + if (multiple) + free (multiple); +} + +static Bool +clipboard_manager_process_event (GsdClipboardManager *manager, + XEvent *xev) +{ + Atom type; + int format; + unsigned long nitems; + unsigned long remaining; + Atom *targets; + + targets = NULL; + + switch (xev->xany.type) { + case DestroyNotify: + if (xev->xdestroywindow.window == manager->priv->requestor) { + list_foreach (manager->priv->contents, (Callback)target_data_unref, NULL); + list_free (manager->priv->contents); + manager->priv->contents = NULL; + + clipboard_manager_watch_cb (manager, + manager->priv->requestor, + False, + 0, + NULL); + manager->priv->requestor = None; + } + break; + case PropertyNotify: + if (xev->xproperty.state == PropertyNewValue) { + return receive_incrementally (manager, xev); + } else { + return send_incrementally (manager, xev); + } + + case SelectionClear: + if (xev->xany.window != manager->priv->window) + return False; + + if (xev->xselectionclear.selection == XA_CLIPBOARD_MANAGER) { + /* We lost the manager selection */ + if (manager->priv->contents) { + list_foreach (manager->priv->contents, (Callback)target_data_unref, NULL); + list_free (manager->priv->contents); + manager->priv->contents = NULL; + + XSetSelectionOwner (manager->priv->display, + XA_CLIPBOARD, + None, manager->priv->time); + } + + return True; + } + if (xev->xselectionclear.selection == XA_CLIPBOARD) { + /* We lost the clipboard selection */ + list_foreach (manager->priv->contents, (Callback)target_data_unref, NULL); + list_free (manager->priv->contents); + manager->priv->contents = NULL; + clipboard_manager_watch_cb (manager, + manager->priv->requestor, + False, + 0, + NULL); + manager->priv->requestor = None; + + return True; + } + break; + + case SelectionNotify: + if (xev->xany.window != manager->priv->window) + return False; + + if (xev->xselection.selection == XA_CLIPBOARD) { + /* a CLIPBOARD conversion is done */ + if (xev->xselection.property == XA_TARGETS) { + XGetWindowProperty (xev->xselection.display, + xev->xselection.requestor, + xev->xselection.property, + 0, 0x1FFFFFFF, True, XA_ATOM, + &type, &format, &nitems, &remaining, + (unsigned char **) &targets); + + save_targets (manager, targets, nitems); + } else if (xev->xselection.property == XA_MULTIPLE) { + List *tmp; + + tmp = list_copy (manager->priv->contents); + list_foreach (tmp, (Callback) get_property, manager); + list_free (tmp); + + manager->priv->time = xev->xselection.time; + XSetSelectionOwner (manager->priv->display, XA_CLIPBOARD, + manager->priv->window, manager->priv->time); + + if (manager->priv->property != None) + XChangeProperty (manager->priv->display, + manager->priv->requestor, + manager->priv->property, + XA_ATOM, 32, PropModeReplace, + (unsigned char *)&XA_NULL, 1); + + if (!list_find (manager->priv->contents, + (ListFindFunc)find_content_type, (void *)XA_INCR)) { + /* all transfers done */ + send_selection_notify (manager, True); + clipboard_manager_watch_cb (manager, + manager->priv->requestor, + False, + 0, + NULL); + manager->priv->requestor = None; + } + } + else if (xev->xselection.property == None) { + send_selection_notify (manager, False); + clipboard_manager_watch_cb (manager, + manager->priv->requestor, + False, + 0, + NULL); + manager->priv->requestor = None; + } + + return True; + } + break; + + case SelectionRequest: + if (xev->xany.window != manager->priv->window) { + return False; + } + + if (xev->xselectionrequest.selection == XA_CLIPBOARD_MANAGER) { + convert_clipboard_manager (manager, xev); + return True; + } else if (xev->xselectionrequest.selection == XA_CLIPBOARD) { + convert_clipboard (manager, xev); + return True; + } + break; + + default: ; + } + + return False; +} + +static GdkFilterReturn +clipboard_manager_event_filter (GdkXEvent *xevent, + GdkEvent *event, + GsdClipboardManager *manager) +{ + if (clipboard_manager_process_event (manager, (XEvent *)xevent)) { + return GDK_FILTER_REMOVE; + } else { + return GDK_FILTER_CONTINUE; + } +} + +static void +clipboard_manager_watch_cb (GsdClipboardManager *manager, + Window window, + Bool is_start, + long mask, + void *cb_data) +{ + GdkWindow *gdkwin; + GdkDisplay *display; + + display = gdk_display_get_default (); + gdkwin = gdk_window_lookup_for_display (display, window); + + if (is_start) { + if (gdkwin == NULL) { + gdkwin = gdk_window_foreign_new_for_display (display, window); + } else { + g_object_ref (gdkwin); + } + + gdk_window_add_filter (gdkwin, + (GdkFilterFunc)clipboard_manager_event_filter, + manager); + } else { + if (gdkwin == NULL) { + return; + } + gdk_window_remove_filter (gdkwin, + (GdkFilterFunc)clipboard_manager_event_filter, + manager); + g_object_unref (gdkwin); + } +} + +static gboolean +start_clipboard_idle_cb (GsdClipboardManager *manager) +{ + XClientMessageEvent xev; + + + mate_settings_profile_start (NULL); + + init_atoms (manager->priv->display); + + /* check if there is a clipboard manager running */ + if (XGetSelectionOwner (manager->priv->display, XA_CLIPBOARD_MANAGER)) { + g_warning ("Clipboard manager is already running."); + return FALSE; + } + + manager->priv->contents = NULL; + manager->priv->conversions = NULL; + manager->priv->requestor = None; + + manager->priv->window = XCreateSimpleWindow (manager->priv->display, + DefaultRootWindow (manager->priv->display), + 0, 0, 10, 10, 0, + WhitePixel (manager->priv->display, + DefaultScreen (manager->priv->display)), + WhitePixel (manager->priv->display, + DefaultScreen (manager->priv->display))); + clipboard_manager_watch_cb (manager, + manager->priv->window, + True, + PropertyChangeMask, + NULL); + XSelectInput (manager->priv->display, + manager->priv->window, + PropertyChangeMask); + manager->priv->timestamp = get_server_time (manager->priv->display, manager->priv->window); + + XSetSelectionOwner (manager->priv->display, + XA_CLIPBOARD_MANAGER, + manager->priv->window, + manager->priv->timestamp); + + /* Check to see if we managed to claim the selection. If not, + * we treat it as if we got it then immediately lost it + */ + if (XGetSelectionOwner (manager->priv->display, XA_CLIPBOARD_MANAGER) == manager->priv->window) { + xev.type = ClientMessage; + xev.window = DefaultRootWindow (manager->priv->display); + xev.message_type = XA_MANAGER; + xev.format = 32; + xev.data.l[0] = manager->priv->timestamp; + xev.data.l[1] = XA_CLIPBOARD_MANAGER; + xev.data.l[2] = manager->priv->window; + xev.data.l[3] = 0; /* manager specific data */ + xev.data.l[4] = 0; /* manager specific data */ + + XSendEvent (manager->priv->display, + DefaultRootWindow (manager->priv->display), + False, + StructureNotifyMask, + (XEvent *)&xev); + } else { + clipboard_manager_watch_cb (manager, + manager->priv->window, + False, + 0, + NULL); + /* FIXME: manager->priv->terminate (manager->priv->cb_data); */ + } + + mate_settings_profile_end (NULL); + + return FALSE; +} + +gboolean +gsd_clipboard_manager_start (GsdClipboardManager *manager, + GError **error) +{ + mate_settings_profile_start (NULL); + + g_idle_add ((GSourceFunc) start_clipboard_idle_cb, manager); + + mate_settings_profile_end (NULL); + + return TRUE; +} + +void +gsd_clipboard_manager_stop (GsdClipboardManager *manager) +{ + g_debug ("Stopping clipboard manager"); + + clipboard_manager_watch_cb (manager, + manager->priv->window, + FALSE, + 0, + NULL); + XDestroyWindow (manager->priv->display, manager->priv->window); + + list_foreach (manager->priv->conversions, (Callback) conversion_free, NULL); + list_free (manager->priv->conversions); + + list_foreach (manager->priv->contents, (Callback) target_data_unref, NULL); + list_free (manager->priv->contents); +} + +static void +gsd_clipboard_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GsdClipboardManager *self; + + self = GSD_CLIPBOARD_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gsd_clipboard_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GsdClipboardManager *self; + + self = GSD_CLIPBOARD_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +gsd_clipboard_manager_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GsdClipboardManager *clipboard_manager; + GsdClipboardManagerClass *klass; + + klass = GSD_CLIPBOARD_MANAGER_CLASS (g_type_class_peek (GSD_TYPE_CLIPBOARD_MANAGER)); + + clipboard_manager = GSD_CLIPBOARD_MANAGER (G_OBJECT_CLASS (gsd_clipboard_manager_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + + return G_OBJECT (clipboard_manager); +} + +static void +gsd_clipboard_manager_dispose (GObject *object) +{ + GsdClipboardManager *clipboard_manager; + + clipboard_manager = GSD_CLIPBOARD_MANAGER (object); + + G_OBJECT_CLASS (gsd_clipboard_manager_parent_class)->dispose (object); +} + +static void +gsd_clipboard_manager_class_init (GsdClipboardManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gsd_clipboard_manager_get_property; + object_class->set_property = gsd_clipboard_manager_set_property; + object_class->constructor = gsd_clipboard_manager_constructor; + object_class->dispose = gsd_clipboard_manager_dispose; + object_class->finalize = gsd_clipboard_manager_finalize; + + g_type_class_add_private (klass, sizeof (GsdClipboardManagerPrivate)); +} + +static void +gsd_clipboard_manager_init (GsdClipboardManager *manager) +{ + manager->priv = GSD_CLIPBOARD_MANAGER_GET_PRIVATE (manager); + + manager->priv->display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + +} + +static void +gsd_clipboard_manager_finalize (GObject *object) +{ + GsdClipboardManager *clipboard_manager; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_CLIPBOARD_MANAGER (object)); + + clipboard_manager = GSD_CLIPBOARD_MANAGER (object); + + g_return_if_fail (clipboard_manager->priv != NULL); + + G_OBJECT_CLASS (gsd_clipboard_manager_parent_class)->finalize (object); +} + +GsdClipboardManager * +gsd_clipboard_manager_new (void) +{ + if (manager_object != NULL) { + g_object_ref (manager_object); + } else { + manager_object = g_object_new (GSD_TYPE_CLIPBOARD_MANAGER, NULL); + g_object_add_weak_pointer (manager_object, + (gpointer *) &manager_object); + } + + return GSD_CLIPBOARD_MANAGER (manager_object); +} diff --git a/plugins/clipboard/gsd-clipboard-manager.h b/plugins/clipboard/gsd-clipboard-manager.h new file mode 100644 index 0000000..0338799 --- /dev/null +++ b/plugins/clipboard/gsd-clipboard-manager.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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_CLIPBOARD_MANAGER_H +#define __GSD_CLIPBOARD_MANAGER_H + +#include <glib-object.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_CLIPBOARD_MANAGER (gsd_clipboard_manager_get_type ()) +#define GSD_CLIPBOARD_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_CLIPBOARD_MANAGER, GsdClipboardManager)) +#define GSD_CLIPBOARD_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_CLIPBOARD_MANAGER, GsdClipboardManagerClass)) +#define GSD_IS_CLIPBOARD_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_CLIPBOARD_MANAGER)) +#define GSD_IS_CLIPBOARD_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_CLIPBOARD_MANAGER)) +#define GSD_CLIPBOARD_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_CLIPBOARD_MANAGER, GsdClipboardManagerClass)) + +typedef struct GsdClipboardManagerPrivate GsdClipboardManagerPrivate; + +typedef struct +{ + GObject parent; + GsdClipboardManagerPrivate *priv; +} GsdClipboardManager; + +typedef struct +{ + GObjectClass parent_class; +} GsdClipboardManagerClass; + +GType gsd_clipboard_manager_get_type (void); + +GsdClipboardManager * gsd_clipboard_manager_new (void); +gboolean gsd_clipboard_manager_start (GsdClipboardManager *manager, + GError **error); +void gsd_clipboard_manager_stop (GsdClipboardManager *manager); + +#ifdef __cplusplus +} +#endif + +#endif /* __GSD_CLIPBOARD_MANAGER_H */ diff --git a/plugins/clipboard/gsd-clipboard-plugin.c b/plugins/clipboard/gsd-clipboard-plugin.c new file mode 100644 index 0000000..f384b52 --- /dev/null +++ b/plugins/clipboard/gsd-clipboard-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 <[email protected]> + * + * 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 <glib/gi18n-lib.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" +#include "gsd-clipboard-plugin.h" +#include "gsd-clipboard-manager.h" + +struct GsdClipboardPluginPrivate { + GsdClipboardManager *manager; +}; + +#define GSD_CLIPBOARD_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSD_TYPE_CLIPBOARD_PLUGIN, GsdClipboardPluginPrivate)) + +MATE_SETTINGS_PLUGIN_REGISTER (GsdClipboardPlugin, gsd_clipboard_plugin) + +static void +gsd_clipboard_plugin_init (GsdClipboardPlugin *plugin) +{ + plugin->priv = GSD_CLIPBOARD_PLUGIN_GET_PRIVATE (plugin); + + g_debug ("GsdClipboardPlugin initializing"); + + plugin->priv->manager = gsd_clipboard_manager_new (); +} + +static void +gsd_clipboard_plugin_finalize (GObject *object) +{ + GsdClipboardPlugin *plugin; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_CLIPBOARD_PLUGIN (object)); + + g_debug ("GsdClipboardPlugin finalizing"); + + plugin = GSD_CLIPBOARD_PLUGIN (object); + + g_return_if_fail (plugin->priv != NULL); + + if (plugin->priv->manager != NULL) { + g_object_unref (plugin->priv->manager); + } + + G_OBJECT_CLASS (gsd_clipboard_plugin_parent_class)->finalize (object); +} + +static void +impl_activate (MateSettingsPlugin *plugin) +{ + gboolean res; + GError *error; + + g_debug ("Activating clipboard plugin"); + + error = NULL; + res = gsd_clipboard_manager_start (GSD_CLIPBOARD_PLUGIN (plugin)->priv->manager, &error); + if (! res) { + g_warning ("Unable to start clipboard manager: %s", error->message); + g_error_free (error); + } +} + +static void +impl_deactivate (MateSettingsPlugin *plugin) +{ + g_debug ("Deactivating clipboard plugin"); + gsd_clipboard_manager_stop (GSD_CLIPBOARD_PLUGIN (plugin)->priv->manager); +} + +static void +gsd_clipboard_plugin_class_init (GsdClipboardPluginClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MateSettingsPluginClass *plugin_class = MATE_SETTINGS_PLUGIN_CLASS (klass); + + object_class->finalize = gsd_clipboard_plugin_finalize; + + plugin_class->activate = impl_activate; + plugin_class->deactivate = impl_deactivate; + + g_type_class_add_private (klass, sizeof (GsdClipboardPluginPrivate)); +} diff --git a/plugins/clipboard/gsd-clipboard-plugin.h b/plugins/clipboard/gsd-clipboard-plugin.h new file mode 100644 index 0000000..4148c09 --- /dev/null +++ b/plugins/clipboard/gsd-clipboard-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 <[email protected]> + * + * 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_CLIPBOARD_PLUGIN_H__ +#define __GSD_CLIPBOARD_PLUGIN_H__ + +#include <glib.h> +#include <glib-object.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_CLIPBOARD_PLUGIN (gsd_clipboard_plugin_get_type ()) +#define GSD_CLIPBOARD_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_CLIPBOARD_PLUGIN, GsdClipboardPlugin)) +#define GSD_CLIPBOARD_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_CLIPBOARD_PLUGIN, GsdClipboardPluginClass)) +#define GSD_IS_CLIPBOARD_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_CLIPBOARD_PLUGIN)) +#define GSD_IS_CLIPBOARD_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_CLIPBOARD_PLUGIN)) +#define GSD_CLIPBOARD_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_CLIPBOARD_PLUGIN, GsdClipboardPluginClass)) + +typedef struct GsdClipboardPluginPrivate GsdClipboardPluginPrivate; + +typedef struct +{ + MateSettingsPlugin parent; + GsdClipboardPluginPrivate *priv; +} GsdClipboardPlugin; + +typedef struct +{ + MateSettingsPluginClass parent_class; +} GsdClipboardPluginClass; + +GType gsd_clipboard_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_CLIPBOARD_PLUGIN_H__ */ diff --git a/plugins/clipboard/list.c b/plugins/clipboard/list.c new file mode 100644 index 0000000..477eead --- /dev/null +++ b/plugins/clipboard/list.c @@ -0,0 +1,150 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Matthias Clasen, Red Hat, Inc. + */ + +#include <stdlib.h> +#include <list.h> + + +void +list_foreach (List *list, + Callback func, + void *user_data) +{ + while (list) + { + func (list->data, user_data); + + list = list->next; + } +} + +List * +list_prepend (List *list, + void *data) +{ + List *link; + + link = (List *) malloc (sizeof (List)); + link->next = list; + link->data = data; + + return link; +} + +void +list_free (List *list) +{ + while (list) + { + List *next = list->next; + + free (list); + + list = next; + } +} + +List * +list_find (List *list, + ListFindFunc func, + void *user_data) +{ + List *tmp; + + for (tmp = list; tmp; tmp = tmp->next) + { + if ((*func) (tmp->data, user_data)) + break; + } + + return tmp; +} + +List * +list_remove (List *list, + void *data) +{ + List *tmp, *prev; + + prev = NULL; + for (tmp = list; tmp; tmp = tmp->next) + { + if (tmp->data == data) + { + if (prev) + prev->next = tmp->next; + else + list = tmp->next; + + free (tmp); + break; + } + + prev = tmp; + } + + return list; +} + +int +list_length (List *list) +{ + List *tmp; + int length; + + length = 0; + for (tmp = list; tmp; tmp = tmp->next) + length++; + + return length; +} + +List * +list_copy (List *list) +{ + List *new_list = NULL; + + if (list) + { + List *last; + + new_list = (List *) malloc (sizeof (List)); + new_list->data = list->data; + new_list->next = NULL; + + last = new_list; + list = list->next; + + while (list) + { + last->next = (List *) malloc (sizeof (List)); + last = last->next; + last->data = list->data; + list = list->next; + } + + last->next = NULL; + } + + return new_list; +} diff --git a/plugins/clipboard/list.h b/plugins/clipboard/list.h new file mode 100644 index 0000000..158b779 --- /dev/null +++ b/plugins/clipboard/list.h @@ -0,0 +1,57 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Matthias Clasen, Red Hat, Inc. + */ +#ifndef LIST_H +#define LIST_H + + +typedef struct _List List; +typedef void (*Callback) (void *data, + void *user_data); + + +struct _List +{ + void *data; + + List *next; +}; + +typedef int (*ListFindFunc) (void *data, + void *user_data); + +void list_foreach (List *list, + Callback func, + void *user_data); +List *list_prepend (List *list, + void *data); +void list_free (List *list); +List *list_find (List *list, + ListFindFunc func, + void *user_data); +List *list_remove (List *list, + void *data); +int list_length (List *list); + +List *list_copy (List *list); + +#endif /* LIST_H */ diff --git a/plugins/clipboard/xutils.c b/plugins/clipboard/xutils.c new file mode 100644 index 0000000..4e48b98 --- /dev/null +++ b/plugins/clipboard/xutils.c @@ -0,0 +1,117 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Matthias Clasen, Red Hat, Inc. + */ + +#include <stdlib.h> + +#include "xutils.h" + +Atom XA_ATOM_PAIR; +Atom XA_CLIPBOARD_MANAGER; +Atom XA_CLIPBOARD; +Atom XA_DELETE; +Atom XA_INCR; +Atom XA_INSERT_PROPERTY; +Atom XA_INSERT_SELECTION; +Atom XA_MANAGER; +Atom XA_MULTIPLE; +Atom XA_NULL; +Atom XA_SAVE_TARGETS; +Atom XA_TARGETS; +Atom XA_TIMESTAMP; + +unsigned long SELECTION_MAX_SIZE = 0; + + +void +init_atoms (Display *display) +{ + unsigned long max_request_size; + + if (SELECTION_MAX_SIZE > 0) + return; + + XA_ATOM_PAIR = XInternAtom (display, "ATOM_PAIR", False); + XA_CLIPBOARD_MANAGER = XInternAtom (display, "CLIPBOARD_MANAGER", False); + XA_CLIPBOARD = XInternAtom (display, "CLIPBOARD", False); + XA_DELETE = XInternAtom (display, "DELETE", False); + XA_INCR = XInternAtom (display, "INCR", False); + XA_INSERT_PROPERTY = XInternAtom (display, "INSERT_PROPERTY", False); + XA_INSERT_SELECTION = XInternAtom (display, "INSERT_SELECTION", False); + XA_MANAGER = XInternAtom (display, "MANAGER", False); + XA_MULTIPLE = XInternAtom (display, "MULTIPLE", False); + XA_NULL = XInternAtom (display, "NULL", False); + XA_SAVE_TARGETS = XInternAtom (display, "SAVE_TARGETS", False); + XA_TARGETS = XInternAtom (display, "TARGETS", False); + XA_TIMESTAMP = XInternAtom (display, "TIMESTAMP", False); + + max_request_size = XExtendedMaxRequestSize (display); + if (max_request_size == 0) + max_request_size = XMaxRequestSize (display); + + SELECTION_MAX_SIZE = max_request_size - 100; + if (SELECTION_MAX_SIZE > 262144) + SELECTION_MAX_SIZE = 262144; +} + +typedef struct +{ + Window window; + Atom timestamp_prop_atom; +} TimeStampInfo; + +static Bool +timestamp_predicate (Display *display, + XEvent *xevent, + XPointer arg) +{ + TimeStampInfo *info = (TimeStampInfo *)arg; + + if (xevent->type == PropertyNotify && + xevent->xproperty.window == info->window && + xevent->xproperty.atom == info->timestamp_prop_atom) + return True; + + return False; +} + +Time +get_server_time (Display *display, + Window window) +{ + unsigned char c = 'a'; + XEvent xevent; + TimeStampInfo info; + + info.timestamp_prop_atom = XInternAtom (display, "_TIMESTAMP_PROP", False); + info.window = window; + + XChangeProperty (display, window, + info.timestamp_prop_atom, info.timestamp_prop_atom, + 8, PropModeReplace, &c, 1); + + XIfEvent (display, &xevent, + timestamp_predicate, (XPointer)&info); + + return xevent.xproperty.time; +} + diff --git a/plugins/clipboard/xutils.h b/plugins/clipboard/xutils.h new file mode 100644 index 0000000..143fe44 --- /dev/null +++ b/plugins/clipboard/xutils.h @@ -0,0 +1,50 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Matthias Clasen, Red Hat, Inc. + */ +#ifndef X_UTILS_H +#define X_UTILS_H + +#include <X11/Xlib.h> + + +extern Atom XA_ATOM_PAIR; +extern Atom XA_CLIPBOARD_MANAGER; +extern Atom XA_CLIPBOARD; +extern Atom XA_DELETE; +extern Atom XA_INCR; +extern Atom XA_INSERT_PROPERTY; +extern Atom XA_INSERT_SELECTION; +extern Atom XA_MANAGER; +extern Atom XA_MULTIPLE; +extern Atom XA_NULL; +extern Atom XA_SAVE_TARGETS; +extern Atom XA_TARGETS; +extern Atom XA_TIMESTAMP; + +extern unsigned long SELECTION_MAX_SIZE; + +void init_atoms (Display *display); + +Time get_server_time (Display *display, + Window window); + +#endif /* X_UTILS_H */ diff --git a/plugins/common/Makefile.am b/plugins/common/Makefile.am new file mode 100644 index 0000000..447d02d --- /dev/null +++ b/plugins/common/Makefile.am @@ -0,0 +1,23 @@ + +noinst_LTLIBRARIES = libcommon.la + +libcommon_la_SOURCES = \ + eggaccelerators.c \ + eggaccelerators.h \ + gsd-keygrab.c \ + gsd-keygrab.h \ + gsd-osd-window.c \ + gsd-osd-window.h + +libcommon_la_CPPFLAGS = \ + $(AM_CPPFLAGS) + +libcommon_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libcommon_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) $(X11_LIBS) + +libcommon_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) diff --git a/plugins/common/Makefile.in b/plugins/common/Makefile.in new file mode 100644 index 0000000..840011d --- /dev/null +++ b/plugins/common/Makefile.in @@ -0,0 +1,584 @@ +# 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/common +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 = +libcommon_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libcommon_la_OBJECTS = libcommon_la-eggaccelerators.lo \ + libcommon_la-gsd-keygrab.lo libcommon_la-gsd-osd-window.lo +libcommon_la_OBJECTS = $(am_libcommon_la_OBJECTS) +libcommon_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libcommon_la_CFLAGS) \ + $(CFLAGS) $(libcommon_la_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 = $(libcommon_la_SOURCES) +DIST_SOURCES = $(libcommon_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@ +noinst_LTLIBRARIES = libcommon.la +libcommon_la_SOURCES = \ + eggaccelerators.c \ + eggaccelerators.h \ + gsd-keygrab.c \ + gsd-keygrab.h \ + gsd-osd-window.c \ + gsd-osd-window.h + +libcommon_la_CPPFLAGS = \ + $(AM_CPPFLAGS) + +libcommon_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libcommon_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) $(X11_LIBS) + +libcommon_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) + +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/common/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plugins/common/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 +libcommon.la: $(libcommon_la_OBJECTS) $(libcommon_la_DEPENDENCIES) + $(libcommon_la_LINK) $(libcommon_la_OBJECTS) $(libcommon_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_la-eggaccelerators.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_la-gsd-keygrab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcommon_la-gsd-osd-window.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 $@ $< + +libcommon_la-eggaccelerators.lo: eggaccelerators.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcommon_la_CPPFLAGS) $(CPPFLAGS) $(libcommon_la_CFLAGS) $(CFLAGS) -MT libcommon_la-eggaccelerators.lo -MD -MP -MF $(DEPDIR)/libcommon_la-eggaccelerators.Tpo -c -o libcommon_la-eggaccelerators.lo `test -f 'eggaccelerators.c' || echo '$(srcdir)/'`eggaccelerators.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_la-eggaccelerators.Tpo $(DEPDIR)/libcommon_la-eggaccelerators.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eggaccelerators.c' object='libcommon_la-eggaccelerators.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) $(libcommon_la_CPPFLAGS) $(CPPFLAGS) $(libcommon_la_CFLAGS) $(CFLAGS) -c -o libcommon_la-eggaccelerators.lo `test -f 'eggaccelerators.c' || echo '$(srcdir)/'`eggaccelerators.c + +libcommon_la-gsd-keygrab.lo: gsd-keygrab.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcommon_la_CPPFLAGS) $(CPPFLAGS) $(libcommon_la_CFLAGS) $(CFLAGS) -MT libcommon_la-gsd-keygrab.lo -MD -MP -MF $(DEPDIR)/libcommon_la-gsd-keygrab.Tpo -c -o libcommon_la-gsd-keygrab.lo `test -f 'gsd-keygrab.c' || echo '$(srcdir)/'`gsd-keygrab.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_la-gsd-keygrab.Tpo $(DEPDIR)/libcommon_la-gsd-keygrab.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-keygrab.c' object='libcommon_la-gsd-keygrab.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) $(libcommon_la_CPPFLAGS) $(CPPFLAGS) $(libcommon_la_CFLAGS) $(CFLAGS) -c -o libcommon_la-gsd-keygrab.lo `test -f 'gsd-keygrab.c' || echo '$(srcdir)/'`gsd-keygrab.c + +libcommon_la-gsd-osd-window.lo: gsd-osd-window.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcommon_la_CPPFLAGS) $(CPPFLAGS) $(libcommon_la_CFLAGS) $(CFLAGS) -MT libcommon_la-gsd-osd-window.lo -MD -MP -MF $(DEPDIR)/libcommon_la-gsd-osd-window.Tpo -c -o libcommon_la-gsd-osd-window.lo `test -f 'gsd-osd-window.c' || echo '$(srcdir)/'`gsd-osd-window.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libcommon_la-gsd-osd-window.Tpo $(DEPDIR)/libcommon_la-gsd-osd-window.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-osd-window.c' object='libcommon_la-gsd-osd-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) $(libcommon_la_CPPFLAGS) $(CPPFLAGS) $(libcommon_la_CFLAGS) $(CFLAGS) -c -o libcommon_la-gsd-osd-window.lo `test -f 'gsd-osd-window.c' || echo '$(srcdir)/'`gsd-osd-window.c + +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." +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/common/eggaccelerators.c b/plugins/common/eggaccelerators.c new file mode 100644 index 0000000..e3b8ae3 --- /dev/null +++ b/plugins/common/eggaccelerators.c @@ -0,0 +1,658 @@ +/* eggaccelerators.c + * Copyright (C) 2002 Red Hat, Inc.; Copyright 1998, 2001 Tim Janik + * Developed by Havoc Pennington, Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "eggaccelerators.h" + +#include <stdlib.h> +#include <string.h> +#include <gdk/gdkx.h> +#include <gdk/gdkkeysyms.h> +#include <gtk/gtk.h> + +enum +{ + EGG_MODMAP_ENTRY_SHIFT = 0, + EGG_MODMAP_ENTRY_LOCK = 1, + EGG_MODMAP_ENTRY_CONTROL = 2, + EGG_MODMAP_ENTRY_MOD1 = 3, + EGG_MODMAP_ENTRY_MOD2 = 4, + EGG_MODMAP_ENTRY_MOD3 = 5, + EGG_MODMAP_ENTRY_MOD4 = 6, + EGG_MODMAP_ENTRY_MOD5 = 7, + EGG_MODMAP_ENTRY_LAST = 8 +}; + +#define MODMAP_ENTRY_TO_MODIFIER(x) (1 << (x)) + +typedef struct +{ + EggVirtualModifierType mapping[EGG_MODMAP_ENTRY_LAST]; + +} EggModmap; + +const EggModmap* egg_keymap_get_modmap (GdkKeymap *keymap); + +static inline gboolean +is_alt (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'a' || string[1] == 'A') && + (string[2] == 'l' || string[2] == 'L') && + (string[3] == 't' || string[3] == 'T') && + (string[4] == '>')); +} + +static inline gboolean +is_ctl (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'c' || string[1] == 'C') && + (string[2] == 't' || string[2] == 'T') && + (string[3] == 'l' || string[3] == 'L') && + (string[4] == '>')); +} + +static inline gboolean +is_modx (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'm' || string[1] == 'M') && + (string[2] == 'o' || string[2] == 'O') && + (string[3] == 'd' || string[3] == 'D') && + (string[4] >= '1' && string[4] <= '5') && + (string[5] == '>')); +} + +static inline gboolean +is_ctrl (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'c' || string[1] == 'C') && + (string[2] == 't' || string[2] == 'T') && + (string[3] == 'r' || string[3] == 'R') && + (string[4] == 'l' || string[4] == 'L') && + (string[5] == '>')); +} + +static inline gboolean +is_shft (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 's' || string[1] == 'S') && + (string[2] == 'h' || string[2] == 'H') && + (string[3] == 'f' || string[3] == 'F') && + (string[4] == 't' || string[4] == 'T') && + (string[5] == '>')); +} + +static inline gboolean +is_shift (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 's' || string[1] == 'S') && + (string[2] == 'h' || string[2] == 'H') && + (string[3] == 'i' || string[3] == 'I') && + (string[4] == 'f' || string[4] == 'F') && + (string[5] == 't' || string[5] == 'T') && + (string[6] == '>')); +} + +static inline gboolean +is_control (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'c' || string[1] == 'C') && + (string[2] == 'o' || string[2] == 'O') && + (string[3] == 'n' || string[3] == 'N') && + (string[4] == 't' || string[4] == 'T') && + (string[5] == 'r' || string[5] == 'R') && + (string[6] == 'o' || string[6] == 'O') && + (string[7] == 'l' || string[7] == 'L') && + (string[8] == '>')); +} + +static inline gboolean +is_release (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'r' || string[1] == 'R') && + (string[2] == 'e' || string[2] == 'E') && + (string[3] == 'l' || string[3] == 'L') && + (string[4] == 'e' || string[4] == 'E') && + (string[5] == 'a' || string[5] == 'A') && + (string[6] == 's' || string[6] == 'S') && + (string[7] == 'e' || string[7] == 'E') && + (string[8] == '>')); +} + +static inline gboolean +is_meta (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'm' || string[1] == 'M') && + (string[2] == 'e' || string[2] == 'E') && + (string[3] == 't' || string[3] == 'T') && + (string[4] == 'a' || string[4] == 'A') && + (string[5] == '>')); +} + +static inline gboolean +is_super (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 's' || string[1] == 'S') && + (string[2] == 'u' || string[2] == 'U') && + (string[3] == 'p' || string[3] == 'P') && + (string[4] == 'e' || string[4] == 'E') && + (string[5] == 'r' || string[5] == 'R') && + (string[6] == '>')); +} + +static inline gboolean +is_hyper (const gchar *string) +{ + return ((string[0] == '<') && + (string[1] == 'h' || string[1] == 'H') && + (string[2] == 'y' || string[2] == 'Y') && + (string[3] == 'p' || string[3] == 'P') && + (string[4] == 'e' || string[4] == 'E') && + (string[5] == 'r' || string[5] == 'R') && + (string[6] == '>')); +} + +static inline gboolean +is_keycode (const gchar *string) +{ + return ((string[0] == '0') && + (string[1] == 'x')); +} + +/** + * egg_accelerator_parse_virtual: + * @accelerator: string representing an accelerator + * @accelerator_key: return location for accelerator keyval + * @accelerator_codes: return location for a 0-terminated array + * of accelerator keycodes + * @accelerator_mods: return location for accelerator modifier mask + * + * Parses a string representing a virtual accelerator. The format + * looks like "<Control>a" or "<Shift><Alt>F1" or + * "<Release>z" (the last one is for key release). The parser + * is fairly liberal and allows lower or upper case, and also + * abbreviations such as "<Ctl>" and "<Ctrl>". + * + * If the parse fails, @accelerator_key and @accelerator_mods will + * be set to 0 (zero) and %FALSE will be returned. If the string contains + * only modifiers, @accelerator_key will be set to 0 but %TRUE will be + * returned. + * + * The virtual vs. concrete accelerator distinction is a relic of + * how the X Window System works; there are modifiers Mod2-Mod5 that + * can represent various keyboard keys (numlock, meta, hyper, etc.), + * the virtual modifier represents the keyboard key, the concrete + * modifier the actual Mod2-Mod5 bits in the key press event. + * + * Returns: %TRUE on success. + */ +gboolean +egg_accelerator_parse_virtual (const gchar *accelerator, + guint *accelerator_key, + guint **accelerator_codes, + EggVirtualModifierType *accelerator_mods) +{ + guint keyval; + GdkModifierType mods; + gint len; + gboolean bad_keyval; + + if (accelerator_key) + *accelerator_key = 0; + if (accelerator_mods) + *accelerator_mods = 0; + if (accelerator_codes) + *accelerator_codes = NULL; + + g_return_val_if_fail (accelerator != NULL, FALSE); + + bad_keyval = FALSE; + + keyval = 0; + mods = 0; + len = strlen (accelerator); + while (len) + { + if (*accelerator == '<') + { + if (len >= 9 && is_release (accelerator)) + { + accelerator += 9; + len -= 9; + mods |= EGG_VIRTUAL_RELEASE_MASK; + } + else if (len >= 9 && is_control (accelerator)) + { + accelerator += 9; + len -= 9; + mods |= EGG_VIRTUAL_CONTROL_MASK; + } + else if (len >= 7 && is_shift (accelerator)) + { + accelerator += 7; + len -= 7; + mods |= EGG_VIRTUAL_SHIFT_MASK; + } + else if (len >= 6 && is_shft (accelerator)) + { + accelerator += 6; + len -= 6; + mods |= EGG_VIRTUAL_SHIFT_MASK; + } + else if (len >= 6 && is_ctrl (accelerator)) + { + accelerator += 6; + len -= 6; + mods |= EGG_VIRTUAL_CONTROL_MASK; + } + else if (len >= 6 && is_modx (accelerator)) + { + static const guint mod_vals[] = { + EGG_VIRTUAL_ALT_MASK, EGG_VIRTUAL_MOD2_MASK, EGG_VIRTUAL_MOD3_MASK, + EGG_VIRTUAL_MOD4_MASK, EGG_VIRTUAL_MOD5_MASK + }; + + len -= 6; + accelerator += 4; + mods |= mod_vals[*accelerator - '1']; + accelerator += 2; + } + else if (len >= 5 && is_ctl (accelerator)) + { + accelerator += 5; + len -= 5; + mods |= EGG_VIRTUAL_CONTROL_MASK; + } + else if (len >= 5 && is_alt (accelerator)) + { + accelerator += 5; + len -= 5; + mods |= EGG_VIRTUAL_ALT_MASK; + } + else if (len >= 6 && is_meta (accelerator)) + { + accelerator += 6; + len -= 6; + mods |= EGG_VIRTUAL_META_MASK; + } + else if (len >= 7 && is_hyper (accelerator)) + { + accelerator += 7; + len -= 7; + mods |= EGG_VIRTUAL_HYPER_MASK; + } + else if (len >= 7 && is_super (accelerator)) + { + accelerator += 7; + len -= 7; + mods |= EGG_VIRTUAL_SUPER_MASK; + } + else + { + gchar last_ch; + + last_ch = *accelerator; + while (last_ch && last_ch != '>') + { + last_ch = *accelerator; + accelerator += 1; + len -= 1; + } + } + } + else + { + keyval = gdk_keyval_from_name (accelerator); + + if (keyval == 0) + { + /* If keyval is 0, then maybe it's a keycode. Check for 0x## */ + if (len >= 4 && is_keycode (accelerator)) + { + char keystring[5]; + gchar *endptr; + gint tmp_keycode; + + memcpy (keystring, accelerator, 4); + keystring [4] = '\000'; + + tmp_keycode = strtol (keystring, &endptr, 16); + + if (endptr == NULL || *endptr != '\000') + { + bad_keyval = TRUE; + } + else if (accelerator_codes != NULL) + { + /* 0x00 is an invalid keycode too. */ + if (tmp_keycode == 0) { + bad_keyval = TRUE; + } else { + *accelerator_codes = g_new0 (guint, 2); + (*accelerator_codes)[0] = tmp_keycode; + } + } + } + else + { + bad_keyval = TRUE; + } + } + else if (accelerator_codes != NULL) + { + GdkKeymapKey *keys; + gint n_keys, i, j; + + if (!gdk_keymap_get_entries_for_keyval (NULL, keyval, &keys, &n_keys)) { + bad_keyval = TRUE; + } else { + *accelerator_codes = g_new0 (guint, n_keys + 1); + + for (i = 0, j = 0; i < n_keys; ++i) { + if (keys[i].level == 0) + (*accelerator_codes)[j++] = keys[i].keycode; + } + + if (j == 0) { + g_free (*accelerator_codes); + *accelerator_codes = NULL; + bad_keyval = TRUE; + } + g_free (keys); + } + } + + accelerator += len; + len -= len; + } + } + + if (accelerator_key) + *accelerator_key = gdk_keyval_to_lower (keyval); + if (accelerator_mods) + *accelerator_mods = mods; + + return !bad_keyval; +} + +/** + * egg_virtual_accelerator_name: + * @accelerator_key: accelerator keyval + * @accelerator_mods: accelerator modifier mask + * @returns: a newly-allocated accelerator name + * + * Converts an accelerator keyval and modifier mask + * into a string parseable by egg_accelerator_parse_virtual(). + * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK, + * this function returns "<Control>q". + * + * The caller of this function must free the returned string. + */ +gchar* +egg_virtual_accelerator_name (guint accelerator_key, + guint keycode, + EggVirtualModifierType accelerator_mods) +{ + gchar *gtk_name; + GdkModifierType gdkmods = 0; + + egg_keymap_resolve_virtual_modifiers (NULL, accelerator_mods, &gdkmods); + gtk_name = gtk_accelerator_name (accelerator_key, gdkmods); + + if (!accelerator_key) + { + gchar *name; + name = g_strdup_printf ("%s0x%02x", gtk_name, keycode); + g_free (gtk_name); + return name; + } + + return gtk_name; +} + +/** + * egg_virtual_accelerator_label: + * @accelerator_key: accelerator keyval + * @accelerator_mods: accelerator modifier mask + * @returns: a newly-allocated accelerator label + * + * Converts an accelerator keyval and modifier mask + * into a (possibly translated) string that can be displayed to + * a user. + * For example, if you pass in #GDK_q and #EGG_VIRTUAL_CONTROL_MASK, + * and you use a German locale, this function returns "Strg+Q". + * + * The caller of this function must free the returned string. + */ +gchar* +egg_virtual_accelerator_label (guint accelerator_key, + guint keycode, + EggVirtualModifierType accelerator_mods) +{ + gchar *gtk_label; + GdkModifierType gdkmods = 0; + + egg_keymap_resolve_virtual_modifiers (NULL, accelerator_mods, &gdkmods); + gtk_label = gtk_accelerator_get_label (accelerator_key, gdkmods); + + if (!accelerator_key) + { + gchar *label; + label = g_strdup_printf ("%s0x%02x", gtk_label, keycode); + g_free (gtk_label); + return label; + } + + return gtk_label; +} + +void +egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap, + EggVirtualModifierType virtual_mods, + GdkModifierType *concrete_mods) +{ + GdkModifierType concrete; + int i; + const EggModmap *modmap; + + g_return_if_fail (concrete_mods != NULL); + g_return_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap)); + + modmap = egg_keymap_get_modmap (keymap); + + /* Not so sure about this algorithm. */ + + concrete = 0; + for (i = 0; i < EGG_MODMAP_ENTRY_LAST; ++i) + { + if (modmap->mapping[i] & virtual_mods) + concrete |= MODMAP_ENTRY_TO_MODIFIER (i); + } + + *concrete_mods = concrete; +} + +void +egg_keymap_virtualize_modifiers (GdkKeymap *keymap, + GdkModifierType concrete_mods, + EggVirtualModifierType *virtual_mods) +{ + GdkModifierType virtual; + int i; + const EggModmap *modmap; + + g_return_if_fail (virtual_mods != NULL); + g_return_if_fail (keymap == NULL || GDK_IS_KEYMAP (keymap)); + + modmap = egg_keymap_get_modmap (keymap); + + /* Not so sure about this algorithm. */ + + virtual = 0; + for (i = 0; i < EGG_MODMAP_ENTRY_LAST; ++i) + { + if (MODMAP_ENTRY_TO_MODIFIER (i) & concrete_mods) + { + EggVirtualModifierType cleaned; + + cleaned = modmap->mapping[i] & ~(EGG_VIRTUAL_MOD2_MASK | + EGG_VIRTUAL_MOD3_MASK | + EGG_VIRTUAL_MOD4_MASK | + EGG_VIRTUAL_MOD5_MASK); + + if (cleaned != 0) + { + virtual |= cleaned; + } + else + { + /* Rather than dropping mod2->mod5 if not bound, + * go ahead and use the concrete names + */ + virtual |= modmap->mapping[i]; + } + } + } + + *virtual_mods = virtual; +} + +static void +reload_modmap (GdkKeymap *keymap, + EggModmap *modmap) +{ + XModifierKeymap *xmodmap; + int map_size; + int i; + + /* FIXME multihead */ + xmodmap = XGetModifierMapping (gdk_x11_get_default_xdisplay ()); + + memset (modmap->mapping, 0, sizeof (modmap->mapping)); + + /* there are 8 modifiers in the order shift, shift lock, + * control, mod1-5 with up to max_keypermod bindings each + */ + map_size = 8 * xmodmap->max_keypermod; + for (i = 3 * xmodmap->max_keypermod; i < map_size; ++i) + { + /* get the key code at this point in the map, + * see if its keysym is one we're interested in + */ + int keycode = xmodmap->modifiermap[i]; + GdkKeymapKey *keys; + guint *keyvals; + int n_entries; + int j; + EggVirtualModifierType mask; + + keys = NULL; + keyvals = NULL; + n_entries = 0; + + gdk_keymap_get_entries_for_keycode (keymap, + keycode, + &keys, &keyvals, &n_entries); + + mask = 0; + for (j = 0; j < n_entries; ++j) + { + if (keyvals[j] == GDK_Num_Lock) + mask |= EGG_VIRTUAL_NUM_LOCK_MASK; + else if (keyvals[j] == GDK_Scroll_Lock) + mask |= EGG_VIRTUAL_SCROLL_LOCK_MASK; + else if (keyvals[j] == GDK_Meta_L || + keyvals[j] == GDK_Meta_R) + mask |= EGG_VIRTUAL_META_MASK; + else if (keyvals[j] == GDK_Hyper_L || + keyvals[j] == GDK_Hyper_R) + mask |= EGG_VIRTUAL_HYPER_MASK; + else if (keyvals[j] == GDK_Super_L || + keyvals[j] == GDK_Super_R) + mask |= EGG_VIRTUAL_SUPER_MASK; + else if (keyvals[j] == GDK_Mode_switch) + mask |= EGG_VIRTUAL_MODE_SWITCH_MASK; + } + + /* Mod1Mask is 1 << 3 for example, i.e. the + * fourth modifier, i / keyspermod is the modifier + * index + */ + modmap->mapping[i/xmodmap->max_keypermod] |= mask; + + g_free (keyvals); + g_free (keys); + } + + /* Add in the not-really-virtual fixed entries */ + modmap->mapping[EGG_MODMAP_ENTRY_SHIFT] |= EGG_VIRTUAL_SHIFT_MASK; + modmap->mapping[EGG_MODMAP_ENTRY_CONTROL] |= EGG_VIRTUAL_CONTROL_MASK; + modmap->mapping[EGG_MODMAP_ENTRY_LOCK] |= EGG_VIRTUAL_LOCK_MASK; + modmap->mapping[EGG_MODMAP_ENTRY_MOD1] |= EGG_VIRTUAL_ALT_MASK; + modmap->mapping[EGG_MODMAP_ENTRY_MOD2] |= EGG_VIRTUAL_MOD2_MASK; + modmap->mapping[EGG_MODMAP_ENTRY_MOD3] |= EGG_VIRTUAL_MOD3_MASK; + modmap->mapping[EGG_MODMAP_ENTRY_MOD4] |= EGG_VIRTUAL_MOD4_MASK; + modmap->mapping[EGG_MODMAP_ENTRY_MOD5] |= EGG_VIRTUAL_MOD5_MASK; + + XFreeModifiermap (xmodmap); +} + +const EggModmap* +egg_keymap_get_modmap (GdkKeymap *keymap) +{ + EggModmap *modmap; + + if (keymap == NULL) + keymap = gdk_keymap_get_default (); + + /* This is all a hack, much simpler when we can just + * modify GDK directly. + */ + + modmap = g_object_get_data (G_OBJECT (keymap), "egg-modmap"); + + if (modmap == NULL) + { + modmap = g_new0 (EggModmap, 1); + + /* FIXME modify keymap change events with an event filter + * and force a reload if we get one + */ + + reload_modmap (keymap, modmap); + + g_object_set_data_full (G_OBJECT (keymap), + "egg-modmap", + modmap, + g_free); + } + + g_assert (modmap != NULL); + + return modmap; +} diff --git a/plugins/common/eggaccelerators.h b/plugins/common/eggaccelerators.h new file mode 100644 index 0000000..786b11f --- /dev/null +++ b/plugins/common/eggaccelerators.h @@ -0,0 +1,99 @@ +/* eggaccelerators.h + * Copyright (C) 2002 Red Hat, Inc. + * Developed by Havoc Pennington + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __EGG_ACCELERATORS_H__ +#define __EGG_ACCELERATORS_H__ + +#include <gtk/gtk.h> +#include <gdk/gdk.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* Where a value is also in GdkModifierType we coincide, + * otherwise we don't overlap. + */ +typedef enum +{ + EGG_VIRTUAL_SHIFT_MASK = 1 << 0, + EGG_VIRTUAL_LOCK_MASK = 1 << 1, + EGG_VIRTUAL_CONTROL_MASK = 1 << 2, + + EGG_VIRTUAL_ALT_MASK = 1 << 3, /* fixed as Mod1 */ + + EGG_VIRTUAL_MOD2_MASK = 1 << 4, + EGG_VIRTUAL_MOD3_MASK = 1 << 5, + EGG_VIRTUAL_MOD4_MASK = 1 << 6, + EGG_VIRTUAL_MOD5_MASK = 1 << 7, + +#if 0 + GDK_BUTTON1_MASK = 1 << 8, + GDK_BUTTON2_MASK = 1 << 9, + GDK_BUTTON3_MASK = 1 << 10, + GDK_BUTTON4_MASK = 1 << 11, + GDK_BUTTON5_MASK = 1 << 12, + /* 13, 14 are used by Xkb for the keyboard group */ +#endif + + EGG_VIRTUAL_MODE_SWITCH_MASK = 1 << 23, + EGG_VIRTUAL_NUM_LOCK_MASK = 1 << 24, + EGG_VIRTUAL_SCROLL_LOCK_MASK = 1 << 25, + + /* Also in GdkModifierType */ + EGG_VIRTUAL_SUPER_MASK = 1 << 26, + EGG_VIRTUAL_HYPER_MASK = 1 << 27, + EGG_VIRTUAL_META_MASK = 1 << 28, + + /* Also in GdkModifierType */ + EGG_VIRTUAL_RELEASE_MASK = 1 << 30, + + /* 28-31 24-27 20-23 16-19 12-15 8-11 4-7 0-3 + * 5 f 8 0 0 0 f f + */ + EGG_VIRTUAL_MODIFIER_MASK = 0x5f8000ff + +} EggVirtualModifierType; + +gboolean egg_accelerator_parse_virtual (const gchar *accelerator, + guint *accelerator_key, + guint **accelerator_codes, + EggVirtualModifierType *accelerator_mods); +void egg_keymap_resolve_virtual_modifiers (GdkKeymap *keymap, + EggVirtualModifierType virtual_mods, + GdkModifierType *concrete_mods); +void egg_keymap_virtualize_modifiers (GdkKeymap *keymap, + GdkModifierType concrete_mods, + EggVirtualModifierType *virtual_mods); + +gchar* egg_virtual_accelerator_name (guint accelerator_key, + guint keycode, + EggVirtualModifierType accelerator_mods); + +gchar* egg_virtual_accelerator_label (guint accelerator_key, + guint keycode, + EggVirtualModifierType accelerator_mods); + +#ifdef __cplusplus +} +#endif + + +#endif /* __EGG_ACCELERATORS_H__ */ diff --git a/plugins/common/gsd-keygrab.c b/plugins/common/gsd-keygrab.c new file mode 100644 index 0000000..7d70665 --- /dev/null +++ b/plugins/common/gsd-keygrab.c @@ -0,0 +1,246 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2001-2003 Bastien Nocera <[email protected]> + * Copyright (C) 2006-2007 William Jon McCann <[email protected]> + * Copyright (C) 2008 Jens Granseuer <[email protected]> + * + * 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 <gdk/gdk.h> +#include <gdk/gdkx.h> +#ifdef HAVE_X11_EXTENSIONS_XKB_H +#include <X11/XKBlib.h> +#include <X11/extensions/XKB.h> +#include <gdk/gdkkeysyms.h> +#endif + +#include "eggaccelerators.h" + +#include "gsd-keygrab.h" + +/* these are the mods whose combinations are ignored by the keygrabbing code */ +static GdkModifierType gsd_ignored_mods = 0; + +/* these are the ones we actually use for global keys, we always only check + * for these set */ +static GdkModifierType gsd_used_mods = 0; + +static void +setup_modifiers (void) +{ + if (gsd_used_mods == 0 || gsd_ignored_mods == 0) { + GdkModifierType dynmods; + + /* default modifiers */ + gsd_ignored_mods = \ + 0x2000 /*Xkb modifier*/ | GDK_LOCK_MASK | GDK_HYPER_MASK; + gsd_used_mods = \ + GDK_SHIFT_MASK | GDK_CONTROL_MASK |\ + GDK_MOD1_MASK | GDK_MOD2_MASK | GDK_MOD3_MASK | GDK_MOD4_MASK |\ + GDK_MOD5_MASK | GDK_SUPER_MASK | GDK_META_MASK; + + /* NumLock can be assigned to varying keys so we need to + * resolve and ignore it specially */ + dynmods = 0; + egg_keymap_resolve_virtual_modifiers (gdk_keymap_get_default (), + EGG_VIRTUAL_NUM_LOCK_MASK, + &dynmods); + + gsd_ignored_mods |= dynmods; + gsd_used_mods &= ~dynmods; + } +} + +static void +grab_key_real (guint keycode, + GdkWindow *root, + gboolean grab, + int mask) +{ + if (grab) { + XGrabKey (GDK_DISPLAY (), + keycode, + mask, + GDK_WINDOW_XID (root), + True, + GrabModeAsync, + GrabModeAsync); + } else { + XUngrabKey (GDK_DISPLAY (), + keycode, + mask, + GDK_WINDOW_XID (root)); + } +} + +/* Grab the key. In order to ignore GSD_IGNORED_MODS we need to grab + * all combinations of the ignored modifiers and those actually used + * for the binding (if any). + * + * inspired by all_combinations from mate-panel/mate-panel/global-keys.c + * + * This may generate X errors. The correct way to use this is like: + * + * gdk_error_trap_push (); + * + * grab_key_unsafe (key, grab, screens); + * + * gdk_flush (); + * if (gdk_error_trap_pop ()) + * g_warning ("Grab failed, another application may already have access to key '%u'", + * key->keycode); + * + * This is not done in the function itself, to allow doing multiple grab_key + * operations with one flush only. + */ +#define N_BITS 32 +void +grab_key_unsafe (Key *key, + gboolean grab, + GSList *screens) +{ + int indexes[N_BITS]; /* indexes of bits we need to flip */ + int i; + int bit; + int bits_set_cnt; + int uppervalue; + guint mask; + + setup_modifiers (); + + mask = gsd_ignored_mods & ~key->state & GDK_MODIFIER_MASK; + + bit = 0; + /* store the indexes of all set bits in mask in the array */ + for (i = 0; mask; ++i, mask >>= 1) { + if (mask & 0x1) { + indexes[bit++] = i; + } + } + + bits_set_cnt = bit; + + uppervalue = 1 << bits_set_cnt; + /* grab all possible modifier combinations for our mask */ + for (i = 0; i < uppervalue; ++i) { + GSList *l; + int j; + int result = 0; + + /* map bits in the counter to those in the mask */ + for (j = 0; j < bits_set_cnt; ++j) { + if (i & (1 << j)) { + result |= (1 << indexes[j]); + } + } + + for (l = screens; l; l = l->next) { + GdkScreen *screen = l->data; + guint *code; + + for (code = key->keycodes; *code; ++code) { + grab_key_real (*code, + gdk_screen_get_root_window (screen), + grab, + result | key->state); + } + } + } +} + +static gboolean +have_xkb (Display *dpy) +{ + static int have_xkb = -1; + + if (have_xkb == -1) { +#ifdef HAVE_X11_EXTENSIONS_XKB_H + int opcode, error_base, major, minor, xkb_event_base; + + have_xkb = XkbQueryExtension (dpy, + &opcode, + &xkb_event_base, + &error_base, + &major, + &minor) + && XkbUseExtension (dpy, &major, &minor); +#else + have_xkb = 0; +#endif + } + + return have_xkb; +} + +gboolean +key_uses_keycode (const Key *key, guint keycode) +{ + if (key->keycodes != NULL) { + guint *c; + + for (c = key->keycodes; *c; ++c) { + if (*c == keycode) + return TRUE; + } + } + return FALSE; +} + +gboolean +match_key (Key *key, XEvent *event) +{ + guint keyval; + GdkModifierType consumed; + gint group; + + if (key == NULL) + return FALSE; + + setup_modifiers (); + +#ifdef HAVE_X11_EXTENSIONS_XKB_H + if (have_xkb (event->xkey.display)) + group = XkbGroupForCoreState (event->xkey.state); + else +#endif + group = (event->xkey.state & GDK_Mode_switch) ? 1 : 0; + + /* Check if we find a keysym that matches our current state */ + if (gdk_keymap_translate_keyboard_state (NULL, event->xkey.keycode, + event->xkey.state, group, + &keyval, NULL, NULL, &consumed)) { + guint lower, upper; + + gdk_keyval_convert_case (keyval, &lower, &upper); + + /* If we are checking against the lower version of the + * keysym, we might need the Shift state for matching, + * so remove it from the consumed modifiers */ + if (lower == key->keysym) + consumed &= ~GDK_SHIFT_MASK; + + return ((lower == key->keysym || upper == key->keysym) + && (event->xkey.state & ~consumed & gsd_used_mods) == key->state); + } + + /* The key we passed doesn't have a keysym, so try with just the keycode */ + return (key != NULL + && key->state == (event->xkey.state & gsd_used_mods) + && key_uses_keycode (key, event->xkey.keycode)); +} diff --git a/plugins/common/gsd-keygrab.h b/plugins/common/gsd-keygrab.h new file mode 100644 index 0000000..a157ab4 --- /dev/null +++ b/plugins/common/gsd-keygrab.h @@ -0,0 +1,51 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Jens Granseuer <[email protected]> + * + * 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_COMMON_KEYGRAB_H +#define __GSD_COMMON_KEYGRAB_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib.h> +#include <X11/keysym.h> + +typedef struct { + guint keysym; + guint state; + guint *keycodes; +} Key; + + +void grab_key_unsafe (Key *key, + gboolean grab, + GSList *screens); + +gboolean match_key (Key *key, + XEvent *event); + +gboolean key_uses_keycode (const Key *key, + guint keycode); + +#ifdef __cplusplus +} +#endif + +#endif /* __GSD_COMMON_KEYGRAB_H */ diff --git a/plugins/common/gsd-osd-window.c b/plugins/common/gsd-osd-window.c new file mode 100644 index 0000000..03ca316 --- /dev/null +++ b/plugins/common/gsd-osd-window.c @@ -0,0 +1,573 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * On-screen-display (OSD) window for mate-settings-daemon's plugins + * + * Copyright (C) 2006-2007 William Jon McCann <[email protected]> + * Copyright (C) 2009 Novell, Inc + * + * Authors: + * William Jon McCann <[email protected]> + * Federico Mena-Quintero <[email protected]> + * + * 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 <stdlib.h> +#include <string.h> +#include <math.h> +#include <glib.h> +#include <glib/gi18n.h> +#include <gtk/gtk.h> + +#include "gsd-osd-window.h" + +#define DIALOG_TIMEOUT 2000 /* dialog timeout in ms */ +#define DIALOG_FADE_TIMEOUT 1500 /* timeout before fade starts */ +#define FADE_TIMEOUT 10 /* timeout in ms between each frame of the fade */ + +#define BG_ALPHA 0.75 + +#define GSD_OSD_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_OSD_WINDOW, GsdOsdWindowPrivate)) + +struct GsdOsdWindowPrivate +{ + guint is_composited : 1; + guint hide_timeout_id; + guint fade_timeout_id; + double fade_out_alpha; +}; + +enum { + EXPOSE_WHEN_COMPOSITED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +G_DEFINE_TYPE (GsdOsdWindow, gsd_osd_window, GTK_TYPE_WINDOW) + +static gboolean +fade_timeout (GsdOsdWindow *window) +{ + if (window->priv->fade_out_alpha <= 0.0) { + gtk_widget_hide (GTK_WIDGET (window)); + + /* Reset it for the next time */ + window->priv->fade_out_alpha = 1.0; + window->priv->fade_timeout_id = 0; + + return FALSE; + } else { + GdkRectangle rect; + GtkWidget *win = GTK_WIDGET (window); + GtkAllocation allocation; + + window->priv->fade_out_alpha -= 0.10; + + rect.x = 0; + rect.y = 0; + gtk_widget_get_allocation (win, &allocation); + rect.width = allocation.width; + rect.height = allocation.height; + + gtk_widget_realize (win); + gdk_window_invalidate_rect (gtk_widget_get_window (win), &rect, FALSE); + } + + return TRUE; +} + +static gboolean +hide_timeout (GsdOsdWindow *window) +{ + if (window->priv->is_composited) { + window->priv->hide_timeout_id = 0; + window->priv->fade_timeout_id = g_timeout_add (FADE_TIMEOUT, + (GSourceFunc) fade_timeout, + window); + } else { + gtk_widget_hide (GTK_WIDGET (window)); + } + + return FALSE; +} + +static void +remove_hide_timeout (GsdOsdWindow *window) +{ + if (window->priv->hide_timeout_id != 0) { + g_source_remove (window->priv->hide_timeout_id); + window->priv->hide_timeout_id = 0; + } + + if (window->priv->fade_timeout_id != 0) { + g_source_remove (window->priv->fade_timeout_id); + window->priv->fade_timeout_id = 0; + window->priv->fade_out_alpha = 1.0; + } +} + +static void +add_hide_timeout (GsdOsdWindow *window) +{ + int timeout; + + if (window->priv->is_composited) { + timeout = DIALOG_FADE_TIMEOUT; + } else { + timeout = DIALOG_TIMEOUT; + } + window->priv->hide_timeout_id = g_timeout_add (timeout, + (GSourceFunc) hide_timeout, + window); +} + +void +gsd_osd_window_draw_rounded_rectangle (cairo_t* cr, + gdouble aspect, + gdouble x, + gdouble y, + gdouble corner_radius, + gdouble width, + gdouble height) +{ + gdouble radius = corner_radius / aspect; + + cairo_move_to (cr, x + radius, y); + + cairo_line_to (cr, + x + width - radius, + y); + cairo_arc (cr, + x + width - radius, + y + radius, + radius, + -90.0f * G_PI / 180.0f, + 0.0f * G_PI / 180.0f); + cairo_line_to (cr, + x + width, + y + height - radius); + cairo_arc (cr, + x + width - radius, + y + height - radius, + radius, + 0.0f * G_PI / 180.0f, + 90.0f * G_PI / 180.0f); + cairo_line_to (cr, + x + radius, + y + height); + cairo_arc (cr, + x + radius, + y + height - radius, + radius, + 90.0f * G_PI / 180.0f, + 180.0f * G_PI / 180.0f); + cairo_line_to (cr, + x, + y + radius); + cairo_arc (cr, + x + radius, + y + radius, + radius, + 180.0f * G_PI / 180.0f, + 270.0f * G_PI / 180.0f); + cairo_close_path (cr); +} + +void +gsd_osd_window_color_reverse (const GdkColor *a, + GdkColor *b) +{ + gdouble red; + gdouble green; + gdouble blue; + gdouble h; + gdouble s; + gdouble v; + + red = (gdouble) a->red / 65535.0; + green = (gdouble) a->green / 65535.0; + blue = (gdouble) a->blue / 65535.0; + + gtk_rgb_to_hsv (red, green, blue, &h, &s, &v); + + v = 0.5 + (0.5 - v); + if (v > 1.0) + v = 1.0; + else if (v < 0.0) + v = 0.0; + + gtk_hsv_to_rgb (h, s, v, &red, &green, &blue); + + b->red = red * 65535.0; + b->green = green * 65535.0; + b->blue = blue * 65535.0; +} + +/* This is our expose-event handler when the window is in a compositing manager. + * We draw everything by hand, using Cairo, so that we can have a nice + * transparent/rounded look. + */ +static void +expose_when_composited (GtkWidget *widget, GdkEventExpose *event) +{ + GsdOsdWindow *window; + cairo_t *context; + cairo_t *cr; + cairo_surface_t *surface; + int width; + int height; + GtkStyle *style; + GdkColor color; + double r, g, b; + + window = GSD_OSD_WINDOW (widget); + + context = gdk_cairo_create (gtk_widget_get_window (widget)); + + style = gtk_widget_get_style (widget); + cairo_set_operator (context, CAIRO_OPERATOR_SOURCE); + gtk_window_get_size (GTK_WINDOW (widget), &width, &height); + + surface = cairo_surface_create_similar (cairo_get_target (context), + CAIRO_CONTENT_COLOR_ALPHA, + width, + height); + + if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) { + goto done; + } + + cr = cairo_create (surface); + if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { + goto done; + } + cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + cairo_paint (cr); + + /* draw a box */ + gsd_osd_window_draw_rounded_rectangle (cr, 1.0, 0.5, 0.5, height / 10, width-1, height-1); + gsd_osd_window_color_reverse (&style->bg[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, BG_ALPHA); + cairo_fill_preserve (cr); + + gsd_osd_window_color_reverse (&style->text_aa[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, BG_ALPHA / 2); + cairo_set_line_width (cr, 1); + cairo_stroke (cr); + + g_signal_emit (window, signals[EXPOSE_WHEN_COMPOSITED], 0, cr); + + cairo_destroy (cr); + + /* Make sure we have a transparent background */ + cairo_rectangle (context, 0, 0, width, height); + cairo_set_source_rgba (context, 0.0, 0.0, 0.0, 0.0); + cairo_fill (context); + + cairo_set_source_surface (context, surface, 0, 0); + cairo_paint_with_alpha (context, window->priv->fade_out_alpha); + + done: + if (surface != NULL) { + cairo_surface_destroy (surface); + } + cairo_destroy (context); +} + +/* This is our expose-event handler when the window is *not* in a compositing manager. + * We just draw a rectangular frame by hand. We do this with hardcoded drawing code, + * instead of GtkFrame, to avoid changing the window's internal widget hierarchy: in + * either case (composited or non-composited), callers can assume that this works + * identically to a GtkWindow without any intermediate widgetry. + */ +static void +expose_when_not_composited (GtkWidget *widget, GdkEventExpose *event) +{ + GsdOsdWindow *window; + GtkAllocation allocation; + + window = GSD_OSD_WINDOW (widget); + + gtk_widget_get_allocation (widget, &allocation); + + gtk_paint_shadow (gtk_widget_get_style (widget), + gtk_widget_get_window (widget), + gtk_widget_get_state (widget), + GTK_SHADOW_OUT, + &event->area, + widget, + NULL, /* NULL detail -> themes should use the GsdOsdWindow widget name, probably */ + 0, + 0, + allocation.width, + allocation.height); +} + +static gboolean +gsd_osd_window_expose_event (GtkWidget *widget, + GdkEventExpose *event) +{ + GsdOsdWindow *window; + GtkWidget *child; + + window = GSD_OSD_WINDOW (widget); + + if (window->priv->is_composited) + expose_when_composited (widget, event); + else + expose_when_not_composited (widget, event); + + child = gtk_bin_get_child (GTK_BIN (window)); + if (child) + gtk_container_propagate_expose (GTK_CONTAINER (window), child, event); + + return FALSE; +} + +static void +gsd_osd_window_real_show (GtkWidget *widget) +{ + GsdOsdWindow *window; + + if (GTK_WIDGET_CLASS (gsd_osd_window_parent_class)->show) { + GTK_WIDGET_CLASS (gsd_osd_window_parent_class)->show (widget); + } + + window = GSD_OSD_WINDOW (widget); + remove_hide_timeout (window); + add_hide_timeout (window); +} + +static void +gsd_osd_window_real_hide (GtkWidget *widget) +{ + GsdOsdWindow *window; + + if (GTK_WIDGET_CLASS (gsd_osd_window_parent_class)->hide) { + GTK_WIDGET_CLASS (gsd_osd_window_parent_class)->hide (widget); + } + + window = GSD_OSD_WINDOW (widget); + remove_hide_timeout (window); +} + +static void +gsd_osd_window_real_realize (GtkWidget *widget) +{ + GdkColormap *colormap; + GtkAllocation allocation; + GdkBitmap *mask; + cairo_t *cr; + + colormap = gdk_screen_get_rgba_colormap (gtk_widget_get_screen (widget)); + + if (colormap != NULL) { + gtk_widget_set_colormap (widget, colormap); + } + + if (GTK_WIDGET_CLASS (gsd_osd_window_parent_class)->realize) { + GTK_WIDGET_CLASS (gsd_osd_window_parent_class)->realize (widget); + } + + gtk_widget_get_allocation (widget, &allocation); + mask = gdk_pixmap_new (gtk_widget_get_window (widget), + allocation.width, + allocation.height, + 1); + cr = gdk_cairo_create (mask); + + cairo_set_source_rgba (cr, 1., 1., 1., 0.); + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + cairo_paint (cr); + + /* make the whole window ignore events */ + gdk_window_input_shape_combine_mask (gtk_widget_get_window (widget), mask, 0, 0); + g_object_unref (mask); + cairo_destroy (cr); +} + +static void +gsd_osd_window_style_set (GtkWidget *widget, + GtkStyle *previous_style) +{ + GtkStyle *style; + + GTK_WIDGET_CLASS (gsd_osd_window_parent_class)->style_set (widget, previous_style); + + /* We set our border width to 12 (per the MATE standard), plus the + * thickness of the frame that we draw in our expose handler. This will + * make our child be 12 pixels away from the frame. + */ + + style = gtk_widget_get_style (widget); + gtk_container_set_border_width (GTK_CONTAINER (widget), 12 + MAX (style->xthickness, style->ythickness)); +} + +static void +gsd_osd_window_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + GtkStyle *style; + + GTK_WIDGET_CLASS (gsd_osd_window_parent_class)->size_request (widget, requisition); + + /* See the comment in gsd_osd_window_style_set() for why we add the thickness here */ + + style = gtk_widget_get_style (widget); + + requisition->width += style->xthickness; + requisition->height += style->ythickness; +} + +static GObject * +gsd_osd_window_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_params) +{ + GObject *object; + + object = G_OBJECT_CLASS (gsd_osd_window_parent_class)->constructor (type, n_construct_properties, construct_params); + + g_object_set (object, + "type", GTK_WINDOW_POPUP, + "type-hint", GDK_WINDOW_TYPE_HINT_NOTIFICATION, + "skip-taskbar-hint", TRUE, + "skip-pager-hint", TRUE, + "focus-on-map", FALSE, + NULL); + + return object; +} + +static void +gsd_osd_window_class_init (GsdOsdWindowClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + gobject_class->constructor = gsd_osd_window_constructor; + + widget_class->show = gsd_osd_window_real_show; + widget_class->hide = gsd_osd_window_real_hide; + widget_class->realize = gsd_osd_window_real_realize; + widget_class->style_set = gsd_osd_window_style_set; + widget_class->size_request = gsd_osd_window_size_request; + widget_class->expose_event = gsd_osd_window_expose_event; + + signals[EXPOSE_WHEN_COMPOSITED] = g_signal_new ("expose-when-composited", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GsdOsdWindowClass, expose_when_composited), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, + G_TYPE_POINTER); + + g_type_class_add_private (klass, sizeof (GsdOsdWindowPrivate)); +} + +/** + * gsd_osd_window_is_composited: + * @window: a #GsdOsdWindow + * + * Return value: whether the window was created on a composited screen. + */ +gboolean +gsd_osd_window_is_composited (GsdOsdWindow *window) +{ + return window->priv->is_composited; +} + +/** + * gsd_osd_window_is_valid: + * @window: a #GsdOsdWindow + * + * Return value: TRUE if the @window's idea of being composited matches whether + * its current screen is actually composited. + */ +gboolean +gsd_osd_window_is_valid (GsdOsdWindow *window) +{ + GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (window)); + return gdk_screen_is_composited (screen) == window->priv->is_composited; +} + +static void +gsd_osd_window_init (GsdOsdWindow *window) +{ + GdkScreen *screen; + + window->priv = GSD_OSD_WINDOW_GET_PRIVATE (window); + + screen = gtk_widget_get_screen (GTK_WIDGET (window)); + + window->priv->is_composited = gdk_screen_is_composited (screen); + + if (window->priv->is_composited) { + gdouble scalew, scaleh, scale; + gint size; + + gtk_window_set_decorated (GTK_WINDOW (window), FALSE); + gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE); + + /* assume 130x130 on a 640x480 display and scale from there */ + scalew = gdk_screen_get_width (screen) / 640.0; + scaleh = gdk_screen_get_height (screen) / 480.0; + scale = MIN (scalew, scaleh); + size = 130 * MAX (1, scale); + + gtk_window_set_default_size (GTK_WINDOW (window), size, size); + + window->priv->fade_out_alpha = 1.0; + } else { + gtk_container_set_border_width (GTK_CONTAINER (window), 12); + } +} + +GtkWidget * +gsd_osd_window_new (void) +{ + return g_object_new (GSD_TYPE_OSD_WINDOW, NULL); +} + +/** + * gsd_osd_window_update_and_hide: + * @window: a #GsdOsdWindow + * + * Queues the @window for immediate drawing, and queues a timer to hide the window. + */ +void +gsd_osd_window_update_and_hide (GsdOsdWindow *window) +{ + remove_hide_timeout (window); + add_hide_timeout (window); + + if (window->priv->is_composited) { + gtk_widget_queue_draw (GTK_WIDGET (window)); + } +} diff --git a/plugins/common/gsd-osd-window.h b/plugins/common/gsd-osd-window.h new file mode 100644 index 0000000..0d8040b --- /dev/null +++ b/plugins/common/gsd-osd-window.h @@ -0,0 +1,98 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8; tab-width: 8 -*- + * + * On-screen-display (OSD) window for mate-settings-daemon's plugins + * + * Copyright (C) 2006 William Jon McCann <[email protected]> + * Copyright (C) 2009 Novell, Inc + * + * Authors: + * William Jon McCann <[email protected]> + * Federico Mena-Quintero <[email protected]> + * + * 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. + * + */ + +/* GsdOsdWindow is an "on-screen-display" window (OSD). It is the cute, + * semi-transparent, curved popup that appears when you press a hotkey global to + * the desktop, such as to change the volume, switch your monitor's parameters, + * etc. + * + * You can create a GsdOsdWindow and use it as a normal GtkWindow. It will + * automatically center itself, figure out if it needs to be composited, etc. + * Just pack your widgets in it, sit back, and enjoy the ride. + */ + +#ifndef GSD_OSD_WINDOW_H +#define GSD_OSD_WINDOW_H + +#include <glib-object.h> +#include <gtk/gtk.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* Alpha value to be used for foreground objects drawn in an OSD window */ +#define GSD_OSD_WINDOW_FG_ALPHA 1.0 + +#define GSD_TYPE_OSD_WINDOW (gsd_osd_window_get_type ()) +#define GSD_OSD_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSD_TYPE_OSD_WINDOW, GsdOsdWindow)) +#define GSD_OSD_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSD_TYPE_OSD_WINDOW, GsdOsdWindowClass)) +#define GSD_IS_OSD_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSD_TYPE_OSD_WINDOW)) +#define GSD_IS_OSD_WINDOW_CLASS(klass) (G_TYPE_INSTANCE_GET_CLASS ((klass), GSD_TYPE_OSD_WINDOW)) +#define GSD_OSD_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSD_TYPE_OSD_WINDOW, GsdOsdWindowClass)) + +typedef struct GsdOsdWindow GsdOsdWindow; +typedef struct GsdOsdWindowClass GsdOsdWindowClass; +typedef struct GsdOsdWindowPrivate GsdOsdWindowPrivate; + +struct GsdOsdWindow { + GtkWindow parent; + + GsdOsdWindowPrivate *priv; +}; + +struct GsdOsdWindowClass { + GtkWindowClass parent_class; + + void (* expose_when_composited) (GsdOsdWindow *window, cairo_t *cr); +}; + +GType gsd_osd_window_get_type (void); + +GtkWidget * gsd_osd_window_new (void); +gboolean gsd_osd_window_is_composited (GsdOsdWindow *window); +gboolean gsd_osd_window_is_valid (GsdOsdWindow *window); +void gsd_osd_window_update_and_hide (GsdOsdWindow *window); + +void gsd_osd_window_draw_rounded_rectangle (cairo_t *cr, + gdouble aspect, + gdouble x, + gdouble y, + gdouble corner_radius, + gdouble width, + gdouble height); + +void gsd_osd_window_color_reverse (const GdkColor *a, + GdkColor *b); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/plugins/datetime/Makefile.am b/plugins/datetime/Makefile.am new file mode 100644 index 0000000..1ae28f7 --- /dev/null +++ b/plugins/datetime/Makefile.am @@ -0,0 +1,60 @@ +dbus_servicesdir = $(datadir)/dbus-1/system-services +dbus_confdir = $(sysconfdir)/dbus-1/system.d +polkitdir = $(datadir)/polkit-1/actions + +dbus_services_in_files = org.mate.SettingsDaemon.DateTimeMechanism.service.in +polkit_in_files = org.mate.settingsdaemon.datetimemechanism.policy.in + +gsd-datetime-mechanism-glue.h: $(srcdir)/gsd-datetime-mechanism.xml + $(AM_V_GEN)dbus-binding-tool \ + --prefix=gsd_datetime_mechanism --mode=glib-server \ + --output=gsd-datetime-mechanism-glue.h \ + $(srcdir)/gsd-datetime-mechanism.xml + +if HAVE_POLKIT +libexec_PROGRAMS = gsd-datetime-mechanism +endif + +gsd_datetime_mechanism_SOURCES = \ + gsd-datetime-mechanism.c \ + gsd-datetime-mechanism.h \ + gsd-datetime-mechanism-main.c \ + system-timezone.c \ + system-timezone.h + + +if HAVE_POLKIT +BUILT_SOURCES = gsd-datetime-mechanism-glue.h +endif + +AM_CFLAGS = $(SETTINGS_PLUGIN_CFLAGS) $(POLKIT_CFLAGS) +gsd_datetime_mechanism_LDADD = $(POLKIT_LIBS) $(SETTINGS_PLUGIN_LIBS) + + +if HAVE_POLKIT +dbus_services_DATA = $(dbus_services_in_files:.service.in=.service) + +$(dbus_services_DATA): $(dbus_services_in_files) + $(AM_V_GEN)sed -e "s|\@LIBEXECDIR\@|$(libexecdir)|" $< > $@ + +dbus_conf_DATA = org.mate.SettingsDaemon.DateTimeMechanism.conf + +@INTLTOOL_POLICY_RULE@ +polkit_DATA = $(polkit_in_files:.policy.in=.policy) + +else +dbus_services_DATA = +dbus_conf_DATA = +polkit_DATA = +endif + +EXTRA_DIST = \ + $(dbus_services_in_files) \ + org.mate.SettingsDaemon.DateTimeMechanism.conf \ + $(polkit_in_files) \ + gsd-datetime-mechanism.xml + +CLEANFILES = \ + org.mate.SettingsDaemon.DateTimeMechanism.service \ + org.mate.settingsdaemon.datetimemechanism.policy \ + $(BUILT_SOURCES)
\ No newline at end of file diff --git a/plugins/datetime/Makefile.in b/plugins/datetime/Makefile.in new file mode 100644 index 0000000..ab5da48 --- /dev/null +++ b/plugins/datetime/Makefile.in @@ -0,0 +1,719 @@ +# 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_POLKIT_TRUE@libexec_PROGRAMS = gsd-datetime-mechanism$(EXEEXT) +subdir = plugins/datetime +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__installdirs = "$(DESTDIR)$(libexecdir)" \ + "$(DESTDIR)$(dbus_confdir)" "$(DESTDIR)$(dbus_servicesdir)" \ + "$(DESTDIR)$(polkitdir)" +PROGRAMS = $(libexec_PROGRAMS) +am_gsd_datetime_mechanism_OBJECTS = gsd-datetime-mechanism.$(OBJEXT) \ + gsd-datetime-mechanism-main.$(OBJEXT) \ + system-timezone.$(OBJEXT) +gsd_datetime_mechanism_OBJECTS = $(am_gsd_datetime_mechanism_OBJECTS) +am__DEPENDENCIES_1 = +gsd_datetime_mechanism_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +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 = $(gsd_datetime_mechanism_SOURCES) +DIST_SOURCES = $(gsd_datetime_mechanism_SOURCES) +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' +DATA = $(dbus_conf_DATA) $(dbus_services_DATA) $(polkit_DATA) +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@ +dbus_servicesdir = $(datadir)/dbus-1/system-services +dbus_confdir = $(sysconfdir)/dbus-1/system.d +polkitdir = $(datadir)/polkit-1/actions +dbus_services_in_files = org.mate.SettingsDaemon.DateTimeMechanism.service.in +polkit_in_files = org.mate.settingsdaemon.datetimemechanism.policy.in +gsd_datetime_mechanism_SOURCES = \ + gsd-datetime-mechanism.c \ + gsd-datetime-mechanism.h \ + gsd-datetime-mechanism-main.c \ + system-timezone.c \ + system-timezone.h + +@HAVE_POLKIT_TRUE@BUILT_SOURCES = gsd-datetime-mechanism-glue.h +AM_CFLAGS = $(SETTINGS_PLUGIN_CFLAGS) $(POLKIT_CFLAGS) +gsd_datetime_mechanism_LDADD = $(POLKIT_LIBS) $(SETTINGS_PLUGIN_LIBS) +@HAVE_POLKIT_FALSE@dbus_services_DATA = +@HAVE_POLKIT_TRUE@dbus_services_DATA = $(dbus_services_in_files:.service.in=.service) +@HAVE_POLKIT_FALSE@dbus_conf_DATA = +@HAVE_POLKIT_TRUE@dbus_conf_DATA = org.mate.SettingsDaemon.DateTimeMechanism.conf +@HAVE_POLKIT_FALSE@polkit_DATA = +@HAVE_POLKIT_TRUE@polkit_DATA = $(polkit_in_files:.policy.in=.policy) +EXTRA_DIST = \ + $(dbus_services_in_files) \ + org.mate.SettingsDaemon.DateTimeMechanism.conf \ + $(polkit_in_files) \ + gsd-datetime-mechanism.xml + +CLEANFILES = \ + org.mate.SettingsDaemon.DateTimeMechanism.service \ + org.mate.settingsdaemon.datetimemechanism.policy \ + $(BUILT_SOURCES) + +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) 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/datetime/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plugins/datetime/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-libexecPROGRAMS: $(libexec_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(libexecdir)" || $(MKDIR_P) "$(DESTDIR)$(libexecdir)" + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(libexecdir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-libexecPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(libexecdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(libexecdir)" && rm -f $$files + +clean-libexecPROGRAMS: + @list='$(libexec_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 +gsd-datetime-mechanism$(EXEEXT): $(gsd_datetime_mechanism_OBJECTS) $(gsd_datetime_mechanism_DEPENDENCIES) + @rm -f gsd-datetime-mechanism$(EXEEXT) + $(LINK) $(gsd_datetime_mechanism_OBJECTS) $(gsd_datetime_mechanism_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsd-datetime-mechanism-main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsd-datetime-mechanism.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/system-timezone.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 $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-dbus_confDATA: $(dbus_conf_DATA) + @$(NORMAL_INSTALL) + test -z "$(dbus_confdir)" || $(MKDIR_P) "$(DESTDIR)$(dbus_confdir)" + @list='$(dbus_conf_DATA)'; test -n "$(dbus_confdir)" || 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)$(dbus_confdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(dbus_confdir)" || exit $$?; \ + done + +uninstall-dbus_confDATA: + @$(NORMAL_UNINSTALL) + @list='$(dbus_conf_DATA)'; test -n "$(dbus_confdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(dbus_confdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(dbus_confdir)" && rm -f $$files +install-dbus_servicesDATA: $(dbus_services_DATA) + @$(NORMAL_INSTALL) + test -z "$(dbus_servicesdir)" || $(MKDIR_P) "$(DESTDIR)$(dbus_servicesdir)" + @list='$(dbus_services_DATA)'; test -n "$(dbus_servicesdir)" || 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)$(dbus_servicesdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(dbus_servicesdir)" || exit $$?; \ + done + +uninstall-dbus_servicesDATA: + @$(NORMAL_UNINSTALL) + @list='$(dbus_services_DATA)'; test -n "$(dbus_servicesdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(dbus_servicesdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(dbus_servicesdir)" && rm -f $$files +install-polkitDATA: $(polkit_DATA) + @$(NORMAL_INSTALL) + test -z "$(polkitdir)" || $(MKDIR_P) "$(DESTDIR)$(polkitdir)" + @list='$(polkit_DATA)'; test -n "$(polkitdir)" || 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)$(polkitdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(polkitdir)" || exit $$?; \ + done + +uninstall-polkitDATA: + @$(NORMAL_UNINSTALL) + @list='$(polkit_DATA)'; test -n "$(polkitdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(polkitdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(polkitdir)" && rm -f $$files + +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: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(PROGRAMS) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(dbus_confdir)" "$(DESTDIR)$(dbus_servicesdir)" "$(DESTDIR)$(polkitdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) 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: + -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) + +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-am + +clean-am: clean-generic clean-libexecPROGRAMS clean-libtool \ + 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-dbus_confDATA install-dbus_servicesDATA \ + install-polkitDATA + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libexecPROGRAMS + +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: uninstall-dbus_confDATA uninstall-dbus_servicesDATA \ + uninstall-libexecPROGRAMS uninstall-polkitDATA + +.MAKE: all check install install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libexecPROGRAMS clean-libtool 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-dbus_confDATA install-dbus_servicesDATA install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am \ + install-libexecPROGRAMS install-man install-pdf install-pdf-am \ + install-polkitDATA 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 uninstall-dbus_confDATA \ + uninstall-dbus_servicesDATA uninstall-libexecPROGRAMS \ + uninstall-polkitDATA + + +gsd-datetime-mechanism-glue.h: $(srcdir)/gsd-datetime-mechanism.xml + $(AM_V_GEN)dbus-binding-tool \ + --prefix=gsd_datetime_mechanism --mode=glib-server \ + --output=gsd-datetime-mechanism-glue.h \ + $(srcdir)/gsd-datetime-mechanism.xml + +@HAVE_POLKIT_TRUE@$(dbus_services_DATA): $(dbus_services_in_files) +@HAVE_POLKIT_TRUE@ $(AM_V_GEN)sed -e "s|\@LIBEXECDIR\@|$(libexecdir)|" $< > $@ + +@HAVE_POLKIT_TRUE@@INTLTOOL_POLICY_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/datetime/gsd-datetime-mechanism-main.c b/plugins/datetime/gsd-datetime-mechanism-main.c new file mode 100644 index 0000000..7d6089f --- /dev/null +++ b/plugins/datetime/gsd-datetime-mechanism-main.c @@ -0,0 +1,171 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 David Zeuthen <[email protected]> + * + * 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. + * + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <signal.h> +#include <errno.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <glib.h> +#include <glib-object.h> + +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> + + +#include "gsd-datetime-mechanism.h" + +static DBusGProxy * +get_bus_proxy (DBusGConnection *connection) +{ + DBusGProxy *bus_proxy; + + bus_proxy = dbus_g_proxy_new_for_name (connection, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS); + return bus_proxy; +} + +#define BUS_NAME "org.mate.SettingsDaemon.DateTimeMechanism" + +static gboolean +acquire_name_on_proxy (DBusGProxy *bus_proxy) +{ + GError *error; + guint result; + gboolean res; + gboolean ret; + + ret = FALSE; + + if (bus_proxy == NULL) { + goto out; + } + + error = NULL; + res = dbus_g_proxy_call (bus_proxy, + "RequestName", + &error, + G_TYPE_STRING, BUS_NAME, + G_TYPE_UINT, 0, + G_TYPE_INVALID, + G_TYPE_UINT, &result, + G_TYPE_INVALID); + if (! res) { + if (error != NULL) { + g_warning ("Failed to acquire %s: %s", BUS_NAME, error->message); + g_error_free (error); + } else { + g_warning ("Failed to acquire %s", BUS_NAME); + } + goto out; + } + + if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { + if (error != NULL) { + g_warning ("Failed to acquire %s: %s", BUS_NAME, error->message); + g_error_free (error); + } else { + g_warning ("Failed to acquire %s", BUS_NAME); + } + goto out; + } + + ret = TRUE; + + out: + return ret; +} + +static DBusGConnection * +get_system_bus (void) +{ + GError *error; + DBusGConnection *bus; + + error = NULL; + bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (bus == NULL) { + g_warning ("Couldn't connect to system bus: %s", error->message); + g_error_free (error); + } + return bus; +} + +int +main (int argc, char **argv) +{ + GMainLoop *loop; + GsdDatetimeMechanism *mechanism; + DBusGProxy *bus_proxy; + DBusGConnection *connection; + int ret; + + ret = 1; + + if (! g_thread_supported ()) { + g_thread_init (NULL); + } + dbus_g_thread_init (); + g_type_init (); + + connection = get_system_bus (); + if (connection == NULL) { + goto out; + } + + bus_proxy = get_bus_proxy (connection); + if (bus_proxy == NULL) { + g_warning ("Could not construct bus_proxy object; bailing out"); + goto out; + } + + if (!acquire_name_on_proxy (bus_proxy) ) { + g_warning ("Could not acquire name; bailing out"); + goto out; + } + + mechanism = gsd_datetime_mechanism_new (); + + if (mechanism == NULL) { + goto out; + } + + loop = g_main_loop_new (NULL, FALSE); + + g_main_loop_run (loop); + + g_object_unref (mechanism); + g_main_loop_unref (loop); + ret = 0; + +out: + return ret; +} diff --git a/plugins/datetime/gsd-datetime-mechanism.c b/plugins/datetime/gsd-datetime-mechanism.c new file mode 100644 index 0000000..5c18040 --- /dev/null +++ b/plugins/datetime/gsd-datetime-mechanism.c @@ -0,0 +1,646 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 David Zeuthen <[email protected]> + * + * 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. + * + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> +#include <sys/wait.h> +#include <errno.h> +#include <sys/time.h> + +#include <glib.h> +#include <glib-object.h> + +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> + +#include <polkit/polkit.h> + +#include "system-timezone.h" + +#include "gsd-datetime-mechanism.h" +#include "gsd-datetime-mechanism-glue.h" + +static gboolean +do_exit (gpointer user_data) +{ + g_debug ("Exiting due to inactivity"); + exit (1); + return FALSE; +} + +static void +reset_killtimer (void) +{ + static guint timer_id = 0; + + if (timer_id > 0) { + g_source_remove (timer_id); + } + g_debug ("Setting killtimer to 30 seconds..."); + timer_id = g_timeout_add_seconds (30, do_exit, NULL); +} + +struct GsdDatetimeMechanismPrivate +{ + DBusGConnection *system_bus_connection; + DBusGProxy *system_bus_proxy; + PolkitAuthority *auth; +}; + +static void gsd_datetime_mechanism_finalize (GObject *object); + +G_DEFINE_TYPE (GsdDatetimeMechanism, gsd_datetime_mechanism, G_TYPE_OBJECT) + +#define GSD_DATETIME_MECHANISM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_DATETIME_TYPE_MECHANISM, GsdDatetimeMechanismPrivate)) + +GQuark +gsd_datetime_mechanism_error_quark (void) +{ + static GQuark ret = 0; + + if (ret == 0) { + ret = g_quark_from_static_string ("gsd_datetime_mechanism_error"); + } + + return ret; +} + + +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +gsd_datetime_mechanism_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) + { + static const GEnumValue values[] = + { + ENUM_ENTRY (GSD_DATETIME_MECHANISM_ERROR_GENERAL, "GeneralError"), + ENUM_ENTRY (GSD_DATETIME_MECHANISM_ERROR_NOT_PRIVILEGED, "NotPrivileged"), + ENUM_ENTRY (GSD_DATETIME_MECHANISM_ERROR_INVALID_TIMEZONE_FILE, "InvalidTimezoneFile"), + { 0, 0, 0 } + }; + + g_assert (GSD_DATETIME_MECHANISM_NUM_ERRORS == G_N_ELEMENTS (values) - 1); + + etype = g_enum_register_static ("GsdDatetimeMechanismError", values); + } + + return etype; +} + + +static GObject * +gsd_datetime_mechanism_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GsdDatetimeMechanism *mechanism; + + mechanism = GSD_DATETIME_MECHANISM (G_OBJECT_CLASS (gsd_datetime_mechanism_parent_class)->constructor ( + type, + n_construct_properties, + construct_properties)); + + return G_OBJECT (mechanism); +} + +static void +gsd_datetime_mechanism_class_init (GsdDatetimeMechanismClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructor = gsd_datetime_mechanism_constructor; + object_class->finalize = gsd_datetime_mechanism_finalize; + + g_type_class_add_private (klass, sizeof (GsdDatetimeMechanismPrivate)); + + dbus_g_object_type_install_info (GSD_DATETIME_TYPE_MECHANISM, &dbus_glib_gsd_datetime_mechanism_object_info); + + dbus_g_error_domain_register (GSD_DATETIME_MECHANISM_ERROR, NULL, GSD_DATETIME_MECHANISM_TYPE_ERROR); + +} + +static void +gsd_datetime_mechanism_init (GsdDatetimeMechanism *mechanism) +{ + mechanism->priv = GSD_DATETIME_MECHANISM_GET_PRIVATE (mechanism); + +} + +static void +gsd_datetime_mechanism_finalize (GObject *object) +{ + GsdDatetimeMechanism *mechanism; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_DATETIME_IS_MECHANISM (object)); + + mechanism = GSD_DATETIME_MECHANISM (object); + + g_return_if_fail (mechanism->priv != NULL); + + g_object_unref (mechanism->priv->system_bus_proxy); + + G_OBJECT_CLASS (gsd_datetime_mechanism_parent_class)->finalize (object); +} + +static gboolean +register_mechanism (GsdDatetimeMechanism *mechanism) +{ + GError *error = NULL; + + mechanism->priv->auth = polkit_authority_get (); + + error = NULL; + mechanism->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (mechanism->priv->system_bus_connection == NULL) { + if (error != NULL) { + g_critical ("error getting system bus: %s", error->message); + g_error_free (error); + } + goto error; + } + + dbus_g_connection_register_g_object (mechanism->priv->system_bus_connection, "/", + G_OBJECT (mechanism)); + + mechanism->priv->system_bus_proxy = dbus_g_proxy_new_for_name (mechanism->priv->system_bus_connection, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS); + + reset_killtimer (); + + return TRUE; + +error: + return FALSE; +} + + +GsdDatetimeMechanism * +gsd_datetime_mechanism_new (void) +{ + GObject *object; + gboolean res; + + object = g_object_new (GSD_DATETIME_TYPE_MECHANISM, NULL); + + res = register_mechanism (GSD_DATETIME_MECHANISM (object)); + if (! res) { + g_object_unref (object); + return NULL; + } + + return GSD_DATETIME_MECHANISM (object); +} + +static gboolean +_check_polkit_for_action (GsdDatetimeMechanism *mechanism, DBusGMethodInvocation *context, const char *action) +{ + const char *sender; + GError *error; + PolkitSubject *subject; + PolkitAuthorizationResult *result; + + error = NULL; + + /* Check that caller is privileged */ + sender = dbus_g_method_get_sender (context); + subject = polkit_system_bus_name_new (sender); + + result = polkit_authority_check_authorization_sync (mechanism->priv->auth, + subject, + action, + NULL, + POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, + NULL, &error); + g_object_unref (subject); + + if (error) { + dbus_g_method_return_error (context, error); + g_error_free (error); + + return FALSE; + } + + if (!polkit_authorization_result_get_is_authorized (result)) { + error = g_error_new (GSD_DATETIME_MECHANISM_ERROR, + GSD_DATETIME_MECHANISM_ERROR_NOT_PRIVILEGED, + "Not Authorized for action %s", action); + dbus_g_method_return_error (context, error); + g_error_free (error); + g_object_unref (result); + + return FALSE; + } + + g_object_unref (result); + + return TRUE; +} + + +static gboolean +_set_time (GsdDatetimeMechanism *mechanism, + const struct timeval *tv, + DBusGMethodInvocation *context) +{ + GError *error; + + if (!_check_polkit_for_action (mechanism, context, "org.mate.settingsdaemon.datetimemechanism.settime")) + return FALSE; + + if (settimeofday (tv, NULL) != 0) { + error = g_error_new (GSD_DATETIME_MECHANISM_ERROR, + GSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Error calling settimeofday({%lld,%lld}): %s", + (gint64) tv->tv_sec, (gint64) tv->tv_usec, + strerror (errno)); + dbus_g_method_return_error (context, error); + g_error_free (error); + return FALSE; + } + + if (g_file_test ("/sbin/hwclock", + G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_EXECUTABLE)) { + int exit_status; + if (!g_spawn_command_line_sync ("/sbin/hwclock --systohc", NULL, NULL, &exit_status, &error)) { + GError *error2; + error2 = g_error_new (GSD_DATETIME_MECHANISM_ERROR, + GSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Error spawning /sbin/hwclock: %s", error->message); + g_error_free (error); + dbus_g_method_return_error (context, error2); + g_error_free (error2); + return FALSE; + } + if (WEXITSTATUS (exit_status) != 0) { + error = g_error_new (GSD_DATETIME_MECHANISM_ERROR, + GSD_DATETIME_MECHANISM_ERROR_GENERAL, + "/sbin/hwclock returned %d", exit_status); + dbus_g_method_return_error (context, error); + g_error_free (error); + return FALSE; + } + } + + dbus_g_method_return (context); + return TRUE; +} + +static gboolean +_rh_update_etc_sysconfig_clock (DBusGMethodInvocation *context, const char *key, const char *value) +{ + /* On Red Hat / Fedora, the /etc/sysconfig/clock file needs to be kept in sync */ + if (g_file_test ("/etc/sysconfig/clock", G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) { + char **lines; + int n; + gboolean replaced; + char *data; + gsize len; + GError *error; + + error = NULL; + + if (!g_file_get_contents ("/etc/sysconfig/clock", &data, &len, &error)) { + GError *error2; + error2 = g_error_new (GSD_DATETIME_MECHANISM_ERROR, + GSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Error reading /etc/sysconfig/clock file: %s", error->message); + g_error_free (error); + dbus_g_method_return_error (context, error2); + g_error_free (error2); + return FALSE; + } + replaced = FALSE; + lines = g_strsplit (data, "\n", 0); + g_free (data); + + for (n = 0; lines[n] != NULL; n++) { + if (g_str_has_prefix (lines[n], key)) { + g_free (lines[n]); + lines[n] = g_strdup_printf ("%s%s", key, value); + replaced = TRUE; + } + } + if (replaced) { + GString *str; + + str = g_string_new (NULL); + for (n = 0; lines[n] != NULL; n++) { + g_string_append (str, lines[n]); + if (lines[n + 1] != NULL) + g_string_append_c (str, '\n'); + } + data = g_string_free (str, FALSE); + len = strlen (data); + if (!g_file_set_contents ("/etc/sysconfig/clock", data, len, &error)) { + GError *error2; + error2 = g_error_new (GSD_DATETIME_MECHANISM_ERROR, + GSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Error updating /etc/sysconfig/clock: %s", error->message); + g_error_free (error); + dbus_g_method_return_error (context, error2); + g_error_free (error2); + g_free (data); + return FALSE; + } + g_free (data); + } + g_strfreev (lines); + } + + return TRUE; +} + +/* exported methods */ + +gboolean +gsd_datetime_mechanism_set_time (GsdDatetimeMechanism *mechanism, + gint64 seconds_since_epoch, + DBusGMethodInvocation *context) +{ + struct timeval tv; + + reset_killtimer (); + g_debug ("SetTime(%lld) called", seconds_since_epoch); + + tv.tv_sec = (time_t) seconds_since_epoch; + tv.tv_usec = 0; + return _set_time (mechanism, &tv, context); +} + +gboolean +gsd_datetime_mechanism_adjust_time (GsdDatetimeMechanism *mechanism, + gint64 seconds_to_add, + DBusGMethodInvocation *context) +{ + struct timeval tv; + + reset_killtimer (); + g_debug ("AdjustTime(%lld) called", seconds_to_add); + + if (gettimeofday (&tv, NULL) != 0) { + GError *error; + error = g_error_new (GSD_DATETIME_MECHANISM_ERROR, + GSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Error calling gettimeofday(): %s", strerror (errno)); + dbus_g_method_return_error (context, error); + g_error_free (error); + return FALSE; + } + + tv.tv_sec += (time_t) seconds_to_add; + return _set_time (mechanism, &tv, context); +} + + +gboolean +gsd_datetime_mechanism_set_timezone (GsdDatetimeMechanism *mechanism, + const char *zone_file, + DBusGMethodInvocation *context) +{ + GError *error; + + reset_killtimer (); + g_debug ("SetTimezone('%s') called", zone_file); + + if (!_check_polkit_for_action (mechanism, context, "org.mate.settingsdaemon.datetimemechanism.settimezone")) + return FALSE; + + error = NULL; + + if (!system_timezone_set_from_file (zone_file, &error)) { + GError *error2; + int code; + + if (error->code == SYSTEM_TIMEZONE_ERROR_INVALID_TIMEZONE_FILE) + code = GSD_DATETIME_MECHANISM_ERROR_INVALID_TIMEZONE_FILE; + else + code = GSD_DATETIME_MECHANISM_ERROR_GENERAL; + + error2 = g_error_new (GSD_DATETIME_MECHANISM_ERROR, + code, "%s", error->message); + + g_error_free (error); + + dbus_g_method_return_error (context, error2); + g_error_free (error2); + + return FALSE; + } + + dbus_g_method_return (context); + return TRUE; +} + + +gboolean +gsd_datetime_mechanism_get_timezone (GsdDatetimeMechanism *mechism, + DBusGMethodInvocation *context) +{ + gchar *timezone; + + reset_killtimer (); + + timezone = system_timezone_find (); + + dbus_g_method_return (context, timezone); + + return TRUE; +} + +gboolean +gsd_datetime_mechanism_get_hardware_clock_using_utc (GsdDatetimeMechanism *mechanism, + DBusGMethodInvocation *context) +{ + char **lines; + char *data; + gsize len; + GError *error; + gboolean is_utc; + + error = NULL; + + if (!g_file_get_contents ("/etc/adjtime", &data, &len, &error)) { + GError *error2; + error2 = g_error_new (GSD_DATETIME_MECHANISM_ERROR, + GSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Error reading /etc/adjtime file: %s", error->message); + g_error_free (error); + dbus_g_method_return_error (context, error2); + g_error_free (error2); + return FALSE; + } + + lines = g_strsplit (data, "\n", 0); + g_free (data); + + if (g_strv_length (lines) < 3) { + error = g_error_new (GSD_DATETIME_MECHANISM_ERROR, + GSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Cannot parse /etc/adjtime"); + dbus_g_method_return_error (context, error); + g_error_free (error); + g_strfreev (lines); + return FALSE; + } + + if (strcmp (lines[2], "UTC") == 0) { + is_utc = TRUE; + } else if (strcmp (lines[2], "LOCAL") == 0) { + is_utc = FALSE; + } else { + error = g_error_new (GSD_DATETIME_MECHANISM_ERROR, + GSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Expected UTC or LOCAL at line 3 of /etc/adjtime; found '%s'", lines[2]); + dbus_g_method_return_error (context, error); + g_error_free (error); + g_strfreev (lines); + return FALSE; + } + g_strfreev (lines); + dbus_g_method_return (context, is_utc); + return TRUE; +} + +gboolean +gsd_datetime_mechanism_set_hardware_clock_using_utc (GsdDatetimeMechanism *mechanism, + gboolean using_utc, + DBusGMethodInvocation *context) +{ + GError *error; + + error = NULL; + + if (!_check_polkit_for_action (mechanism, context, + "org.mate.settingsdaemon.datetimemechanism.configurehwclock")) + return FALSE; + + if (g_file_test ("/sbin/hwclock", + G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_EXECUTABLE)) { + int exit_status; + char *cmd; + cmd = g_strdup_printf ("/sbin/hwclock %s --systohc", using_utc ? "--utc" : "--localtime"); + if (!g_spawn_command_line_sync (cmd, NULL, NULL, &exit_status, &error)) { + GError *error2; + error2 = g_error_new (GSD_DATETIME_MECHANISM_ERROR, + GSD_DATETIME_MECHANISM_ERROR_GENERAL, + "Error spawning /sbin/hwclock: %s", error->message); + g_error_free (error); + dbus_g_method_return_error (context, error2); + g_error_free (error2); + g_free (cmd); + return FALSE; + } + g_free (cmd); + if (WEXITSTATUS (exit_status) != 0) { + error = g_error_new (GSD_DATETIME_MECHANISM_ERROR, + GSD_DATETIME_MECHANISM_ERROR_GENERAL, + "/sbin/hwclock returned %d", exit_status); + dbus_g_method_return_error (context, error); + g_error_free (error); + return FALSE; + } + + if (!_rh_update_etc_sysconfig_clock (context, "UTC=", using_utc ? "true" : "false")) + return FALSE; + + } + dbus_g_method_return (context); + return TRUE; +} + +static void +check_can_do (GsdDatetimeMechanism *mechanism, + const char *action, + DBusGMethodInvocation *context) +{ + const char *sender; + PolkitSubject *subject; + PolkitAuthorizationResult *result; + GError *error; + + /* Check that caller is privileged */ + sender = dbus_g_method_get_sender (context); + subject = polkit_system_bus_name_new (sender); + + error = NULL; + result = polkit_authority_check_authorization_sync (mechanism->priv->auth, + subject, + action, + NULL, + 0, + NULL, + &error); + g_object_unref (subject); + + if (error) { + dbus_g_method_return_error (context, error); + g_error_free (error); + return; + } + + if (polkit_authorization_result_get_is_authorized (result)) { + dbus_g_method_return (context, 2); + } + else if (polkit_authorization_result_get_is_challenge (result)) { + dbus_g_method_return (context, 1); + } + else { + dbus_g_method_return (context, 0); + } + + g_object_unref (result); +} + + +gboolean +gsd_datetime_mechanism_can_set_time (GsdDatetimeMechanism *mechanism, + DBusGMethodInvocation *context) +{ + check_can_do (mechanism, + "org.mate.settingsdaemon.datetimemechanism.settime", + context); + + return TRUE; +} + +gboolean +gsd_datetime_mechanism_can_set_timezone (GsdDatetimeMechanism *mechanism, + DBusGMethodInvocation *context) +{ + check_can_do (mechanism, + "org.mate.settingsdaemon.datetimemechanism.settimezone", + context); + + return TRUE; +} diff --git a/plugins/datetime/gsd-datetime-mechanism.h b/plugins/datetime/gsd-datetime-mechanism.h new file mode 100644 index 0000000..52b3b02 --- /dev/null +++ b/plugins/datetime/gsd-datetime-mechanism.h @@ -0,0 +1,101 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 David Zeuthen <[email protected]> + * + * 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_DATETIME_MECHANISM_H +#define GSD_DATETIME_MECHANISM_H + +#include <glib-object.h> +#include <dbus/dbus-glib.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_DATETIME_TYPE_MECHANISM (gsd_datetime_mechanism_get_type ()) +#define GSD_DATETIME_MECHANISM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_DATETIME_TYPE_MECHANISM, GsdDatetimeMechanism)) +#define GSD_DATETIME_MECHANISM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_DATETIME_TYPE_MECHANISM, GsdDatetimeMechanismClass)) +#define GSD_DATETIME_IS_MECHANISM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_DATETIME_TYPE_MECHANISM)) +#define GSD_DATETIME_IS_MECHANISM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_DATETIME_TYPE_MECHANISM)) +#define GSD_DATETIME_MECHANISM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_DATETIME_TYPE_MECHANISM, GsdDatetimeMechanismClass)) + +typedef struct GsdDatetimeMechanismPrivate GsdDatetimeMechanismPrivate; + +typedef struct +{ + GObject parent; + GsdDatetimeMechanismPrivate *priv; +} GsdDatetimeMechanism; + +typedef struct +{ + GObjectClass parent_class; +} GsdDatetimeMechanismClass; + +typedef enum +{ + GSD_DATETIME_MECHANISM_ERROR_GENERAL, + GSD_DATETIME_MECHANISM_ERROR_NOT_PRIVILEGED, + GSD_DATETIME_MECHANISM_ERROR_INVALID_TIMEZONE_FILE, + GSD_DATETIME_MECHANISM_NUM_ERRORS +} GsdDatetimeMechanismError; + +#define GSD_DATETIME_MECHANISM_ERROR gsd_datetime_mechanism_error_quark () + +GType gsd_datetime_mechanism_error_get_type (void); +#define GSD_DATETIME_MECHANISM_TYPE_ERROR (gsd_datetime_mechanism_error_get_type ()) + + +GQuark gsd_datetime_mechanism_error_quark (void); +GType gsd_datetime_mechanism_get_type (void); +GsdDatetimeMechanism *gsd_datetime_mechanism_new (void); + +/* exported methods */ +gboolean gsd_datetime_mechanism_get_timezone (GsdDatetimeMechanism *mechanism, + DBusGMethodInvocation *context); +gboolean gsd_datetime_mechanism_set_timezone (GsdDatetimeMechanism *mechanism, + const char *zone_file, + DBusGMethodInvocation *context); + +gboolean gsd_datetime_mechanism_can_set_timezone (GsdDatetimeMechanism *mechanism, + DBusGMethodInvocation *context); + +gboolean gsd_datetime_mechanism_set_time (GsdDatetimeMechanism *mechanism, + gint64 seconds_since_epoch, + DBusGMethodInvocation *context); + +gboolean gsd_datetime_mechanism_can_set_time (GsdDatetimeMechanism *mechanism, + DBusGMethodInvocation *context); + +gboolean gsd_datetime_mechanism_adjust_time (GsdDatetimeMechanism *mechanism, + gint64 seconds_to_add, + DBusGMethodInvocation *context); + +gboolean gsd_datetime_mechanism_get_hardware_clock_using_utc (GsdDatetimeMechanism *mechanism, + DBusGMethodInvocation *context); + +gboolean gsd_datetime_mechanism_set_hardware_clock_using_utc (GsdDatetimeMechanism *mechanism, + gboolean using_utc, + DBusGMethodInvocation *context); + +#ifdef __cplusplus +} +#endif + +#endif /* GSD_DATETIME_MECHANISM_H */ diff --git a/plugins/datetime/gsd-datetime-mechanism.xml b/plugins/datetime/gsd-datetime-mechanism.xml new file mode 100644 index 0000000..1962235 --- /dev/null +++ b/plugins/datetime/gsd-datetime-mechanism.xml @@ -0,0 +1,87 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node name="/"> + <interface name="org.mate.SettingsDaemon.DateTimeMechanism"> + <method name="SetTimezone"> + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> + <arg name="zonefile" direction="in" type="s"/> + </method> + + <method name="GetTimezone"> + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> + <arg name="timezone" direction="out" type="s"/> + </method> + + <method name="CanSetTimezone"> + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> + <arg name="value" direction="out" type="i"> + <doc:doc> + <doc:summary>Whether the caller can set the timezone</doc:summary> + <doc:description> + <doc:para> + The return value is not a boolean, but an integer with the following meaning: + <doc:list> + <doc:item> + <doc:term>0</doc:term> + <doc:definition>the caller cannot set the timezone</doc:definition> + </doc:item> + <doc:item> + <doc:term>1</doc:term> + <doc:definition>the caller will be challenged before being able to set the timezone</doc:definition> + </doc:item> + <doc:item> + <doc:term>2</doc:term> + <doc:definition>the caller is authorized to set the timezone</doc:definition> + </doc:item> + </doc:list> + </doc:para> + </doc:description> + </doc:doc> + </arg> + </method> + <method name="SetTime"> + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> + <arg name="seconds_since_epoch" direction="in" type="x"/> + </method> + <method name="CanSetTime"> + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> + <arg name="value" direction="out" type="i"> + <doc:doc> + <doc:summary>Whether the caller can set the time</doc:summary> + <doc:description> + <doc:para> + The return value is not a boolean, but an integer with the following meaning: + <doc:list> + <doc:item> + <doc:term>0</doc:term> + <doc:definition>the caller cannot set the time</doc:definition> + </doc:item> + <doc:item> + <doc:term>1</doc:term> + <doc:definition>the caller will be challenged before being able to set the time</doc:definition> + </doc:item> + <doc:item> + <doc:term>2</doc:term> + <doc:definition>the caller is authorized to set the time</doc:definition> + </doc:item> + </doc:list> + </doc:para> + </doc:description> + </doc:doc> + </arg> + </method> + <method name="AdjustTime"> + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> + <arg name="seconds_to_add" direction="in" type="x"/> + </method> + + <method name="GetHardwareClockUsingUtc"> + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> + <arg name="is_using_utc" direction="out" type="b"/> + </method> + <method name="SetHardwareClockUsingUtc"> + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/> + <arg name="is_using_utc" direction="in" type="b"/> + </method> + + </interface> +</node> diff --git a/plugins/datetime/org.mate.SettingsDaemon.DateTimeMechanism.conf b/plugins/datetime/org.mate.SettingsDaemon.DateTimeMechanism.conf new file mode 100644 index 0000000..c861ace --- /dev/null +++ b/plugins/datetime/org.mate.SettingsDaemon.DateTimeMechanism.conf @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- --> + +<!DOCTYPE busconfig PUBLIC + "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + + <!-- Only root can own the service --> + <policy user="root"> + <allow own="org.mate.SettingsDaemon.DateTimeMechanism"/> + <allow send_destination="org.mate.SettingsDaemon.DateTimeMechanism"/> + </policy> + + <!-- Allow anyone to invoke methods on the interfaces --> + <policy context="default"> + <allow send_destination="org.mate.SettingsDaemon.DateTimeMechanism"/> + </policy> + +</busconfig> diff --git a/plugins/datetime/org.mate.SettingsDaemon.DateTimeMechanism.service.in b/plugins/datetime/org.mate.SettingsDaemon.DateTimeMechanism.service.in new file mode 100644 index 0000000..ac7fa29 --- /dev/null +++ b/plugins/datetime/org.mate.SettingsDaemon.DateTimeMechanism.service.in @@ -0,0 +1,4 @@ +[D-BUS Service] +Name=org.mate.SettingsDaemon.DateTimeMechanism +Exec=@LIBEXECDIR@/gsd-datetime-mechanism +User=root diff --git a/plugins/datetime/org.mate.settingsdaemon.datetimemechanism.policy.in b/plugins/datetime/org.mate.settingsdaemon.datetimemechanism.policy.in new file mode 100644 index 0000000..3fb688e --- /dev/null +++ b/plugins/datetime/org.mate.settingsdaemon.datetimemechanism.policy.in @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE policyconfig PUBLIC + "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" + "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd"> + +<policyconfig> + <vendor>The MATE Project</vendor> + <vendor_url>http://www.gnome.org/</vendor_url> + <icon_name>mate-panel-clock</icon_name> + + <action id="org.mate.settingsdaemon.datetimemechanism.settimezone"> + <_description>Change system time zone</_description> + <_message>Privileges are required to change the system time zone.</_message> + <defaults> + <allow_inactive>no</allow_inactive> + <allow_active>auth_self_keep</allow_active> + </defaults> + </action> + + <action id="org.mate.settingsdaemon.datetimemechanism.settime"> + <_description>Change system time</_description> + <_message>Privileges are required to change the system time.</_message> + <defaults> + <allow_inactive>no</allow_inactive> + <allow_active>auth_admin_keep</allow_active> + </defaults> + </action> + + <action id="org.mate.settingsdaemon.datetimemechanism.configurehwclock"> + <_description>Configure hardware clock</_description> + <_message>Privileges are required to configure the hardware clock.</_message> + <defaults> + <allow_inactive>no</allow_inactive> + <allow_active>auth_admin_keep</allow_active> + </defaults> + </action> + +</policyconfig> diff --git a/plugins/datetime/system-timezone.c b/plugins/datetime/system-timezone.c new file mode 100644 index 0000000..43add01 --- /dev/null +++ b/plugins/datetime/system-timezone.c @@ -0,0 +1,1047 @@ +/* System timezone handling + * + * Copyright (C) 2008 Novell, Inc. + * + * Authors: Vincent Untz <[email protected]> + * + * 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. + * + * Some code is based on previous code in clock-location.c and on code from + * tz.c (shipped with version <= 2.22.0). Those files were under the same + * license, with those authors and copyrights: + * + * clock-location.c: + * ================ + * No header, but most of the work was done (AFAIK) by + * Federico Mena Quintero <[email protected]> + * Matthias Clasen <[email protected]> + * + * tz.c: + * ==== + * Copyright (C) 2000-2001 Ximian, Inc. + * Copyright (C) 2004 Sun Microsystems, Inc. + * + * Authors: Hans Petter Jansson <[email protected]> + * additional functions by Erwann Chenede <[email protected]> + * reworked by Vincent Untz <[email protected]> + * + * Largely based on Michael Fulbright's work on Anaconda. + */ + +/* FIXME: it'd be nice to filter out the timezones that we might get when + * parsing config files that are not in zone.tab. Note that it's also wrong + * in some cases: eg, in tzdata2008b, Asia/Calcutta got renamed to + * Asia/Kolkata and the old name is not in zone.tab. */ + +#include <string.h> +#include <unistd.h> + +#include <glib.h> +#include <glib/gstdio.h> +#include <gio/gio.h> + +#include "system-timezone.h" + +/* Files that we look at and that should be monitored */ +#define CHECK_NB 5 +#define ETC_TIMEZONE "/etc/timezone" +#define ETC_TIMEZONE_MAJ "/etc/TIMEZONE" +#define ETC_RC_CONF "/etc/rc.conf" +#define ETC_SYSCONFIG_CLOCK "/etc/sysconfig/clock" +#define ETC_CONF_D_CLOCK "/etc/conf.d/clock" +#define ETC_LOCALTIME "/etc/localtime" + +/* The first 4 characters in a timezone file, from tzfile.h */ +#define TZ_MAGIC "TZif" + +static char *files_to_check[CHECK_NB] = { + ETC_TIMEZONE, + ETC_TIMEZONE_MAJ, + ETC_SYSCONFIG_CLOCK, + ETC_CONF_D_CLOCK, + ETC_LOCALTIME +}; + +static GObject *systz_singleton = NULL; + +G_DEFINE_TYPE (SystemTimezone, system_timezone, G_TYPE_OBJECT) + +typedef struct { + char *tz; + char *env_tz; + GFileMonitor *monitors[CHECK_NB]; +} SystemTimezonePrivate; + +enum { + CHANGED, + LAST_SIGNAL +}; + +static guint system_timezone_signals[LAST_SIGNAL] = { 0 }; + +static GObject *system_timezone_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties); +static void system_timezone_finalize (GObject *obj); + +static void system_timezone_monitor_changed (GFileMonitor *handle, + GFile *file, + GFile *other_file, + GFileMonitorEvent event, + gpointer user_data); + +#define PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SYSTEM_TIMEZONE_TYPE, SystemTimezonePrivate)) + +SystemTimezone * +system_timezone_new (void) +{ + return g_object_new (SYSTEM_TIMEZONE_TYPE, NULL); +} + +const char * +system_timezone_get (SystemTimezone *systz) +{ + SystemTimezonePrivate *priv; + + g_return_val_if_fail (IS_SYSTEM_TIMEZONE (systz), NULL); + + priv = PRIVATE (systz); + return priv->tz; +} + +const char * +system_timezone_get_env (SystemTimezone *systz) +{ + SystemTimezonePrivate *priv; + + g_return_val_if_fail (IS_SYSTEM_TIMEZONE (systz), NULL); + + priv = PRIVATE (systz); + return priv->env_tz; +} + +static void +system_timezone_class_init (SystemTimezoneClass *class) +{ + GObjectClass *g_obj_class = G_OBJECT_CLASS (class); + + g_obj_class->constructor = system_timezone_constructor; + g_obj_class->finalize = system_timezone_finalize; + + system_timezone_signals[CHANGED] = + g_signal_new ("changed", + G_OBJECT_CLASS_TYPE (g_obj_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (SystemTimezoneClass, changed), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); + + g_type_class_add_private (class, sizeof (SystemTimezonePrivate)); +} + +static void +system_timezone_init (SystemTimezone *systz) +{ + int i; + SystemTimezonePrivate *priv = PRIVATE (systz); + + priv->tz = NULL; + priv->env_tz = NULL; + for (i = 0; i < CHECK_NB; i++) + priv->monitors[i] = NULL; +} + +static GObject * +system_timezone_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GObject *obj; + SystemTimezonePrivate *priv; + int i; + + /* This is a singleton, we don't need to have it per-applet */ + if (systz_singleton) + return g_object_ref (systz_singleton); + + obj = G_OBJECT_CLASS (system_timezone_parent_class)->constructor ( + type, + n_construct_properties, + construct_properties); + + priv = PRIVATE (obj); + + priv->tz = system_timezone_find (); + + priv->env_tz = g_strdup (g_getenv ("TZ")); + + for (i = 0; i < CHECK_NB; i++) { + GFile *file; + GFile *parent; + GFileType parent_type; + + file = g_file_new_for_path (files_to_check[i]); + + parent = g_file_get_parent (file); + parent_type = g_file_query_file_type (parent, G_FILE_QUERY_INFO_NONE, NULL); + g_object_unref (parent); + + /* We don't try to monitor the file if the parent directory + * doesn't exist: this means we're on a system where this file + * is not useful to determine the system timezone. + * Since gio does not monitor file in non-existing directories + * in a clever way (as of gio 2.22, it just polls every other + * seconds to see if the directory now exists), this avoids + * unnecessary wakeups. */ + if (parent_type == G_FILE_TYPE_DIRECTORY) + priv->monitors[i] = g_file_monitor_file (file, + G_FILE_MONITOR_NONE, + NULL, NULL); + g_object_unref (file); + + if (priv->monitors[i]) + g_signal_connect (G_OBJECT (priv->monitors[i]), + "changed", + G_CALLBACK (system_timezone_monitor_changed), + obj); + } + + systz_singleton = obj; + + return systz_singleton; +} + +static void +system_timezone_finalize (GObject *obj) +{ + int i; + SystemTimezonePrivate *priv = PRIVATE (obj); + + if (priv->tz) { + g_free (priv->tz); + priv->tz = NULL; + } + + if (priv->env_tz) { + g_free (priv->env_tz); + priv->env_tz = NULL; + } + + for (i = 0; i < CHECK_NB; i++) { + if (priv->monitors[i]) + g_object_unref (priv->monitors[i]); + priv->monitors[i] = NULL; + } + + G_OBJECT_CLASS (system_timezone_parent_class)->finalize (obj); + + g_assert (obj == systz_singleton); + + systz_singleton = NULL; +} + +static void +system_timezone_monitor_changed (GFileMonitor *handle, + GFile *file, + GFile *other_file, + GFileMonitorEvent event, + gpointer user_data) +{ + SystemTimezonePrivate *priv = PRIVATE (user_data); + char *new_tz; + + if (event != G_FILE_MONITOR_EVENT_CHANGED && + event != G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT && + event != G_FILE_MONITOR_EVENT_DELETED && + event != G_FILE_MONITOR_EVENT_CREATED) + return; + + new_tz = system_timezone_find (); + + g_assert (priv->tz != NULL && new_tz != NULL); + + if (strcmp (priv->tz, new_tz) != 0) { + g_free (priv->tz); + priv->tz = new_tz; + + g_signal_emit (G_OBJECT (user_data), + system_timezone_signals[CHANGED], + 0, priv->tz); + } else + g_free (new_tz); +} + + +/* + * Code to deal with the system timezone on all distros. + * There's no dependency on the SystemTimezone GObject here. + * + * Here's what we know: + * + * + /etc/localtime contains the binary data of the timezone. + * It can be a symlink to the actual data file, a hard link to the data + * file, or just a copy. So we can determine the timezone with this + * (reading the symlink, comparing inodes, or comparing content). + * + * + However, most distributions also have the timezone setting + * configured somewhere else. This might be better to read it from there. + * + * Debian/Ubuntu/Gentoo (new): content of /etc/timezone + * Fedora/Mandriva: the ZONE key in /etc/sysconfig/clock + * openSUSE: the TIMEZONE key in /etc/sysconfig/clock + * Solaris/OpenSolaris: the TZ key in /etc/TIMEZONE + * Arch Linux: the TIMEZONE key in /etc/rc.conf + * Gentoo (old): the ZONE key in /etc/conf.d/clock + * + * FIXME: reading the system-tools-backends, it seems there's this too: + * Solaris: the TZ key in /etc/default/init + * /etc/TIMEZONE seems to be a link to /etc/default/init + * + * First, some functions to handle those system config files. + * + */ + +/* This works for Debian and derivatives (including Ubuntu), and new Gentoo */ +static char * +system_timezone_read_etc_timezone (void) +{ + FILE *etc_timezone; + GString *reading; + int c; + + etc_timezone = g_fopen (ETC_TIMEZONE, "r"); + if (!etc_timezone) + return NULL; + + reading = g_string_new (""); + + c = fgetc (etc_timezone); + /* only get the first line, we'll validate the value later */ + while (c != EOF && !g_ascii_isspace (c)) { + reading = g_string_append_c (reading, c); + c = fgetc (etc_timezone); + } + + fclose (etc_timezone); + + if (reading->str && reading->str[0] != '\0') + return g_string_free (reading, FALSE); + else + g_string_free (reading, TRUE); + + return NULL; +} + +static gboolean +system_timezone_write_etc_timezone (const char *tz, + GError **error) +{ + char *content; + GError *our_error; + gboolean retval; + + if (!g_file_test (ETC_TIMEZONE, G_FILE_TEST_IS_REGULAR)) + return TRUE; + + content = g_strdup_printf ("%s\n", tz); + + our_error = NULL; + retval = g_file_set_contents (ETC_TIMEZONE, content, -1, &our_error); + g_free (content); + + if (!retval) { + g_set_error (error, SYSTEM_TIMEZONE_ERROR, + SYSTEM_TIMEZONE_ERROR_GENERAL, + ETC_TIMEZONE" cannot be overwritten: %s", + our_error->message); + g_error_free (our_error); + } + + return retval; +} + + +/* Read a file that looks like a key-file (but there's no need for groups) + * and get the last value for a specific key */ +static char * +system_timezone_read_key_file (const char *filename, + const char *key) +{ + GIOChannel *channel; + char *key_eq; + char *line; + char *retval; + + if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) + return NULL; + + channel = g_io_channel_new_file (filename, "r", NULL); + if (!channel) + return NULL; + + key_eq = g_strdup_printf ("%s=", key); + retval = NULL; + + while (g_io_channel_read_line (channel, &line, NULL, + NULL, NULL) == G_IO_STATUS_NORMAL) { + if (g_str_has_prefix (line, key_eq)) { + char *value; + int len; + + value = line + strlen (key_eq); + g_strstrip (value); + + len = strlen (value); + + if (value[0] == '\"') { + if (value[len - 1] == '\"') { + if (retval) + g_free (retval); + + retval = g_strndup (value + 1, + len - 2); + } + } else { + if (retval) + g_free (retval); + + retval = g_strdup (line + strlen (key_eq)); + } + + g_strstrip (retval); + } + + g_free (line); + } + + g_free (key_eq); + g_io_channel_unref (channel); + + return retval; +} + +static gboolean +system_timezone_write_key_file (const char *filename, + const char *key, + const char *value, + GError **error) +{ + GError *our_error; + char *content; + gsize len; + char *key_eq; + char **lines; + gboolean replaced; + gboolean retval; + int n; + + if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR)) + return TRUE; + + our_error = NULL; + + if (!g_file_get_contents (filename, &content, &len, &our_error)) { + g_set_error (error, SYSTEM_TIMEZONE_ERROR, + SYSTEM_TIMEZONE_ERROR_GENERAL, + "%s cannot be read: %s", + filename, our_error->message); + g_error_free (our_error); + return FALSE; + } + + lines = g_strsplit (content, "\n", 0); + g_free (content); + + key_eq = g_strdup_printf ("%s=", key); + replaced = FALSE; + + for (n = 0; lines[n] != NULL; n++) { + if (g_str_has_prefix (lines[n], key_eq)) { + char *old_value; + gboolean use_quotes; + + old_value = lines[n] + strlen (key_eq); + g_strstrip (old_value); + use_quotes = old_value[0] == '\"'; + + g_free (lines[n]); + + if (use_quotes) + lines[n] = g_strdup_printf ("%s\"%s\"", + key_eq, value); + else + lines[n] = g_strdup_printf ("%s%s", + key_eq, value); + + replaced = TRUE; + } + } + + g_free (key_eq); + + if (!replaced) { + g_strfreev (lines); + return TRUE; + } + + content = g_strjoinv ("\n", lines); + g_strfreev (lines); + + retval = g_file_set_contents (filename, content, -1, &our_error); + g_free (content); + + if (!retval) { + g_set_error (error, SYSTEM_TIMEZONE_ERROR, + SYSTEM_TIMEZONE_ERROR_GENERAL, + "%s cannot be overwritten: %s", + filename, our_error->message); + g_error_free (our_error); + } + + return retval; +} + +/* This works for Solaris/OpenSolaris */ +static char * +system_timezone_read_etc_TIMEZONE (void) +{ + return system_timezone_read_key_file (ETC_TIMEZONE_MAJ, + "TZ"); +} + +static gboolean +system_timezone_write_etc_TIMEZONE (const char *tz, + GError **error) +{ + return system_timezone_write_key_file (ETC_TIMEZONE_MAJ, + "TZ", tz, error); +} + +/* This works for Fedora and Mandriva */ +static char * +system_timezone_read_etc_sysconfig_clock (void) +{ + return system_timezone_read_key_file (ETC_SYSCONFIG_CLOCK, + "ZONE"); +} + +static gboolean +system_timezone_write_etc_sysconfig_clock (const char *tz, + GError **error) +{ + return system_timezone_write_key_file (ETC_SYSCONFIG_CLOCK, + "ZONE", tz, error); +} + +/* This works for openSUSE */ +static char * +system_timezone_read_etc_sysconfig_clock_alt (void) +{ + return system_timezone_read_key_file (ETC_SYSCONFIG_CLOCK, + "TIMEZONE"); +} + +static gboolean +system_timezone_write_etc_sysconfig_clock_alt (const char *tz, + GError **error) +{ + return system_timezone_write_key_file (ETC_SYSCONFIG_CLOCK, + "TIMEZONE", tz, error); +} + +/* This works for old Gentoo */ +static char * +system_timezone_read_etc_conf_d_clock (void) +{ + return system_timezone_read_key_file (ETC_CONF_D_CLOCK, + "TIMEZONE"); +} + +static gboolean +system_timezone_write_etc_conf_d_clock (const char *tz, + GError **error) +{ + return system_timezone_write_key_file (ETC_CONF_D_CLOCK, + "TIMEZONE", tz, error); +} + +/* This works for Arch Linux */ +static char * +system_timezone_read_etc_rc_conf (void) +{ + return system_timezone_read_key_file (ETC_RC_CONF, + "TIMEZONE"); +} + +static gboolean +system_timezone_write_etc_rc_conf (const char *tz, + GError **error) +{ + return system_timezone_write_key_file (ETC_RC_CONF, + "TIMEZONE", tz, error); +} + +/* + * + * First, getting the timezone. + * + */ + +static char * +system_timezone_strip_path_if_valid (const char *filename) +{ + int skip; + + if (!filename || !g_str_has_prefix (filename, SYSTEM_ZONEINFODIR"/")) + return NULL; + + /* Timezone data files also live under posix/ and right/ for some + * reason. + * FIXME: make sure accepting those files is valid. I think "posix" is + * okay, not sure about "right" */ + if (g_str_has_prefix (filename, SYSTEM_ZONEINFODIR"/posix/")) + skip = strlen (SYSTEM_ZONEINFODIR"/posix/"); + else if (g_str_has_prefix (filename, SYSTEM_ZONEINFODIR"/right/")) + skip = strlen (SYSTEM_ZONEINFODIR"/right/"); + else + skip = strlen (SYSTEM_ZONEINFODIR"/"); + + return g_strdup (filename + skip); +} + +/* Read the soft symlink from /etc/localtime */ +static char * +system_timezone_read_etc_localtime_softlink (void) +{ + char *file; + char *tz; + + if (!g_file_test (ETC_LOCALTIME, G_FILE_TEST_IS_SYMLINK)) + return NULL; + + file = g_file_read_link (ETC_LOCALTIME, NULL); + tz = system_timezone_strip_path_if_valid (file); + g_free (file); + + return tz; +} + +typedef gboolean (*CompareFiles) (struct stat *a_stat, + struct stat *b_stat, + const char *a_content, + gsize a_content_len, + const char *b_filename); + +static char * +recursive_compare (struct stat *localtime_stat, + const char *localtime_content, + gsize localtime_content_len, + char *file, + CompareFiles compare_func) +{ + struct stat file_stat; + + if (g_stat (file, &file_stat) != 0) + return NULL; + + if (S_ISREG (file_stat.st_mode)) { + if (compare_func (localtime_stat, + &file_stat, + localtime_content, + localtime_content_len, + file)) + return system_timezone_strip_path_if_valid (file); + else + return NULL; + } else if (S_ISDIR (file_stat.st_mode)) { + GDir *dir = NULL; + char *ret = NULL; + const char *subfile = NULL; + char *subpath = NULL; + + dir = g_dir_open (file, 0, NULL); + if (dir == NULL) + return NULL; + + while ((subfile = g_dir_read_name (dir)) != NULL) { + subpath = g_build_filename (file, subfile, NULL); + + ret = recursive_compare (localtime_stat, + localtime_content, + localtime_content_len, + subpath, + compare_func); + + g_free (subpath); + + if (ret != NULL) + break; + } + + g_dir_close (dir); + + return ret; + } + + return NULL; +} + + +static gboolean +files_are_identical_inode (struct stat *a_stat, + struct stat *b_stat, + const char *a_content, + gsize a_content_len, + const char *b_filename) +{ + return (a_stat->st_ino == b_stat->st_ino); +} + + +/* Determine if /etc/localtime is a hard link to some file, by looking at + * the inodes */ +static char * +system_timezone_read_etc_localtime_hardlink (void) +{ + struct stat stat_localtime; + + if (g_stat (ETC_LOCALTIME, &stat_localtime) != 0) + return NULL; + + if (!S_ISREG (stat_localtime.st_mode)) + return NULL; + + return recursive_compare (&stat_localtime, + NULL, + 0, + SYSTEM_ZONEINFODIR, + files_are_identical_inode); +} + +static gboolean +files_are_identical_content (struct stat *a_stat, + struct stat *b_stat, + const char *a_content, + gsize a_content_len, + const char *b_filename) +{ + char *b_content = NULL; + gsize b_content_len = -1; + int cmp; + + if (a_stat->st_size != b_stat->st_size) + return FALSE; + + if (!g_file_get_contents (b_filename, + &b_content, &b_content_len, NULL)) + return FALSE; + + if (a_content_len != b_content_len) { + g_free (b_content); + return FALSE; + } + + cmp = memcmp (a_content, b_content, a_content_len); + g_free (b_content); + + return (cmp == 0); +} + +/* Determine if /etc/localtime is a copy of a timezone file */ +static char * +system_timezone_read_etc_localtime_content (void) +{ + struct stat stat_localtime; + char *localtime_content = NULL; + gsize localtime_content_len = -1; + char *retval; + + if (g_stat (ETC_LOCALTIME, &stat_localtime) != 0) + return NULL; + + if (!S_ISREG (stat_localtime.st_mode)) + return NULL; + + if (!g_file_get_contents (ETC_LOCALTIME, + &localtime_content, + &localtime_content_len, + NULL)) + return NULL; + + retval = recursive_compare (&stat_localtime, + localtime_content, + localtime_content_len, + SYSTEM_ZONEINFODIR, + files_are_identical_content); + + g_free (localtime_content); + + return retval; +} + +typedef char * (*GetSystemTimezone) (void); +/* The order of the functions here define the priority of the methods used + * to find the timezone. First method has higher priority. */ +static GetSystemTimezone get_system_timezone_methods[] = { + /* cheap and "more correct" than data from a config file */ + system_timezone_read_etc_localtime_softlink, + /* reading various config files */ + system_timezone_read_etc_timezone, + system_timezone_read_etc_sysconfig_clock, + system_timezone_read_etc_sysconfig_clock_alt, + system_timezone_read_etc_TIMEZONE, + system_timezone_read_etc_rc_conf, + /* reading deprecated config files */ + system_timezone_read_etc_conf_d_clock, + /* reading /etc/timezone directly. Expensive since we have to stat + * many files */ + system_timezone_read_etc_localtime_hardlink, + system_timezone_read_etc_localtime_content, + NULL +}; + +static gboolean +system_timezone_is_valid (const char *tz) +{ + const char *c; + + if (!tz) + return FALSE; + + for (c = tz; *c != '\0'; c++) { + if (!(g_ascii_isalnum (*c) || + *c == '/' || *c == '-' || *c == '_')) + return FALSE; + } + + return TRUE; +} + +char * +system_timezone_find (void) +{ + char *tz; + int i; + + for (i = 0; get_system_timezone_methods[i] != NULL; i++) { + tz = get_system_timezone_methods[i] (); + + if (system_timezone_is_valid (tz)) + return tz; + + g_free (tz); + } + + return g_strdup ("UTC"); +} + +/* + * + * Now, setting the timezone. + * + */ + +static gboolean +system_timezone_is_zone_file_valid (const char *zone_file, + GError **error) +{ + GError *our_error; + GIOChannel *channel; + GIOStatus status; + char buffer[strlen (TZ_MAGIC)]; + gsize read; + + /* First, check the zone_file is properly rooted */ + if (!g_str_has_prefix (zone_file, SYSTEM_ZONEINFODIR"/")) { + g_set_error (error, SYSTEM_TIMEZONE_ERROR, + SYSTEM_TIMEZONE_ERROR_INVALID_TIMEZONE_FILE, + "Timezone file needs to be under "SYSTEM_ZONEINFODIR); + return FALSE; + } + + /* Second, check it's a regular file that exists */ + if (!g_file_test (zone_file, G_FILE_TEST_IS_REGULAR)) { + g_set_error (error, SYSTEM_TIMEZONE_ERROR, + SYSTEM_TIMEZONE_ERROR_INVALID_TIMEZONE_FILE, + "No such timezone file %s", zone_file); + return FALSE; + } + + /* Third, check that it's a tzfile (see tzfile(5)). The file has a 4 + * bytes header which is TZ_MAGIC. + * + * TODO: is there glibc API for this? */ + our_error = NULL; + channel = g_io_channel_new_file (zone_file, "r", &our_error); + if (!our_error) + status = g_io_channel_read_chars (channel, + buffer, strlen (TZ_MAGIC), + &read, &our_error); + if (channel) + g_io_channel_unref (channel); + + if (our_error) { + g_set_error (error, SYSTEM_TIMEZONE_ERROR, + SYSTEM_TIMEZONE_ERROR_INVALID_TIMEZONE_FILE, + "Timezone file %s cannot be read: %s", + zone_file, our_error->message); + g_error_free (our_error); + return FALSE; + } + + if (read != strlen (TZ_MAGIC) || strncmp (buffer, TZ_MAGIC, strlen (TZ_MAGIC)) != 0) { + g_set_error (error, SYSTEM_TIMEZONE_ERROR, + SYSTEM_TIMEZONE_ERROR_INVALID_TIMEZONE_FILE, + "%s is not a timezone file", + zone_file); + return FALSE; + } + + return TRUE; +} + +static gboolean +system_timezone_set_etc_timezone (const char *zone_file, + GError **error) +{ + GError *our_error; + char *content; + gsize len; + + if (!system_timezone_is_zone_file_valid (zone_file, error)) + return FALSE; + + /* If /etc/localtime is a symlink, write a symlink */ + if (g_file_test (ETC_LOCALTIME, G_FILE_TEST_IS_SYMLINK)) { + if (g_unlink (ETC_LOCALTIME) == 0 && + symlink (zone_file, ETC_LOCALTIME) == 0) + return TRUE; + + /* If we couldn't symlink the file, we'll just fallback on + * copying it */ + } + + /* Else copy the file to /etc/localtime. We explicitly avoid doing + * hard links since they break with different partitions */ + our_error = NULL; + if (!g_file_get_contents (zone_file, &content, &len, &our_error)) { + g_set_error (error, SYSTEM_TIMEZONE_ERROR, + SYSTEM_TIMEZONE_ERROR_GENERAL, + "Timezone file %s cannot be read: %s", + zone_file, our_error->message); + g_error_free (our_error); + return FALSE; + } + + if (!g_file_set_contents (ETC_LOCALTIME, content, len, &our_error)) { + g_set_error (error, SYSTEM_TIMEZONE_ERROR, + SYSTEM_TIMEZONE_ERROR_GENERAL, + ETC_LOCALTIME" cannot be overwritten: %s", + our_error->message); + g_error_free (our_error); + g_free (content); + return FALSE; + } + + g_free (content); + + return TRUE; +} + +typedef gboolean (*SetSystemTimezone) (const char *tz, + GError **error); +/* The order here does not matter too much: we'll try to change all files + * that already have a timezone configured. It matters in case of error, + * since the process will be stopped and the last methods won't be called. + * So we use the same order as in get_system_timezone_methods */ +static SetSystemTimezone set_system_timezone_methods[] = { + /* writing various config files if they exist and have the + * setting already present */ + system_timezone_write_etc_timezone, + system_timezone_write_etc_sysconfig_clock, + system_timezone_write_etc_sysconfig_clock_alt, + system_timezone_write_etc_TIMEZONE, + system_timezone_write_etc_rc_conf, + /* writing deprecated config files if they exist and have the + * setting already present */ + system_timezone_write_etc_conf_d_clock, + NULL +}; + +static gboolean +system_timezone_update_config (const char *tz, + GError **error) +{ + int i; + + for (i = 0; set_system_timezone_methods[i] != NULL; i++) { + if (!set_system_timezone_methods[i] (tz, error)) + return FALSE; + /* FIXME: maybe continue to change all config files if + * possible? */ + } + + return TRUE; +} + +gboolean +system_timezone_set_from_file (const char *zone_file, + GError **error) +{ + const char *tz; + + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + tz = zone_file + strlen (SYSTEM_ZONEINFODIR"/"); + + /* FIXME: is it right to return FALSE even when /etc/localtime was + * changed but not the config files? */ + return (system_timezone_set_etc_timezone (zone_file, error) && + system_timezone_update_config (tz, error)); +} + +gboolean +system_timezone_set (const char *tz, + GError **error) +{ + char *zone_file; + gboolean retval; + + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + zone_file = g_build_filename (SYSTEM_ZONEINFODIR, tz, NULL); + + /* FIXME: is it right to return FALSE even when /etc/localtime was + * changed but not the config files? */ + retval = system_timezone_set_etc_timezone (zone_file, error) && + system_timezone_update_config (tz, error); + + g_free (zone_file); + + return retval; +} + +GQuark +system_timezone_error_quark (void) +{ + static GQuark ret = 0; + + if (ret == 0) { + ret = g_quark_from_static_string ("system-timezone-error"); + } + + return ret; +} diff --git a/plugins/datetime/system-timezone.h b/plugins/datetime/system-timezone.h new file mode 100644 index 0000000..b958cec --- /dev/null +++ b/plugins/datetime/system-timezone.h @@ -0,0 +1,89 @@ +/* System timezone handling + * + * Copyright (C) 2008 Novell, Inc. + * + * Authors: Vincent Untz <[email protected]> + * + * 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 __SYSTEM_TIMEZONE_H__ +#define __SYSTEM_TIMEZONE_H__ + +#include <glib.h> +#include <glib-object.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAVE_SOLARIS +#define SYSTEM_ZONEINFODIR "/usr/share/lib/zoneinfo/tab" +#else +#define SYSTEM_ZONEINFODIR "/usr/share/zoneinfo" +#endif + + +#define SYSTEM_TIMEZONE_TYPE (system_timezone_get_type ()) +#define SYSTEM_TIMEZONE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SYSTEM_TIMEZONE_TYPE, SystemTimezone)) +#define SYSTEM_TIMEZONE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), SYSTEM_TIMEZONE_TYPE, SystemTimezoneClass)) +#define IS_SYSTEM_TIMEZONE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SYSTEM_TIMEZONE_TYPE)) +#define IS_SYSTEM_TIMEZONE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), SYSTEM_TIMEZONE_TYPE)) +#define SYSTEM_TIMEZONE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), SYSTEM_TIMEZONE_TYPE, SystemTimezoneClass)) + +typedef struct +{ + GObject g_object; +} SystemTimezone; + +typedef struct +{ + GObjectClass g_object_class; + + void (* changed) (SystemTimezone *systz, + const char *tz); +} SystemTimezoneClass; + +GType system_timezone_get_type (void); + +SystemTimezone *system_timezone_new (void); + +const char *system_timezone_get (SystemTimezone *systz); +const char *system_timezone_get_env (SystemTimezone *systz); + +/* Functions to set the timezone. They won't be used by the applet, but + * by a program with more privileges */ + +#define SYSTEM_TIMEZONE_ERROR system_timezone_error_quark () +GQuark system_timezone_error_quark (void); + +typedef enum +{ + SYSTEM_TIMEZONE_ERROR_GENERAL, + SYSTEM_TIMEZONE_ERROR_INVALID_TIMEZONE_FILE, + SYSTEM_TIMEZONE_NUM_ERRORS +} SystemTimezoneError; + +char *system_timezone_find (void); + +gboolean system_timezone_set_from_file (const char *zone_file, + GError **error); +gboolean system_timezone_set (const char *tz, + GError **error); + +#ifdef __cplusplus +} +#endif +#endif /* __SYSTEM_TIMEZONE_H__ */ diff --git a/plugins/dummy/Makefile.am b/plugins/dummy/Makefile.am new file mode 100644 index 0000000..0f77530 --- /dev/null +++ b/plugins/dummy/Makefile.am @@ -0,0 +1,44 @@ +plugin_LTLIBRARIES = \ + libdummy.la + +libdummy_la_SOURCES = \ + gsd-dummy-manager.c \ + gsd-dummy-manager.h \ + gsd-dummy-plugin.c \ + gsd-dummy-plugin.h + +libdummy_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libdummy_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libdummy_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) + +libdummy_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) + +plugin_in_files = \ + dummy.mate-settings-plugin.in + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) + +EXTRA_DIST = \ + $(plugin_in_files) + +CLEANFILES = \ + $(plugin_DATA) + +DISTCLEANFILES = \ + $(plugin_DATA) + +@GSD_INTLTOOL_PLUGIN_RULE@ + +# override to _not_ install the test plugin +# do not copy into your plugin +install-pluginDATA: +install-pluginLTLIBRARIES: diff --git a/plugins/dummy/Makefile.in b/plugins/dummy/Makefile.in new file mode 100644 index 0000000..3680d45 --- /dev/null +++ b/plugins/dummy/Makefile.in @@ -0,0 +1,646 @@ +# 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/dummy +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)$(plugindir)" +LTLIBRARIES = $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +libdummy_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libdummy_la_OBJECTS = libdummy_la-gsd-dummy-manager.lo \ + libdummy_la-gsd-dummy-plugin.lo +libdummy_la_OBJECTS = $(am_libdummy_la_OBJECTS) +libdummy_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libdummy_la_CFLAGS) \ + $(CFLAGS) $(libdummy_la_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 = $(libdummy_la_SOURCES) +DIST_SOURCES = $(libdummy_la_SOURCES) +DATA = $(plugin_DATA) +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@ +plugin_LTLIBRARIES = \ + libdummy.la + +libdummy_la_SOURCES = \ + gsd-dummy-manager.c \ + gsd-dummy-manager.h \ + gsd-dummy-plugin.c \ + gsd-dummy-plugin.h + +libdummy_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libdummy_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libdummy_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) + +libdummy_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) + +plugin_in_files = \ + dummy.mate-settings-plugin.in + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) +EXTRA_DIST = \ + $(plugin_in_files) + +CLEANFILES = \ + $(plugin_DATA) + +DISTCLEANFILES = \ + $(plugin_DATA) + +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/dummy/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plugins/dummy/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): + +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 +libdummy.la: $(libdummy_la_OBJECTS) $(libdummy_la_DEPENDENCIES) + $(libdummy_la_LINK) -rpath $(plugindir) $(libdummy_la_OBJECTS) $(libdummy_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdummy_la-gsd-dummy-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdummy_la-gsd-dummy-plugin.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 $@ $< + +libdummy_la-gsd-dummy-manager.lo: gsd-dummy-manager.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdummy_la_CPPFLAGS) $(CPPFLAGS) $(libdummy_la_CFLAGS) $(CFLAGS) -MT libdummy_la-gsd-dummy-manager.lo -MD -MP -MF $(DEPDIR)/libdummy_la-gsd-dummy-manager.Tpo -c -o libdummy_la-gsd-dummy-manager.lo `test -f 'gsd-dummy-manager.c' || echo '$(srcdir)/'`gsd-dummy-manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libdummy_la-gsd-dummy-manager.Tpo $(DEPDIR)/libdummy_la-gsd-dummy-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-dummy-manager.c' object='libdummy_la-gsd-dummy-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) $(libdummy_la_CPPFLAGS) $(CPPFLAGS) $(libdummy_la_CFLAGS) $(CFLAGS) -c -o libdummy_la-gsd-dummy-manager.lo `test -f 'gsd-dummy-manager.c' || echo '$(srcdir)/'`gsd-dummy-manager.c + +libdummy_la-gsd-dummy-plugin.lo: gsd-dummy-plugin.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdummy_la_CPPFLAGS) $(CPPFLAGS) $(libdummy_la_CFLAGS) $(CFLAGS) -MT libdummy_la-gsd-dummy-plugin.lo -MD -MP -MF $(DEPDIR)/libdummy_la-gsd-dummy-plugin.Tpo -c -o libdummy_la-gsd-dummy-plugin.lo `test -f 'gsd-dummy-plugin.c' || echo '$(srcdir)/'`gsd-dummy-plugin.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libdummy_la-gsd-dummy-plugin.Tpo $(DEPDIR)/libdummy_la-gsd-dummy-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-dummy-plugin.c' object='libdummy_la-gsd-dummy-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) $(libdummy_la_CPPFLAGS) $(CPPFLAGS) $(libdummy_la_CFLAGS) $(CFLAGS) -c -o libdummy_la-gsd-dummy-plugin.lo `test -f 'gsd-dummy-plugin.c' || echo '$(srcdir)/'`gsd-dummy-plugin.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +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 + +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) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -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." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ + 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-pluginDATA install-pluginLTLIBRARIES + +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: uninstall-pluginDATA uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-pluginLTLIBRARIES 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-pluginDATA \ + install-pluginLTLIBRARIES 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 \ + uninstall-pluginDATA uninstall-pluginLTLIBRARIES + + +@GSD_INTLTOOL_PLUGIN_RULE@ + +# override to _not_ install the test plugin +# do not copy into your plugin +install-pluginDATA: +install-pluginLTLIBRARIES: + +# 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/dummy/dummy.mate-settings-plugin.in b/plugins/dummy/dummy.mate-settings-plugin.in new file mode 100644 index 0000000..c9f8838 --- /dev/null +++ b/plugins/dummy/dummy.mate-settings-plugin.in @@ -0,0 +1,8 @@ +[MATE Settings Plugin] +Module=dummy +IAge=0 +_Name=Dummy +_Description=Dummy plugin +Authors=AUTHOR +Copyright=Copyright © 2007 AUTHOR +Website= diff --git a/plugins/dummy/gsd-dummy-manager.c b/plugins/dummy/gsd-dummy-manager.c new file mode 100644 index 0000000..568c832 --- /dev/null +++ b/plugins/dummy/gsd-dummy-manager.c @@ -0,0 +1,186 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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 <sys/types.h> +#include <sys/wait.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> + +#include <locale.h> + +#include <glib.h> +#include <glib/gi18n.h> +#include <gdk/gdk.h> +#include <gdk/gdkx.h> +#include <gtk/gtk.h> + +#include "mate-settings-profile.h" +#include "gsd-dummy-manager.h" + +#define GSD_DUMMY_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_DUMMY_MANAGER, GsdDummyManagerPrivate)) + +struct GsdDummyManagerPrivate +{ + gboolean padding; +}; + +enum { + PROP_0, +}; + +static void gsd_dummy_manager_class_init (GsdDummyManagerClass *klass); +static void gsd_dummy_manager_init (GsdDummyManager *dummy_manager); +static void gsd_dummy_manager_finalize (GObject *object); + +G_DEFINE_TYPE (GsdDummyManager, gsd_dummy_manager, G_TYPE_OBJECT) + +static gpointer manager_object = NULL; + +gboolean +gsd_dummy_manager_start (GsdDummyManager *manager, + GError **error) +{ + g_debug ("Starting dummy manager"); + mate_settings_profile_start (NULL); + mate_settings_profile_end (NULL); + return TRUE; +} + +void +gsd_dummy_manager_stop (GsdDummyManager *manager) +{ + g_debug ("Stopping dummy manager"); +} + +static void +gsd_dummy_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GsdDummyManager *self; + + self = GSD_DUMMY_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gsd_dummy_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GsdDummyManager *self; + + self = GSD_DUMMY_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +gsd_dummy_manager_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GsdDummyManager *dummy_manager; + GsdDummyManagerClass *klass; + + klass = GSD_DUMMY_MANAGER_CLASS (g_type_class_peek (GSD_TYPE_DUMMY_MANAGER)); + + dummy_manager = GSD_DUMMY_MANAGER (G_OBJECT_CLASS (gsd_dummy_manager_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + + return G_OBJECT (dummy_manager); +} + +static void +gsd_dummy_manager_dispose (GObject *object) +{ + GsdDummyManager *dummy_manager; + + dummy_manager = GSD_DUMMY_MANAGER (object); + + G_OBJECT_CLASS (gsd_dummy_manager_parent_class)->dispose (object); +} + +static void +gsd_dummy_manager_class_init (GsdDummyManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gsd_dummy_manager_get_property; + object_class->set_property = gsd_dummy_manager_set_property; + object_class->constructor = gsd_dummy_manager_constructor; + object_class->dispose = gsd_dummy_manager_dispose; + object_class->finalize = gsd_dummy_manager_finalize; + + g_type_class_add_private (klass, sizeof (GsdDummyManagerPrivate)); +} + +static void +gsd_dummy_manager_init (GsdDummyManager *manager) +{ + manager->priv = GSD_DUMMY_MANAGER_GET_PRIVATE (manager); + +} + +static void +gsd_dummy_manager_finalize (GObject *object) +{ + GsdDummyManager *dummy_manager; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_DUMMY_MANAGER (object)); + + dummy_manager = GSD_DUMMY_MANAGER (object); + + g_return_if_fail (dummy_manager->priv != NULL); + + G_OBJECT_CLASS (gsd_dummy_manager_parent_class)->finalize (object); +} + +GsdDummyManager * +gsd_dummy_manager_new (void) +{ + if (manager_object != NULL) { + g_object_ref (manager_object); + } else { + manager_object = g_object_new (GSD_TYPE_DUMMY_MANAGER, NULL); + g_object_add_weak_pointer (manager_object, + (gpointer *) &manager_object); + } + + return GSD_DUMMY_MANAGER (manager_object); +} diff --git a/plugins/dummy/gsd-dummy-manager.h b/plugins/dummy/gsd-dummy-manager.h new file mode 100644 index 0000000..ba63560 --- /dev/null +++ b/plugins/dummy/gsd-dummy-manager.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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_DUMMY_MANAGER_H +#define __GSD_DUMMY_MANAGER_H + +#include <glib-object.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_DUMMY_MANAGER (gsd_dummy_manager_get_type ()) +#define GSD_DUMMY_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_DUMMY_MANAGER, GsdDummyManager)) +#define GSD_DUMMY_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_DUMMY_MANAGER, GsdDummyManagerClass)) +#define GSD_IS_DUMMY_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_DUMMY_MANAGER)) +#define GSD_IS_DUMMY_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_DUMMY_MANAGER)) +#define GSD_DUMMY_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_DUMMY_MANAGER, GsdDummyManagerClass)) + +typedef struct GsdDummyManagerPrivate GsdDummyManagerPrivate; + +typedef struct +{ + GObject parent; + GsdDummyManagerPrivate *priv; +} GsdDummyManager; + +typedef struct +{ + GObjectClass parent_class; +} GsdDummyManagerClass; + +GType gsd_dummy_manager_get_type (void); + +GsdDummyManager * gsd_dummy_manager_new (void); +gboolean gsd_dummy_manager_start (GsdDummyManager *manager, + GError **error); +void gsd_dummy_manager_stop (GsdDummyManager *manager); + +#ifdef __cplusplus +} +#endif + +#endif /* __GSD_DUMMY_MANAGER_H */ diff --git a/plugins/dummy/gsd-dummy-plugin.c b/plugins/dummy/gsd-dummy-plugin.c new file mode 100644 index 0000000..f284423 --- /dev/null +++ b/plugins/dummy/gsd-dummy-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 <[email protected]> + * + * 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 <glib/gi18n-lib.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" +#include "gsd-dummy-plugin.h" +#include "gsd-dummy-manager.h" + +struct GsdDummyPluginPrivate { + GsdDummyManager *manager; +}; + +#define GSD_DUMMY_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSD_TYPE_DUMMY_PLUGIN, GsdDummyPluginPrivate)) + +MATE_SETTINGS_PLUGIN_REGISTER (GsdDummyPlugin, gsd_dummy_plugin) + +static void +gsd_dummy_plugin_init (GsdDummyPlugin *plugin) +{ + plugin->priv = GSD_DUMMY_PLUGIN_GET_PRIVATE (plugin); + + g_debug ("GsdDummyPlugin initializing"); + + plugin->priv->manager = gsd_dummy_manager_new (); +} + +static void +gsd_dummy_plugin_finalize (GObject *object) +{ + GsdDummyPlugin *plugin; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_DUMMY_PLUGIN (object)); + + g_debug ("GsdDummyPlugin finalizing"); + + plugin = GSD_DUMMY_PLUGIN (object); + + g_return_if_fail (plugin->priv != NULL); + + if (plugin->priv->manager != NULL) { + g_object_unref (plugin->priv->manager); + } + + G_OBJECT_CLASS (gsd_dummy_plugin_parent_class)->finalize (object); +} + +static void +impl_activate (MateSettingsPlugin *plugin) +{ + gboolean res; + GError *error; + + g_debug ("Activating dummy plugin"); + + error = NULL; + res = gsd_dummy_manager_start (GSD_DUMMY_PLUGIN (plugin)->priv->manager, &error); + if (! res) { + g_warning ("Unable to start dummy manager: %s", error->message); + g_error_free (error); + } +} + +static void +impl_deactivate (MateSettingsPlugin *plugin) +{ + g_debug ("Deactivating dummy plugin"); + gsd_dummy_manager_stop (GSD_DUMMY_PLUGIN (plugin)->priv->manager); +} + +static void +gsd_dummy_plugin_class_init (GsdDummyPluginClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MateSettingsPluginClass *plugin_class = MATE_SETTINGS_PLUGIN_CLASS (klass); + + object_class->finalize = gsd_dummy_plugin_finalize; + + plugin_class->activate = impl_activate; + plugin_class->deactivate = impl_deactivate; + + g_type_class_add_private (klass, sizeof (GsdDummyPluginPrivate)); +} diff --git a/plugins/dummy/gsd-dummy-plugin.h b/plugins/dummy/gsd-dummy-plugin.h new file mode 100644 index 0000000..153e0fa --- /dev/null +++ b/plugins/dummy/gsd-dummy-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 <[email protected]> + * + * 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_DUMMY_PLUGIN_H__ +#define __GSD_DUMMY_PLUGIN_H__ + +#include <glib.h> +#include <glib-object.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_DUMMY_PLUGIN (gsd_dummy_plugin_get_type ()) +#define GSD_DUMMY_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_DUMMY_PLUGIN, GsdDummyPlugin)) +#define GSD_DUMMY_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_DUMMY_PLUGIN, GsdDummyPluginClass)) +#define GSD_IS_DUMMY_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_DUMMY_PLUGIN)) +#define GSD_IS_DUMMY_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_DUMMY_PLUGIN)) +#define GSD_DUMMY_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_DUMMY_PLUGIN, GsdDummyPluginClass)) + +typedef struct GsdDummyPluginPrivate GsdDummyPluginPrivate; + +typedef struct +{ + MateSettingsPlugin parent; + GsdDummyPluginPrivate *priv; +} GsdDummyPlugin; + +typedef struct +{ + MateSettingsPluginClass parent_class; +} GsdDummyPluginClass; + +GType gsd_dummy_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_DUMMY_PLUGIN_H__ */ diff --git a/plugins/font/Makefile.am b/plugins/font/Makefile.am new file mode 100644 index 0000000..99dff34 --- /dev/null +++ b/plugins/font/Makefile.am @@ -0,0 +1,51 @@ +NULL = + +plugin_LTLIBRARIES = \ + libfont.la \ + $(NULL) + +libfont_la_SOURCES = \ + gsd-font-plugin.h \ + gsd-font-plugin.c \ + gsd-font-manager.h \ + gsd-font-manager.c \ + delayed-dialog.h \ + delayed-dialog.c \ + $(NULL) + +libfont_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libfont_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libfont_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) \ + $(NULL) + +libfont_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(NULL) + +plugin_in_files = \ + font.mate-settings-plugin.in \ + $(NULL) + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) + +EXTRA_DIST = \ + $(plugin_in_files) \ + $(NULL) + +CLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +DISTCLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +@GSD_INTLTOOL_PLUGIN_RULE@ diff --git a/plugins/font/Makefile.in b/plugins/font/Makefile.in new file mode 100644 index 0000000..a3c90ea --- /dev/null +++ b/plugins/font/Makefile.in @@ -0,0 +1,687 @@ +# 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/font +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)$(plugindir)" +LTLIBRARIES = $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +libfont_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am__objects_1 = +am_libfont_la_OBJECTS = libfont_la-gsd-font-plugin.lo \ + libfont_la-gsd-font-manager.lo libfont_la-delayed-dialog.lo \ + $(am__objects_1) +libfont_la_OBJECTS = $(am_libfont_la_OBJECTS) +libfont_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libfont_la_CFLAGS) \ + $(CFLAGS) $(libfont_la_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 = $(libfont_la_SOURCES) +DIST_SOURCES = $(libfont_la_SOURCES) +DATA = $(plugin_DATA) +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 = +plugin_LTLIBRARIES = \ + libfont.la \ + $(NULL) + +libfont_la_SOURCES = \ + gsd-font-plugin.h \ + gsd-font-plugin.c \ + gsd-font-manager.h \ + gsd-font-manager.c \ + delayed-dialog.h \ + delayed-dialog.c \ + $(NULL) + +libfont_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libfont_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libfont_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) \ + $(NULL) + +libfont_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(NULL) + +plugin_in_files = \ + font.mate-settings-plugin.in \ + $(NULL) + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) +EXTRA_DIST = \ + $(plugin_in_files) \ + $(NULL) + +CLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +DISTCLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +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/font/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plugins/font/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 +libfont.la: $(libfont_la_OBJECTS) $(libfont_la_DEPENDENCIES) + $(libfont_la_LINK) -rpath $(plugindir) $(libfont_la_OBJECTS) $(libfont_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfont_la-delayed-dialog.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfont_la-gsd-font-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfont_la-gsd-font-plugin.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 $@ $< + +libfont_la-gsd-font-plugin.lo: gsd-font-plugin.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfont_la_CPPFLAGS) $(CPPFLAGS) $(libfont_la_CFLAGS) $(CFLAGS) -MT libfont_la-gsd-font-plugin.lo -MD -MP -MF $(DEPDIR)/libfont_la-gsd-font-plugin.Tpo -c -o libfont_la-gsd-font-plugin.lo `test -f 'gsd-font-plugin.c' || echo '$(srcdir)/'`gsd-font-plugin.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfont_la-gsd-font-plugin.Tpo $(DEPDIR)/libfont_la-gsd-font-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-font-plugin.c' object='libfont_la-gsd-font-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) $(libfont_la_CPPFLAGS) $(CPPFLAGS) $(libfont_la_CFLAGS) $(CFLAGS) -c -o libfont_la-gsd-font-plugin.lo `test -f 'gsd-font-plugin.c' || echo '$(srcdir)/'`gsd-font-plugin.c + +libfont_la-gsd-font-manager.lo: gsd-font-manager.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfont_la_CPPFLAGS) $(CPPFLAGS) $(libfont_la_CFLAGS) $(CFLAGS) -MT libfont_la-gsd-font-manager.lo -MD -MP -MF $(DEPDIR)/libfont_la-gsd-font-manager.Tpo -c -o libfont_la-gsd-font-manager.lo `test -f 'gsd-font-manager.c' || echo '$(srcdir)/'`gsd-font-manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfont_la-gsd-font-manager.Tpo $(DEPDIR)/libfont_la-gsd-font-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-font-manager.c' object='libfont_la-gsd-font-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) $(libfont_la_CPPFLAGS) $(CPPFLAGS) $(libfont_la_CFLAGS) $(CFLAGS) -c -o libfont_la-gsd-font-manager.lo `test -f 'gsd-font-manager.c' || echo '$(srcdir)/'`gsd-font-manager.c + +libfont_la-delayed-dialog.lo: delayed-dialog.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfont_la_CPPFLAGS) $(CPPFLAGS) $(libfont_la_CFLAGS) $(CFLAGS) -MT libfont_la-delayed-dialog.lo -MD -MP -MF $(DEPDIR)/libfont_la-delayed-dialog.Tpo -c -o libfont_la-delayed-dialog.lo `test -f 'delayed-dialog.c' || echo '$(srcdir)/'`delayed-dialog.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libfont_la-delayed-dialog.Tpo $(DEPDIR)/libfont_la-delayed-dialog.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='delayed-dialog.c' object='libfont_la-delayed-dialog.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) $(libfont_la_CPPFLAGS) $(CPPFLAGS) $(libfont_la_CFLAGS) $(CFLAGS) -c -o libfont_la-delayed-dialog.lo `test -f 'delayed-dialog.c' || echo '$(srcdir)/'`delayed-dialog.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +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 + +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) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -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." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ + 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-pluginDATA install-pluginLTLIBRARIES + +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: uninstall-pluginDATA uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-pluginLTLIBRARIES 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-pluginDATA \ + install-pluginLTLIBRARIES 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 \ + uninstall-pluginDATA uninstall-pluginLTLIBRARIES + + +@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/font/delayed-dialog.c b/plugins/font/delayed-dialog.c new file mode 100644 index 0000000..bfc8493 --- /dev/null +++ b/plugins/font/delayed-dialog.c @@ -0,0 +1,122 @@ +/* + * Copyright © 2006 Novell, 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, 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 <stdlib.h> +#include <string.h> + +#include <gtk/gtk.h> +#include <gdk/gdkx.h> + +#include "delayed-dialog.h" + +static gboolean delayed_show_timeout (gpointer data); +static GdkFilterReturn message_filter (GdkXEvent *xevent, + GdkEvent *event, + gpointer data); + +static GSList *dialogs = NULL; + +/** + * mate_settings_delayed_show_dialog: + * @dialog: the dialog + * + * Shows the dialog as with gtk_widget_show(), unless a window manager + * hasn't been started yet, in which case it will wait up to 5 seconds + * for that to happen before showing the dialog. + **/ +void +mate_settings_delayed_show_dialog (GtkWidget *dialog) +{ + GdkDisplay *display = gtk_widget_get_display (dialog); + Display *xdisplay = GDK_DISPLAY_XDISPLAY (display); + GdkScreen *screen = gtk_widget_get_screen (dialog); + GdkAtom manager_atom; + char selection_name[10]; + Atom selection_atom; + + /* We can't use gdk_selection_owner_get() for this, because + * it's an unknown out-of-process window. + */ + snprintf (selection_name, sizeof (selection_name), "WM_S%d", + gdk_screen_get_number (screen)); + selection_atom = XInternAtom (xdisplay, selection_name, True); + if (selection_atom && + XGetSelectionOwner (xdisplay, selection_atom) != None) { + gtk_widget_show (dialog); + return; + } + + dialogs = g_slist_prepend (dialogs, dialog); + + manager_atom = gdk_atom_intern ("MANAGER", FALSE); + gdk_display_add_client_message_filter (display, manager_atom, + message_filter, NULL); + + g_timeout_add (5000, delayed_show_timeout, NULL); +} + +static gboolean +delayed_show_timeout (gpointer data) +{ + GSList *l; + + for (l = dialogs; l; l = l->next) + gtk_widget_show (l->data); + g_slist_free (dialogs); + dialogs = NULL; + + /* FIXME: There's no gdk_display_remove_client_message_filter */ + + return FALSE; +} + +static GdkFilterReturn +message_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data) +{ + XClientMessageEvent *evt = (XClientMessageEvent *)xevent; + char *selection_name = XGetAtomName (evt->display, evt->data.l[1]); + int screen; + GSList *l, *next; + + if (!dialogs) + return GDK_FILTER_CONTINUE; + + if (strncmp (selection_name, "WM_S", 4) != 0) { + XFree (selection_name); + return GDK_FILTER_CONTINUE; + } + + screen = atoi (selection_name + 4); + + for (l = dialogs; l; l = next) { + GtkWidget *dialog = l->data; + next = l->next; + + if (gdk_screen_get_number (gtk_widget_get_screen (dialog)) == screen) { + gtk_widget_show (dialog); + dialogs = g_slist_remove (dialogs, dialog); + } + } + + if (!dialogs) { + /* FIXME: There's no gdk_display_remove_client_message_filter */ + } + + return GDK_FILTER_CONTINUE; +} diff --git a/plugins/font/delayed-dialog.h b/plugins/font/delayed-dialog.h new file mode 100644 index 0000000..0c35317 --- /dev/null +++ b/plugins/font/delayed-dialog.h @@ -0,0 +1,36 @@ +/* + * Copyright © 2006 Novell, 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, 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 __DELAYED_DIALOG_H +#define __DELAYED_DIALOG_H + +#include <gtk/gtk.h> + +#ifdef __cplusplus +extern "C" { +#endif + +void mate_settings_delayed_show_dialog (GtkWidget *dialog); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/plugins/font/font.mate-settings-plugin.in b/plugins/font/font.mate-settings-plugin.in new file mode 100644 index 0000000..6bb1c47 --- /dev/null +++ b/plugins/font/font.mate-settings-plugin.in @@ -0,0 +1,8 @@ +[MATE Settings Plugin] +Module=font +IAge=0 +_Name=Font +_Description=Font plugin +Authors=Rodrigo Moya +Copyright=Copyright © 2007 The MATE Foundation +Website= diff --git a/plugins/font/gsd-font-manager.c b/plugins/font/gsd-font-manager.c new file mode 100644 index 0000000..ed33e1c --- /dev/null +++ b/plugins/font/gsd-font-manager.c @@ -0,0 +1,440 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 The MATE Foundation + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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 <sys/types.h> +#include <sys/wait.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <sys/stat.h> +#include <dirent.h> + +#include <locale.h> + +#include <X11/Xatom.h> + +#include <glib.h> +#include <glib/gi18n.h> +#include <gdk/gdk.h> +#include <gdk/gdkx.h> +#include <gtk/gtk.h> +#include <mateconf/mateconf.h> +#include <mateconf/mateconf-client.h> + +#include "mate-settings-profile.h" +#include "gsd-font-manager.h" +#include "delayed-dialog.h" + +static void gsd_font_manager_class_init (GsdFontManagerClass *klass); +static void gsd_font_manager_init (GsdFontManager *font_manager); + +G_DEFINE_TYPE (GsdFontManager, gsd_font_manager, G_TYPE_OBJECT) + +static gpointer manager_object = NULL; + +static void +update_property (GString *props, const gchar* key, const gchar* value) +{ + gchar* needle; + size_t needle_len; + gchar* found = NULL; + + /* update an existing property */ + needle = g_strconcat (key, ":", NULL); + needle_len = strlen (needle); + if (g_str_has_prefix (props->str, needle)) + found = props->str; + else + found = strstr (props->str, needle); + + if (found) { + size_t value_index; + gchar* end; + + end = strchr (found, '\n'); + value_index = (found - props->str) + needle_len + 1; + g_string_erase (props, value_index, end ? (end - found - needle_len) : -1); + g_string_insert (props, value_index, "\n"); + g_string_insert (props, value_index, value); + } else { + g_string_append_printf (props, "%s:\t%s\n", key, value); + } +} + +static void +load_xcursor_theme (MateConfClient *client) +{ + char *cursor_theme; + int size; + GString *add_string; + Display *dpy; + gchar numbuf[20]; + + mate_settings_profile_start (NULL); + + size = mateconf_client_get_int (client, + "/desktop/mate/peripherals/mouse/cursor_size", + NULL); + if (size <= 0) { + return; + } + + cursor_theme = mateconf_client_get_string (client, + "/desktop/mate/peripherals/mouse/cursor_theme", + NULL); + if (cursor_theme == NULL) { + return; + } + + /* get existing properties */ + dpy = XOpenDisplay (NULL); + g_return_if_fail (dpy != NULL); + add_string = g_string_new (XResourceManagerString (dpy)); + g_debug("load_xcursor_theme: existing res '%s'", add_string->str); + + update_property (add_string, "Xcursor.theme", cursor_theme); + update_property (add_string, "Xcursor.theme_core", "true"); + g_snprintf (numbuf, sizeof (numbuf), "%i", size); + update_property (add_string, "Xcursor.size", numbuf); + + g_debug("load_xcursor_theme: new res '%s'", add_string->str); + + /* Set the new X property */ + XChangeProperty(dpy, RootWindow (dpy, 0), + XA_RESOURCE_MANAGER, XA_STRING, 8, PropModeReplace, add_string->str, add_string->len); + XCloseDisplay (dpy); + + g_free (cursor_theme); + g_string_free (add_string, TRUE); + + mate_settings_profile_end (NULL); +} + +static char* +setup_dir (const char *font_dir_name, gboolean create) +{ + char *font_dir; + + font_dir = g_build_path (G_DIR_SEPARATOR_S, g_get_home_dir (), ".mate2", "share", font_dir_name, NULL); + + if (create) { + if (g_mkdir_with_parents (font_dir, 0755) != 0) { + g_warning ("Cannot create needed directory \"%s\".", font_dir); + g_free (font_dir); + font_dir = NULL; + } + } else if (! g_file_test (font_dir, G_FILE_TEST_EXISTS)) { + g_free (font_dir); + font_dir = NULL; + } + + return font_dir; +} + +static char * +empty_check_dir (char *font_dir) +{ + char *file_name; + + if (!font_dir) + return NULL; + + /* remove the fonts.dir and fonts.scale files that mkfontdir generates. */ + + file_name = g_build_filename (G_DIR_SEPARATOR_S, font_dir, "fonts.dir", NULL); + unlink (file_name); + g_free (file_name); + + file_name = g_build_filename (G_DIR_SEPARATOR_S, font_dir, "fonts.scale", NULL); + unlink (file_name); + g_free (file_name); + + /* if it's empty, get rid of it. */ + if (0 == rmdir (font_dir)) { + g_free (font_dir); + font_dir = NULL; + } + + return font_dir; +} + +static char* +setup_font_dir (MateConfClient *client) +{ + return empty_check_dir (setup_dir ("fonts", FALSE)); +} + +static char* +setup_cursor_dir (MateConfClient *client) +{ + char *cursor_dir; + char *cursor_font; + DIR *dir; + struct dirent *file_dirent; + + cursor_font = mateconf_client_get_string (client, + "/desktop/mate/peripherals/mouse/cursor_font", + NULL); + if (cursor_font != NULL) { + if (!g_path_is_absolute (cursor_font) || + !g_file_test (cursor_font, G_FILE_TEST_IS_REGULAR)) { + /* font file is not usable */ + g_free (cursor_font); + cursor_font = NULL; + } + } + + cursor_dir = setup_dir ("cursor-fonts", cursor_font != NULL); + + /* remove previously made symlinks, if any */ + if (cursor_dir) { + dir = opendir (cursor_dir); + while ((file_dirent = readdir (dir)) != NULL) { + struct stat st; + char *link_name; + + link_name = g_build_filename (cursor_dir, file_dirent->d_name, NULL); + if (lstat (link_name, &st)) { + g_free (link_name); + continue; + } + g_free (link_name); + + if (S_ISLNK (st.st_mode)) + unlink (link_name); + } + closedir (dir); + } + + if (cursor_font && cursor_dir) { + char *newpath; + char *font_name; + + font_name = strrchr (cursor_font, G_DIR_SEPARATOR); + newpath = g_build_filename (cursor_dir, font_name, NULL); + symlink (cursor_font, newpath); + g_free (newpath); + g_free (cursor_font); + cursor_font = NULL; + } else { + cursor_dir = empty_check_dir (cursor_dir); + } + + return cursor_dir; +} + +static void +load_font_paths (MateConfClient *client) +{ + char *font_dir_name; + char *cursor_dir_name; + + char **font_path; + char **new_font_path; + int n_fonts; + int new_n_fonts; + + int i; + + const char *argv[4]; + int argc = 0; + + mate_settings_profile_start (NULL); + + font_dir_name = setup_font_dir (client); + cursor_dir_name = setup_cursor_dir (client); + + if (font_dir_name == NULL && cursor_dir_name == NULL) + goto done; + + /* run mkfontdir */ + argv[argc++] = "mkfontdir"; + if (font_dir_name) + argv[argc++] = font_dir_name; + if (cursor_dir_name) + argv[argc++] = cursor_dir_name; + argv[argc] = NULL; + g_spawn_sync (NULL, /* current dir */ + (char **) (void *) argv, NULL /* envp */, + G_SPAWN_SEARCH_PATH, + NULL, NULL, /* child_setup */ + NULL, NULL, NULL, NULL); + + /* Set the font path */ + font_path = XGetFontPath (gdk_x11_get_default_xdisplay (), &n_fonts); + new_n_fonts = n_fonts; + if (cursor_dir_name && (n_fonts == 0 || strcmp (font_path[0], cursor_dir_name))) + new_n_fonts++; + if (font_dir_name && (n_fonts == 0 || strcmp (font_path[n_fonts-1], font_dir_name))) + new_n_fonts++; + + if (new_n_fonts == n_fonts) + new_font_path = font_path; + else { + new_font_path = g_new0 (char *, new_n_fonts); + + if (cursor_dir_name && (n_fonts == 0 || strcmp (font_path[0], cursor_dir_name))) { + new_font_path[0] = cursor_dir_name; + for (i = 0; i < n_fonts; i++) + new_font_path [i+1] = font_path [i]; + } else { + for (i = 0; i < n_fonts; i++) + new_font_path [i] = font_path [i]; + } + + if (font_dir_name && (n_fonts == 0 || strcmp (font_path[n_fonts-1], font_dir_name))) { + new_font_path[new_n_fonts-1] = font_dir_name; + } + } + + /* We set font path even if it was not changed, to enforce dropping + * caches in the server */ + gdk_error_trap_push (); + XSetFontPath (gdk_display, new_font_path, new_n_fonts); + gdk_flush (); + + /* if there was an error setting the new path, revert */ + if (gdk_error_trap_pop ()) { + XSetFontPath (gdk_display, font_path, n_fonts); + } + + g_free (font_dir_name); + g_free (cursor_dir_name); + + if (new_font_path != font_path) + g_free (new_font_path); + + XFreeFontPath (font_path); + +done: + mate_settings_profile_end (NULL); +} + +gboolean +gsd_font_manager_start (GsdFontManager *manager, + GError **error) +{ + MateConfClient *client; + + g_debug ("Starting font manager"); + mate_settings_profile_start (NULL); + + client = mateconf_client_get_default (); + + load_xcursor_theme (client); + load_font_paths (client); + + g_object_unref (client); + + mate_settings_profile_end (NULL); + + return TRUE; +} + +void +gsd_font_manager_stop (GsdFontManager *manager) +{ + g_debug ("Stopping font manager"); +} + +static void +gsd_font_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GsdFontManager *self; + + self = GSD_FONT_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gsd_font_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GsdFontManager *self; + + self = GSD_FONT_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +gsd_font_manager_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GsdFontManager *font_manager; + GsdFontManagerClass *klass; + + klass = GSD_FONT_MANAGER_CLASS (g_type_class_peek (GSD_TYPE_FONT_MANAGER)); + + font_manager = GSD_FONT_MANAGER (G_OBJECT_CLASS (gsd_font_manager_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + + return G_OBJECT (font_manager); +} + +static void +gsd_font_manager_class_init (GsdFontManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gsd_font_manager_get_property; + object_class->set_property = gsd_font_manager_set_property; + object_class->constructor = gsd_font_manager_constructor; +} + +static void +gsd_font_manager_init (GsdFontManager *manager) +{ +} + +GsdFontManager * +gsd_font_manager_new (void) +{ + if (manager_object != NULL) { + g_object_ref (manager_object); + } else { + manager_object = g_object_new (GSD_TYPE_FONT_MANAGER, NULL); + g_object_add_weak_pointer (manager_object, + (gpointer *) &manager_object); + } + + return GSD_FONT_MANAGER (manager_object); +} diff --git a/plugins/font/gsd-font-manager.h b/plugins/font/gsd-font-manager.h new file mode 100644 index 0000000..be53d98 --- /dev/null +++ b/plugins/font/gsd-font-manager.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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_FONT_MANAGER_H +#define __GSD_FONT_MANAGER_H + +#include <glib-object.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_FONT_MANAGER (gsd_font_manager_get_type ()) +#define GSD_FONT_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_FONT_MANAGER, GsdFontManager)) +#define GSD_FONT_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_FONT_MANAGER, GsdFontManagerClass)) +#define GSD_IS_FONT_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_FONT_MANAGER)) +#define GSD_IS_FONT_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_FONT_MANAGER)) +#define GSD_FONT_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_FONT_MANAGER, GsdFontManagerClass)) + +typedef struct GsdFontManagerPrivate GsdFontManagerPrivate; + +typedef struct +{ + GObject parent; + GsdFontManagerPrivate *priv; +} GsdFontManager; + +typedef struct +{ + GObjectClass parent_class; +} GsdFontManagerClass; + +GType gsd_font_manager_get_type (void); + +GsdFontManager * gsd_font_manager_new (void); +gboolean gsd_font_manager_start (GsdFontManager *manager, + GError **error); +void gsd_font_manager_stop (GsdFontManager *manager); + +#ifdef __cplusplus +} +#endif + +#endif /* __GSD_FONT_MANAGER_H */ diff --git a/plugins/font/gsd-font-plugin.c b/plugins/font/gsd-font-plugin.c new file mode 100644 index 0000000..dc34c6b --- /dev/null +++ b/plugins/font/gsd-font-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 <[email protected]> + * + * 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 <glib/gi18n-lib.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" +#include "gsd-font-plugin.h" +#include "gsd-font-manager.h" + +struct GsdFontPluginPrivate { + GsdFontManager *manager; +}; + +#define GSD_FONT_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSD_TYPE_FONT_PLUGIN, GsdFontPluginPrivate)) + +MATE_SETTINGS_PLUGIN_REGISTER (GsdFontPlugin, gsd_font_plugin) + +static void +gsd_font_plugin_init (GsdFontPlugin *plugin) +{ + plugin->priv = GSD_FONT_PLUGIN_GET_PRIVATE (plugin); + + g_debug ("GsdFontPlugin initializing"); + + plugin->priv->manager = gsd_font_manager_new (); +} + +static void +gsd_font_plugin_finalize (GObject *object) +{ + GsdFontPlugin *plugin; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_FONT_PLUGIN (object)); + + g_debug ("GsdFontPlugin finalizing"); + + plugin = GSD_FONT_PLUGIN (object); + + g_return_if_fail (plugin->priv != NULL); + + if (plugin->priv->manager != NULL) { + g_object_unref (plugin->priv->manager); + } + + G_OBJECT_CLASS (gsd_font_plugin_parent_class)->finalize (object); +} + +static void +impl_activate (MateSettingsPlugin *plugin) +{ + gboolean res; + GError *error; + + g_debug ("Activating font plugin"); + + error = NULL; + res = gsd_font_manager_start (GSD_FONT_PLUGIN (plugin)->priv->manager, &error); + if (! res) { + g_warning ("Unable to start font manager: %s", error->message); + g_error_free (error); + } +} + +static void +impl_deactivate (MateSettingsPlugin *plugin) +{ + g_debug ("Deactivating font plugin"); + gsd_font_manager_stop (GSD_FONT_PLUGIN (plugin)->priv->manager); +} + +static void +gsd_font_plugin_class_init (GsdFontPluginClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MateSettingsPluginClass *plugin_class = MATE_SETTINGS_PLUGIN_CLASS (klass); + + object_class->finalize = gsd_font_plugin_finalize; + + plugin_class->activate = impl_activate; + plugin_class->deactivate = impl_deactivate; + + g_type_class_add_private (klass, sizeof (GsdFontPluginPrivate)); +} diff --git a/plugins/font/gsd-font-plugin.h b/plugins/font/gsd-font-plugin.h new file mode 100644 index 0000000..06dd2be --- /dev/null +++ b/plugins/font/gsd-font-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 <[email protected]> + * + * 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_FONT_PLUGIN_H__ +#define __GSD_FONT_PLUGIN_H__ + +#include <glib.h> +#include <glib-object.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_FONT_PLUGIN (gsd_font_plugin_get_type ()) +#define GSD_FONT_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_FONT_PLUGIN, GsdFontPlugin)) +#define GSD_FONT_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_FONT_PLUGIN, GsdFontPluginClass)) +#define GSD_IS_FONT_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_FONT_PLUGIN)) +#define GSD_IS_FONT_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_FONT_PLUGIN)) +#define GSD_FONT_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_FONT_PLUGIN, GsdFontPluginClass)) + +typedef struct GsdFontPluginPrivate GsdFontPluginPrivate; + +typedef struct +{ + MateSettingsPlugin parent; + GsdFontPluginPrivate *priv; +} GsdFontPlugin; + +typedef struct +{ + MateSettingsPluginClass parent_class; +} GsdFontPluginClass; + +GType gsd_font_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_FONT_PLUGIN_H__ */ diff --git a/plugins/housekeeping/Makefile.am b/plugins/housekeeping/Makefile.am new file mode 100644 index 0000000..485d4ed --- /dev/null +++ b/plugins/housekeeping/Makefile.am @@ -0,0 +1,40 @@ +plugin_LTLIBRARIES = libhousekeeping.la + +libhousekeeping_la_SOURCES = \ + gsd-ldsm-dialog.c \ + gsd-ldsm-dialog.h \ + gsd-ldsm-trash-empty.c \ + gsd-ldsm-trash-empty.h \ + gsd-disk-space.c \ + gsd-disk-space.h \ + gsd-housekeeping-manager.c \ + gsd-housekeeping-manager.h \ + gsd-housekeeping-plugin.c \ + gsd-housekeeping-plugin.h + +libhousekeeping_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libhousekeeping_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(GIOUNIX_CFLAGS) \ + $(LIBMATENOTIFY_CFLAGS) \ + $(AM_CFLAGS) + +libhousekeeping_la_LDFLAGS = $(GSD_PLUGIN_LDFLAGS) + +libhousekeeping_la_LIBADD = $(SETTINGS_PLUGIN_LIBS) $(GIOUNIX_LIBS) $(LIBMATENOTIFY_LIBS) + +plugin_in_files = housekeeping.mate-settings-plugin.in + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) + +EXTRA_DIST = $(plugin_in_files) + +CLEANFILES = $(plugin_DATA) + +DISTCLEANFILES = (plugin_DATA) + +@GSD_INTLTOOL_PLUGIN_RULE@ diff --git a/plugins/housekeeping/Makefile.in b/plugins/housekeeping/Makefile.in new file mode 100644 index 0000000..806a4d5 --- /dev/null +++ b/plugins/housekeeping/Makefile.in @@ -0,0 +1,689 @@ +# 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/housekeeping +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)$(plugindir)" +LTLIBRARIES = $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +libhousekeeping_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_libhousekeeping_la_OBJECTS = libhousekeeping_la-gsd-ldsm-dialog.lo \ + libhousekeeping_la-gsd-ldsm-trash-empty.lo \ + libhousekeeping_la-gsd-disk-space.lo \ + libhousekeeping_la-gsd-housekeeping-manager.lo \ + libhousekeeping_la-gsd-housekeeping-plugin.lo +libhousekeeping_la_OBJECTS = $(am_libhousekeeping_la_OBJECTS) +libhousekeeping_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libhousekeeping_la_CFLAGS) $(CFLAGS) \ + $(libhousekeeping_la_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 = $(libhousekeeping_la_SOURCES) +DIST_SOURCES = $(libhousekeeping_la_SOURCES) +DATA = $(plugin_DATA) +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@ +plugin_LTLIBRARIES = libhousekeeping.la +libhousekeeping_la_SOURCES = \ + gsd-ldsm-dialog.c \ + gsd-ldsm-dialog.h \ + gsd-ldsm-trash-empty.c \ + gsd-ldsm-trash-empty.h \ + gsd-disk-space.c \ + gsd-disk-space.h \ + gsd-housekeeping-manager.c \ + gsd-housekeeping-manager.h \ + gsd-housekeeping-plugin.c \ + gsd-housekeeping-plugin.h + +libhousekeeping_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libhousekeeping_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(GIOUNIX_CFLAGS) \ + $(LIBMATENOTIFY_CFLAGS) \ + $(AM_CFLAGS) + +libhousekeeping_la_LDFLAGS = $(GSD_PLUGIN_LDFLAGS) +libhousekeeping_la_LIBADD = $(SETTINGS_PLUGIN_LIBS) $(GIOUNIX_LIBS) $(LIBMATENOTIFY_LIBS) +plugin_in_files = housekeeping.mate-settings-plugin.in +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) +EXTRA_DIST = $(plugin_in_files) +CLEANFILES = $(plugin_DATA) +DISTCLEANFILES = (plugin_DATA) +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/housekeeping/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plugins/housekeeping/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 +libhousekeeping.la: $(libhousekeeping_la_OBJECTS) $(libhousekeeping_la_DEPENDENCIES) + $(libhousekeeping_la_LINK) -rpath $(plugindir) $(libhousekeeping_la_OBJECTS) $(libhousekeeping_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhousekeeping_la-gsd-disk-space.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhousekeeping_la-gsd-housekeeping-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhousekeeping_la-gsd-housekeeping-plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhousekeeping_la-gsd-ldsm-dialog.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhousekeeping_la-gsd-ldsm-trash-empty.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 $@ $< + +libhousekeeping_la-gsd-ldsm-dialog.lo: gsd-ldsm-dialog.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhousekeeping_la_CPPFLAGS) $(CPPFLAGS) $(libhousekeeping_la_CFLAGS) $(CFLAGS) -MT libhousekeeping_la-gsd-ldsm-dialog.lo -MD -MP -MF $(DEPDIR)/libhousekeeping_la-gsd-ldsm-dialog.Tpo -c -o libhousekeeping_la-gsd-ldsm-dialog.lo `test -f 'gsd-ldsm-dialog.c' || echo '$(srcdir)/'`gsd-ldsm-dialog.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libhousekeeping_la-gsd-ldsm-dialog.Tpo $(DEPDIR)/libhousekeeping_la-gsd-ldsm-dialog.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-ldsm-dialog.c' object='libhousekeeping_la-gsd-ldsm-dialog.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) $(libhousekeeping_la_CPPFLAGS) $(CPPFLAGS) $(libhousekeeping_la_CFLAGS) $(CFLAGS) -c -o libhousekeeping_la-gsd-ldsm-dialog.lo `test -f 'gsd-ldsm-dialog.c' || echo '$(srcdir)/'`gsd-ldsm-dialog.c + +libhousekeeping_la-gsd-ldsm-trash-empty.lo: gsd-ldsm-trash-empty.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhousekeeping_la_CPPFLAGS) $(CPPFLAGS) $(libhousekeeping_la_CFLAGS) $(CFLAGS) -MT libhousekeeping_la-gsd-ldsm-trash-empty.lo -MD -MP -MF $(DEPDIR)/libhousekeeping_la-gsd-ldsm-trash-empty.Tpo -c -o libhousekeeping_la-gsd-ldsm-trash-empty.lo `test -f 'gsd-ldsm-trash-empty.c' || echo '$(srcdir)/'`gsd-ldsm-trash-empty.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libhousekeeping_la-gsd-ldsm-trash-empty.Tpo $(DEPDIR)/libhousekeeping_la-gsd-ldsm-trash-empty.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-ldsm-trash-empty.c' object='libhousekeeping_la-gsd-ldsm-trash-empty.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) $(libhousekeeping_la_CPPFLAGS) $(CPPFLAGS) $(libhousekeeping_la_CFLAGS) $(CFLAGS) -c -o libhousekeeping_la-gsd-ldsm-trash-empty.lo `test -f 'gsd-ldsm-trash-empty.c' || echo '$(srcdir)/'`gsd-ldsm-trash-empty.c + +libhousekeeping_la-gsd-disk-space.lo: gsd-disk-space.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhousekeeping_la_CPPFLAGS) $(CPPFLAGS) $(libhousekeeping_la_CFLAGS) $(CFLAGS) -MT libhousekeeping_la-gsd-disk-space.lo -MD -MP -MF $(DEPDIR)/libhousekeeping_la-gsd-disk-space.Tpo -c -o libhousekeeping_la-gsd-disk-space.lo `test -f 'gsd-disk-space.c' || echo '$(srcdir)/'`gsd-disk-space.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libhousekeeping_la-gsd-disk-space.Tpo $(DEPDIR)/libhousekeeping_la-gsd-disk-space.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-disk-space.c' object='libhousekeeping_la-gsd-disk-space.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) $(libhousekeeping_la_CPPFLAGS) $(CPPFLAGS) $(libhousekeeping_la_CFLAGS) $(CFLAGS) -c -o libhousekeeping_la-gsd-disk-space.lo `test -f 'gsd-disk-space.c' || echo '$(srcdir)/'`gsd-disk-space.c + +libhousekeeping_la-gsd-housekeeping-manager.lo: gsd-housekeeping-manager.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhousekeeping_la_CPPFLAGS) $(CPPFLAGS) $(libhousekeeping_la_CFLAGS) $(CFLAGS) -MT libhousekeeping_la-gsd-housekeeping-manager.lo -MD -MP -MF $(DEPDIR)/libhousekeeping_la-gsd-housekeeping-manager.Tpo -c -o libhousekeeping_la-gsd-housekeeping-manager.lo `test -f 'gsd-housekeeping-manager.c' || echo '$(srcdir)/'`gsd-housekeeping-manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libhousekeeping_la-gsd-housekeeping-manager.Tpo $(DEPDIR)/libhousekeeping_la-gsd-housekeeping-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-housekeeping-manager.c' object='libhousekeeping_la-gsd-housekeeping-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) $(libhousekeeping_la_CPPFLAGS) $(CPPFLAGS) $(libhousekeeping_la_CFLAGS) $(CFLAGS) -c -o libhousekeeping_la-gsd-housekeeping-manager.lo `test -f 'gsd-housekeeping-manager.c' || echo '$(srcdir)/'`gsd-housekeeping-manager.c + +libhousekeeping_la-gsd-housekeeping-plugin.lo: gsd-housekeeping-plugin.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhousekeeping_la_CPPFLAGS) $(CPPFLAGS) $(libhousekeeping_la_CFLAGS) $(CFLAGS) -MT libhousekeeping_la-gsd-housekeeping-plugin.lo -MD -MP -MF $(DEPDIR)/libhousekeeping_la-gsd-housekeeping-plugin.Tpo -c -o libhousekeeping_la-gsd-housekeeping-plugin.lo `test -f 'gsd-housekeeping-plugin.c' || echo '$(srcdir)/'`gsd-housekeeping-plugin.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libhousekeeping_la-gsd-housekeeping-plugin.Tpo $(DEPDIR)/libhousekeeping_la-gsd-housekeeping-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-housekeeping-plugin.c' object='libhousekeeping_la-gsd-housekeeping-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) $(libhousekeeping_la_CPPFLAGS) $(CPPFLAGS) $(libhousekeeping_la_CFLAGS) $(CFLAGS) -c -o libhousekeeping_la-gsd-housekeeping-plugin.lo `test -f 'gsd-housekeeping-plugin.c' || echo '$(srcdir)/'`gsd-housekeeping-plugin.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +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 + +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) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -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." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ + 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-pluginDATA install-pluginLTLIBRARIES + +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: uninstall-pluginDATA uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-pluginLTLIBRARIES 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-pluginDATA \ + install-pluginLTLIBRARIES 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 \ + uninstall-pluginDATA uninstall-pluginLTLIBRARIES + + +@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/housekeeping/gsd-disk-space.c b/plugins/housekeeping/gsd-disk-space.c new file mode 100644 index 0000000..951264f --- /dev/null +++ b/plugins/housekeeping/gsd-disk-space.c @@ -0,0 +1,733 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * vim: set et sw=8 ts=8: + * + * Copyright (c) 2008, Novell, Inc. + * + * Authors: Vincent Untz <[email protected]> + * + * 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. + * + */ + +/* gcc -DHAVE_LIBMATENOTIFY -DTEST -Wall `pkg-config --cflags --libs gobject-2.0 gio-unix-2.0 glib-2.0 gtk+-2.0 libmatenotify` -o gsd-disk-space-test gsd-disk-space.c */ + +#include "config.h" + +#include <sys/statvfs.h> +#include <time.h> +#include <unistd.h> + +#include <glib.h> +#include <glib/gi18n.h> +#include <glib-object.h> +#include <gio/gunixmounts.h> +#include <gio/gio.h> +#include <gtk/gtk.h> +#include <mateconf/mateconf-client.h> + +#include "gsd-disk-space.h" +#include "gsd-ldsm-dialog.h" +#include "gsd-ldsm-trash-empty.h" + + +#define GIGABYTE 1024 * 1024 * 1024 + +#define CHECK_EVERY_X_SECONDS 60 + +#define DISK_SPACE_ANALYZER "baobab" + +#define MATECONF_HOUSEKEEPING_DIR "/apps/mate_settings_daemon/plugins/housekeeping" +#define MATECONF_FREE_PC_NOTIFY_KEY "free_percent_notify" +#define MATECONF_FREE_PC_NOTIFY_AGAIN_KEY "free_percent_notify_again" +#define MATECONF_FREE_SIZE_NO_NOTIFY "free_size_gb_no_notify" +#define MATECONF_MIN_NOTIFY_PERIOD "min_notify_period" +#define MATECONF_IGNORE_PATHS "ignore_paths" + +typedef struct +{ + GUnixMountEntry *mount; + struct statvfs buf; + time_t notify_time; +} LdsmMountInfo; + +static GHashTable *ldsm_notified_hash = NULL; +static unsigned int ldsm_timeout_id = 0; +static GUnixMountMonitor *ldsm_monitor = NULL; +static double free_percent_notify = 0.05; +static double free_percent_notify_again = 0.01; +static unsigned int free_size_gb_no_notify = 2; +static unsigned int min_notify_period = 10; +static GSList *ignore_paths = NULL; +static unsigned int mateconf_notify_id; +static MateConfClient *client = NULL; +static GsdLdsmDialog *dialog = NULL; +static guint64 *time_read; + +static gchar* +ldsm_get_fs_id_for_path (const gchar *path) +{ + GFile *file; + GFileInfo *fileinfo; + gchar *attr_id_fs; + + file = g_file_new_for_path (path); + fileinfo = g_file_query_info (file, G_FILE_ATTRIBUTE_ID_FILESYSTEM, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, NULL); + if (fileinfo) { + attr_id_fs = g_strdup (g_file_info_get_attribute_string (fileinfo, G_FILE_ATTRIBUTE_ID_FILESYSTEM)); + g_object_unref (fileinfo); + } else { + attr_id_fs = NULL; + } + + g_object_unref (file); + + return attr_id_fs; +} + +static gboolean +ldsm_mount_has_trash (LdsmMountInfo *mount) +{ + const gchar *user_data_dir; + gchar *user_data_attr_id_fs; + gchar *path_attr_id_fs; + gboolean mount_uses_user_trash = FALSE; + gchar *trash_files_dir; + gboolean has_trash = FALSE; + GDir *dir; + const gchar *path; + + user_data_dir = g_get_user_data_dir (); + user_data_attr_id_fs = ldsm_get_fs_id_for_path (user_data_dir); + + path = g_unix_mount_get_mount_path (mount->mount); + path_attr_id_fs = ldsm_get_fs_id_for_path (path); + + if (g_strcmp0 (user_data_attr_id_fs, path_attr_id_fs) == 0) { + /* The volume that is low on space is on the same volume as our home + * directory. This means the trash is at $XDG_DATA_HOME/Trash, + * not at the root of the volume which is full. + */ + mount_uses_user_trash = TRUE; + } + + g_free (user_data_attr_id_fs); + g_free (path_attr_id_fs); + + /* I can't think of a better way to find out if a volume has any trash. Any suggestions? */ + if (mount_uses_user_trash) { + trash_files_dir = g_build_filename (g_get_user_data_dir (), "Trash", "files", NULL); + } else { + gchar *uid; + + uid = g_strdup_printf ("%d", getuid ()); + trash_files_dir = g_build_filename (path, ".Trash", uid, "files", NULL); + if (!g_file_test (trash_files_dir, G_FILE_TEST_IS_DIR)) { + gchar *trash_dir; + + g_free (trash_files_dir); + trash_dir = g_strdup_printf (".Trash-%s", uid); + trash_files_dir = g_build_filename (path, trash_dir, "files", NULL); + g_free (trash_dir); + if (!g_file_test (trash_files_dir, G_FILE_TEST_IS_DIR)) { + g_free (trash_files_dir); + g_free (uid); + return has_trash; + } + } + g_free (uid); + } + + dir = g_dir_open (trash_files_dir, 0, NULL); + if (dir) { + if (g_dir_read_name (dir)) + has_trash = TRUE; + g_dir_close (dir); + } + + g_free (trash_files_dir); + + return has_trash; +} + +static void +ldsm_analyze_path (const gchar *path) +{ + const gchar *argv[] = { DISK_SPACE_ANALYZER, path, NULL }; + + g_spawn_async (NULL, (gchar **) argv, NULL, G_SPAWN_SEARCH_PATH, + NULL, NULL, NULL, NULL); +} + +static gboolean +ldsm_notify_for_mount (LdsmMountInfo *mount, + gboolean multiple_volumes, + gboolean other_usable_volumes) +{ + gchar *name, *program; + gint64 free_space; + gint response; + gboolean has_trash; + gboolean has_disk_analyzer; + gboolean retval = TRUE; + const gchar *path; + + /* Don't show a dialog if one is already displayed */ + if (dialog) + return retval; + + name = g_unix_mount_guess_name (mount->mount); + free_space = (gint64) mount->buf.f_frsize * (gint64) mount->buf.f_bavail; + has_trash = ldsm_mount_has_trash (mount); + path = g_unix_mount_get_mount_path (mount->mount); + + program = g_find_program_in_path (DISK_SPACE_ANALYZER); + has_disk_analyzer = (program != NULL); + g_free (program); + + dialog = gsd_ldsm_dialog_new (other_usable_volumes, + multiple_volumes, + has_disk_analyzer, + has_trash, + free_space, + name, + path); + + g_free (name); + + g_object_ref (G_OBJECT (dialog)); + response = gtk_dialog_run (GTK_DIALOG (dialog)); + + gtk_object_destroy (GTK_OBJECT (dialog)); + dialog = NULL; + + switch (response) { + case GTK_RESPONSE_CANCEL: + retval = FALSE; + break; + case GSD_LDSM_DIALOG_RESPONSE_ANALYZE: + retval = FALSE; + ldsm_analyze_path (g_unix_mount_get_mount_path (mount->mount)); + break; + case GSD_LDSM_DIALOG_RESPONSE_EMPTY_TRASH: + retval = TRUE; + gsd_ldsm_trash_empty (); + break; + case GTK_RESPONSE_NONE: + case GTK_RESPONSE_DELETE_EVENT: + retval = TRUE; + break; + default: + g_assert_not_reached (); + } + + return retval; +} + +static gboolean +ldsm_mount_has_space (LdsmMountInfo *mount) +{ + gdouble free_space; + + free_space = (double) mount->buf.f_bavail / (double) mount->buf.f_blocks; + /* enough free space, nothing to do */ + if (free_space > free_percent_notify) + return TRUE; + + if (((gint64) mount->buf.f_frsize * (gint64) mount->buf.f_bavail) > ((gint64) free_size_gb_no_notify * GIGABYTE)) + return TRUE; + + /* If we got here, then this volume is low on space */ + return FALSE; +} + +static gboolean +ldsm_mount_is_virtual (LdsmMountInfo *mount) +{ + if (mount->buf.f_blocks == 0) { + /* Filesystems with zero blocks are virtual */ + return TRUE; + } + + return FALSE; +} + +static gint +ldsm_ignore_path_compare (gconstpointer a, + gconstpointer b) +{ + return g_strcmp0 ((const gchar *)a, (const gchar *)b); +} + +static gboolean +ldsm_mount_is_user_ignore (const gchar *path) +{ + if (g_slist_find_custom (ignore_paths, path, (GCompareFunc) ldsm_ignore_path_compare) != NULL) + return TRUE; + else + return FALSE; +} + + +static gboolean +is_in (const gchar *value, const gchar *set[]) +{ + int i; + for (i = 0; set[i] != NULL; i++) + { + if (strcmp (set[i], value) == 0) + return TRUE; + } + return FALSE; +} + +static gboolean +ldsm_mount_should_ignore (GUnixMountEntry *mount) +{ + const gchar *fs, *device, *path; + + path = g_unix_mount_get_mount_path (mount); + if (ldsm_mount_is_user_ignore (path)) + return TRUE; + + /* This is borrowed from GLib and used as a way to determine + * which mounts we should ignore by default. GLib doesn't + * expose this in a way that allows it to be used for this + * purpose + */ + + const gchar *ignore_fs[] = { + "auto", + "autofs", + "devfs", + "devpts", + "ecryptfs", + "kernfs", + "linprocfs", + "proc", + "procfs", + "ptyfs", + "selinuxfs", + "linsysfs", + "sysfs", + "tmpfs", + "usbfs", + "nfsd", + "rpc_pipefs", + "zfs", + NULL + }; + const gchar *ignore_devices[] = { + "none", + "sunrpc", + "devpts", + "nfsd", + "/dev/loop", + "/dev/vn", + NULL + }; + + fs = g_unix_mount_get_fs_type (mount); + device = g_unix_mount_get_device_path (mount); + + if (is_in (fs, ignore_fs)) + return TRUE; + + if (is_in (device, ignore_devices)) + return TRUE; + + return FALSE; +} + +static void +ldsm_free_mount_info (gpointer data) +{ + LdsmMountInfo *mount = data; + + g_return_if_fail (mount != NULL); + + g_unix_mount_free (mount->mount); + g_free (mount); +} + +static void +ldsm_maybe_warn_mounts (GList *mounts, + gboolean multiple_volumes, + gboolean other_usable_volumes) +{ + GList *l; + gboolean done = FALSE; + + for (l = mounts; l != NULL; l = l->next) { + LdsmMountInfo *mount_info = l->data; + LdsmMountInfo *previous_mount_info; + gdouble free_space; + gdouble previous_free_space; + time_t curr_time; + const gchar *path; + gboolean show_notify; + + if (done) { + /* Don't show any more dialogs if the user took action with the last one. The user action + * might free up space on multiple volumes, making the next dialog redundant. + */ + ldsm_free_mount_info (mount_info); + continue; + } + + path = g_unix_mount_get_mount_path (mount_info->mount); + + previous_mount_info = g_hash_table_lookup (ldsm_notified_hash, path); + if (previous_mount_info != NULL) + previous_free_space = (gdouble) previous_mount_info->buf.f_bavail / (gdouble) previous_mount_info->buf.f_blocks; + + free_space = (gdouble) mount_info->buf.f_bavail / (gdouble) mount_info->buf.f_blocks; + + if (previous_mount_info == NULL) { + /* We haven't notified for this mount yet */ + show_notify = TRUE; + mount_info->notify_time = time (NULL); + g_hash_table_replace (ldsm_notified_hash, g_strdup (path), mount_info); + } else if ((previous_free_space - free_space) > free_percent_notify_again) { + /* We've notified for this mount before and free space has decreased sufficiently since last time to notify again */ + curr_time = time (NULL); + if (difftime (curr_time, previous_mount_info->notify_time) > (gdouble)(min_notify_period * 60)) { + show_notify = TRUE; + mount_info->notify_time = curr_time; + } else { + /* It's too soon to show the dialog again. However, we still replace the LdsmMountInfo + * struct in the hash table, but give it the notfiy time from the previous dialog. + * This will stop the notification from reappearing unnecessarily as soon as the timeout expires. + */ + show_notify = FALSE; + mount_info->notify_time = previous_mount_info->notify_time; + } + g_hash_table_replace (ldsm_notified_hash, g_strdup (path), mount_info); + } else { + /* We've notified for this mount before, but the free space hasn't decreased sufficiently to notify again */ + ldsm_free_mount_info (mount_info); + show_notify = FALSE; + } + + if (show_notify) { + if (ldsm_notify_for_mount (mount_info, multiple_volumes, other_usable_volumes)) + done = TRUE; + } + } +} + +static gboolean +ldsm_check_all_mounts (gpointer data) +{ + GList *mounts; + GList *l; + GList *check_mounts = NULL; + GList *full_mounts = NULL; + guint number_of_mounts; + guint number_of_full_mounts; + gboolean multiple_volumes = FALSE; + gboolean other_usable_volumes = FALSE; + + /* We iterate through the static mounts in /etc/fstab first, seeing if + * they're mounted by checking if the GUnixMountPoint has a corresponding GUnixMountEntry. + * Iterating through the static mounts means we automatically ignore dynamically mounted media. + */ + mounts = g_unix_mount_points_get (time_read); + + for (l = mounts; l != NULL; l = l->next) { + GUnixMountPoint *mount_point = l->data; + GUnixMountEntry *mount; + LdsmMountInfo *mount_info; + const gchar *path; + + path = g_unix_mount_point_get_mount_path (mount_point); + mount = g_unix_mount_at (path, time_read); + g_unix_mount_point_free (mount_point); + if (mount == NULL) { + /* The GUnixMountPoint is not mounted */ + continue; + } + + mount_info = g_new0 (LdsmMountInfo, 1); + mount_info->mount = mount; + + path = g_unix_mount_get_mount_path (mount); + + if (g_unix_mount_is_readonly (mount)) { + ldsm_free_mount_info (mount_info); + continue; + } + + if (ldsm_mount_should_ignore (mount)) { + ldsm_free_mount_info (mount_info); + continue; + } + + if (statvfs (path, &mount_info->buf) != 0) { + ldsm_free_mount_info (mount_info); + continue; + } + + if (ldsm_mount_is_virtual (mount_info)) { + ldsm_free_mount_info (mount_info); + continue; + } + + check_mounts = g_list_prepend (check_mounts, mount_info); + } + + number_of_mounts = g_list_length (check_mounts); + if (number_of_mounts > 1) + multiple_volumes = TRUE; + + for (l = check_mounts; l != NULL; l = l->next) { + LdsmMountInfo *mount_info = l->data; + + if (!ldsm_mount_has_space (mount_info)) { + full_mounts = g_list_prepend (full_mounts, mount_info); + } else { + g_hash_table_remove (ldsm_notified_hash, g_unix_mount_get_mount_path (mount_info->mount)); + ldsm_free_mount_info (mount_info); + } + } + + number_of_full_mounts = g_list_length (full_mounts); + if (number_of_mounts > number_of_full_mounts) + other_usable_volumes = TRUE; + + ldsm_maybe_warn_mounts (full_mounts, multiple_volumes, + other_usable_volumes); + + g_list_free (check_mounts); + g_list_free (full_mounts); + + return TRUE; +} + +static gboolean +ldsm_is_hash_item_not_in_mounts (gpointer key, + gpointer value, + gpointer user_data) +{ + GList *l; + + for (l = (GList *) user_data; l != NULL; l = l->next) { + GUnixMountEntry *mount = l->data; + const char *path; + + path = g_unix_mount_get_mount_path (mount); + + if (strcmp (path, key) == 0) + return FALSE; + } + + return TRUE; +} + +static void +ldsm_mounts_changed (GObject *monitor, + gpointer data) +{ + GList *mounts; + + /* remove the saved data for mounts that got removed */ + mounts = g_unix_mounts_get (time_read); + g_hash_table_foreach_remove (ldsm_notified_hash, + ldsm_is_hash_item_not_in_mounts, mounts); + g_list_foreach (mounts, (GFunc) g_unix_mount_free, NULL); + + /* check the status now, for the new mounts */ + ldsm_check_all_mounts (NULL); + + /* and reset the timeout */ + if (ldsm_timeout_id) + g_source_remove (ldsm_timeout_id); + ldsm_timeout_id = g_timeout_add_seconds (CHECK_EVERY_X_SECONDS, + ldsm_check_all_mounts, NULL); +} + +static gboolean +ldsm_is_hash_item_in_ignore_paths (gpointer key, + gpointer value, + gpointer user_data) +{ + return ldsm_mount_is_user_ignore (key); +} + +static void +gsd_ldsm_get_config () +{ + GError *error = NULL; + + free_percent_notify = mateconf_client_get_float (client, + MATECONF_HOUSEKEEPING_DIR "/" MATECONF_FREE_PC_NOTIFY_KEY, + &error); + if (error != NULL) { + g_warning ("Error reading configuration from MateConf: %s", error->message ? error->message : "Unknown error"); + g_clear_error (&error); + } + if (free_percent_notify >= 1 || free_percent_notify < 0) { + g_warning ("Invalid configuration of free_percent_notify: %f\n" \ + "Using sensible default", free_percent_notify); + free_percent_notify = 0.05; + } + + free_percent_notify_again = mateconf_client_get_float (client, + MATECONF_HOUSEKEEPING_DIR "/" MATECONF_FREE_PC_NOTIFY_AGAIN_KEY, + &error); + if (error != NULL) { + g_warning ("Error reading configuration from MateConf: %s", error->message ? error->message : "Unknown error"); + g_clear_error (&error); + } + if (free_percent_notify_again >= 1 || free_percent_notify_again < 0) { + g_warning ("Invalid configuration of free_percent_notify_again: %f\n" \ + "Using sensible default\n", free_percent_notify_again); + free_percent_notify_again = 0.01; + } + + free_size_gb_no_notify = mateconf_client_get_int (client, + MATECONF_HOUSEKEEPING_DIR "/" MATECONF_FREE_SIZE_NO_NOTIFY, + &error); + if (error != NULL) { + g_warning ("Error reading configuration from MateConf: %s", error->message ? error->message : "Unknown error"); + g_clear_error (&error); + } + min_notify_period = mateconf_client_get_int (client, + MATECONF_HOUSEKEEPING_DIR "/" MATECONF_MIN_NOTIFY_PERIOD, + &error); + if (error != NULL) { + g_warning ("Error reading configuration from MateConf: %s", error->message ? error->message : "Unkown error"); + g_clear_error (&error); + } + + if (ignore_paths != NULL) { + g_slist_foreach (ignore_paths, (GFunc) g_free, NULL); + g_slist_free (ignore_paths); + } + ignore_paths = mateconf_client_get_list (client, + MATECONF_HOUSEKEEPING_DIR "/" MATECONF_IGNORE_PATHS, + MATECONF_VALUE_STRING, &error); + if (error != NULL) { + g_warning ("Error reading configuration from MateConf: %s", error->message ? error->message : "Unkown error"); + g_clear_error (&error); + } else { + /* Make sure we dont leave stale entries in ldsm_notified_hash */ + g_hash_table_foreach_remove (ldsm_notified_hash, + ldsm_is_hash_item_in_ignore_paths, NULL); + } +} + +static void +gsd_ldsm_update_config (MateConfClient *client, + guint cnxn_id, + MateConfEntry *entry, + gpointer user_data) +{ + gsd_ldsm_get_config (); +} + +void +gsd_ldsm_setup (gboolean check_now) +{ + GError *error = NULL; + + if (ldsm_notified_hash || ldsm_timeout_id || ldsm_monitor) { + g_warning ("Low disk space monitor already initialized."); + return; + } + + ldsm_notified_hash = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, + ldsm_free_mount_info); + + client = mateconf_client_get_default (); + if (client != NULL) { + gsd_ldsm_get_config (); + mateconf_notify_id = mateconf_client_notify_add (client, + MATECONF_HOUSEKEEPING_DIR, + (MateConfClientNotifyFunc) gsd_ldsm_update_config, + NULL, NULL, &error); + if (error != NULL) { + g_warning ("Cannot register callback for MateConf notification"); + g_clear_error (&error); + } + } else { + g_warning ("Failed to get default client"); + } + + ldsm_monitor = g_unix_mount_monitor_new (); + g_unix_mount_monitor_set_rate_limit (ldsm_monitor, 1000); + g_signal_connect (ldsm_monitor, "mounts-changed", + G_CALLBACK (ldsm_mounts_changed), NULL); + + if (check_now) + ldsm_check_all_mounts (NULL); + + ldsm_timeout_id = g_timeout_add_seconds (CHECK_EVERY_X_SECONDS, + ldsm_check_all_mounts, NULL); + +} + +void +gsd_ldsm_clean (void) +{ + if (ldsm_timeout_id) + g_source_remove (ldsm_timeout_id); + ldsm_timeout_id = 0; + + if (ldsm_notified_hash) + g_hash_table_destroy (ldsm_notified_hash); + ldsm_notified_hash = NULL; + + if (ldsm_monitor) + g_object_unref (ldsm_monitor); + ldsm_monitor = NULL; + + if (client) { + mateconf_client_notify_remove (client, mateconf_notify_id); + g_object_unref (client); + } + + if (dialog) { + gtk_widget_destroy (GTK_WIDGET (dialog)); + dialog = NULL; + } + + if (ignore_paths) { + g_slist_foreach (ignore_paths, (GFunc) g_free, NULL); + g_slist_free (ignore_paths); + } +} + +#ifdef TEST +int +main (int argc, + char **argv) +{ + GMainLoop *loop; + + gtk_init (&argc, &argv); + + loop = g_main_loop_new (NULL, FALSE); + + gsd_ldsm_setup (TRUE); + + g_main_loop_run (loop); + + gsd_ldsm_clean (); + g_main_loop_unref (loop); + + return 0; +} +#endif /* TEST */ diff --git a/plugins/housekeeping/gsd-disk-space.h b/plugins/housekeeping/gsd-disk-space.h new file mode 100644 index 0000000..9a079a4 --- /dev/null +++ b/plugins/housekeeping/gsd-disk-space.h @@ -0,0 +1,40 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * vim: set et sw=8 ts=8: + * + * Copyright (c) 2008, Novell, Inc. + * + * Authors: Vincent Untz <[email protected]> + * + * 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_DISK_SPACE_H +#define __GSD_DISK_SPACE_H + +#include <glib.h> + +#ifdef __cplusplus +extern "C" { +#endif + +void gsd_ldsm_setup (gboolean check_now); +void gsd_ldsm_clean (void); + +#ifdef __cplusplus +} +#endif + +#endif /* __GSD_DISK_SPACE_H */ diff --git a/plugins/housekeeping/gsd-housekeeping-manager.c b/plugins/housekeeping/gsd-housekeeping-manager.c new file mode 100644 index 0000000..bbdea2c --- /dev/null +++ b/plugins/housekeeping/gsd-housekeeping-manager.c @@ -0,0 +1,389 @@ +/* + * Copyright (C) 2008 Michael J. Chudobiak <[email protected]> + * + * 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 <mateconf/mateconf-client.h> +#include <gio/gio.h> +#include <glib/gstdio.h> +#include <string.h> + +#include "mate-settings-profile.h" +#include "gsd-housekeeping-manager.h" +#include "gsd-disk-space.h" + + +/* General */ +#define INTERVAL_ONCE_A_DAY 24*60*60 +#define INTERVAL_TWO_MINUTES 2*60 + + +/* Thumbnail cleaner */ +#define MATECONF_THUMB_AGE "/desktop/mate/thumbnail_cache/maximum_age" +#define DEFAULT_MAX_AGE_IN_DAYS 180 +#define MATECONF_THUMB_SIZE "/desktop/mate/thumbnail_cache/maximum_size" +#define DEFAULT_MAX_SIZE_IN_MB 512 +#define MATECONF_THUMB_BINDING_DIR "/desktop/mate/thumbnail_cache" + + +struct GsdHousekeepingManagerPrivate { + guint long_term_cb; + guint short_term_cb; + guint mateconf_notify; +}; + + +#define GSD_HOUSEKEEPING_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_HOUSEKEEPING_MANAGER, GsdHousekeepingManagerPrivate)) + +static void gsd_housekeeping_manager_class_init (GsdHousekeepingManagerClass *klass); +static void gsd_housekeeping_manager_init (GsdHousekeepingManager *housekeeping_manager); + +G_DEFINE_TYPE (GsdHousekeepingManager, gsd_housekeeping_manager, G_TYPE_OBJECT) + +static gpointer manager_object = NULL; + + +typedef struct { + glong now; + glong max_age; + goffset total_size; + goffset max_size; +} PurgeData; + + +typedef struct { + time_t mtime; + char *path; + glong size; +} ThumbData; + + +static void +thumb_data_free (gpointer data) +{ + ThumbData *info = data; + + if (info) { + g_free (info->path); + g_free (info); + } +} + + +static GList * +read_dir_for_purge (const char *path, GList *files) +{ + GFile *read_path; + GFileEnumerator *enum_dir; + + read_path = g_file_new_for_path (path); + enum_dir = g_file_enumerate_children (read_path, + G_FILE_ATTRIBUTE_STANDARD_NAME "," + G_FILE_ATTRIBUTE_TIME_MODIFIED "," + G_FILE_ATTRIBUTE_STANDARD_SIZE, + G_FILE_QUERY_INFO_NONE, + NULL, + NULL); + + if (enum_dir != NULL) { + GFileInfo *info; + while ((info = g_file_enumerator_next_file (enum_dir, NULL, NULL)) != NULL) { + const char *name; + name = g_file_info_get_name (info); + + if (strlen (name) == 36 && strcmp (name + 32, ".png") == 0) { + ThumbData *td; + GFile *entry; + char *entry_path; + GTimeVal mod_time; + + entry = g_file_get_child (read_path, name); + entry_path = g_file_get_path (entry); + g_object_unref (entry); + + g_file_info_get_modification_time (info, &mod_time); + + td = g_new0 (ThumbData, 1); + td->path = entry_path; + td->mtime = mod_time.tv_sec; + td->size = g_file_info_get_size (info); + + files = g_list_prepend (files, td); + } + g_object_unref (info); + } + g_object_unref (enum_dir); + } + g_object_unref (read_path); + + return files; +} + + +static void +purge_old_thumbnails (ThumbData *info, PurgeData *purge_data) +{ + if ((purge_data->now - info->mtime) > purge_data->max_age) { + g_unlink (info->path); + info->size = 0; + } else { + purge_data->total_size += info->size; + } +} + + +static int +sort_file_mtime (ThumbData *file1, ThumbData *file2) +{ + return file1->mtime - file2->mtime; +} + + +static int +get_mateconf_int_with_default (char *key, int default_value) +{ + /* If the key is unset, we use a non-zero default value. + A zero value corresponds to an extra-paranoid level + of cleaning - it deletes all files. We don't want that + as a default condition. */ + + MateConfValue *value; + MateConfClient *client; + int res; + + client = mateconf_client_get_default (); + value = mateconf_client_get (client, key, NULL); + g_object_unref (client); + + if (value == NULL || value->type != MATECONF_VALUE_INT) { + res = default_value; + } else { + res = mateconf_value_get_int (value); + mateconf_value_free (value); + } + + return res; +} + + +static void +purge_thumbnail_cache (void) +{ + + char *path; + GList *files; + PurgeData purge_data; + GTimeVal current_time; + + g_debug ("housekeeping: checking thumbnail cache size and freshness"); + + path = g_build_filename (g_get_home_dir (), + ".thumbnails", + "normal", + NULL); + files = read_dir_for_purge (path, NULL); + g_free (path); + + path = g_build_filename (g_get_home_dir (), + ".thumbnails", + "large", + NULL); + files = read_dir_for_purge (path, files); + g_free (path); + + path = g_build_filename (g_get_home_dir (), + ".thumbnails", + "fail", + "mate-thumbnail-factory", + NULL); + files = read_dir_for_purge (path, files); + g_free (path); + + g_get_current_time (¤t_time); + + purge_data.now = current_time.tv_sec; + purge_data.max_age = get_mateconf_int_with_default (MATECONF_THUMB_AGE, DEFAULT_MAX_AGE_IN_DAYS) * 24 * 60 * 60; + purge_data.max_size = get_mateconf_int_with_default (MATECONF_THUMB_SIZE, DEFAULT_MAX_SIZE_IN_MB) * 1024 * 1024; + purge_data.total_size = 0; + + if (purge_data.max_age >= 0) + g_list_foreach (files, (GFunc) purge_old_thumbnails, &purge_data); + + if ((purge_data.total_size > purge_data.max_size) && (purge_data.max_size >= 0)) { + GList *scan; + files = g_list_sort (files, (GCompareFunc) sort_file_mtime); + for (scan = files; scan && (purge_data.total_size > purge_data.max_size); scan = scan->next) { + ThumbData *info = scan->data; + g_unlink (info->path); + purge_data.total_size -= info->size; + } + } + + g_list_foreach (files, (GFunc) thumb_data_free, NULL); + g_list_free (files); +} + + +static gboolean +do_cleanup (GsdHousekeepingManager *manager) +{ + purge_thumbnail_cache (); + return TRUE; +} + + +static gboolean +do_cleanup_once (GsdHousekeepingManager *manager) +{ + do_cleanup (manager); + manager->priv->short_term_cb = 0; + return FALSE; +} + + +static void +do_cleanup_soon (GsdHousekeepingManager *manager) +{ + if (manager->priv->short_term_cb == 0) { + g_debug ("housekeeping: will tidy up in 2 minutes"); + manager->priv->short_term_cb = g_timeout_add_seconds (INTERVAL_TWO_MINUTES, + (GSourceFunc) do_cleanup_once, + manager); + } +} + + +static void +bindings_callback (MateConfClient *client, + guint cnxn_id, + MateConfEntry *entry, + GsdHousekeepingManager *manager) +{ + do_cleanup_soon (manager); +} + + +static guint +register_config_callback (GsdHousekeepingManager *manager, + const char *path, + MateConfClientNotifyFunc func) +{ + MateConfClient *client = mateconf_client_get_default (); + guint notify; + + mateconf_client_add_dir (client, path, MATECONF_CLIENT_PRELOAD_NONE, NULL); + notify = mateconf_client_notify_add (client, path, func, manager, NULL, NULL); + + g_object_unref (client); + + return notify; +} + + +gboolean +gsd_housekeeping_manager_start (GsdHousekeepingManager *manager, + GError **error) +{ + g_debug ("Starting housekeeping manager"); + mate_settings_profile_start (NULL); + + gsd_ldsm_setup (FALSE); + + manager->priv->mateconf_notify = register_config_callback (manager, + MATECONF_THUMB_BINDING_DIR, + (MateConfClientNotifyFunc) bindings_callback); + + /* Clean once, a few minutes after start-up */ + do_cleanup_soon (manager); + + /* Clean periodically, on a daily basis. */ + manager->priv->long_term_cb = g_timeout_add_seconds (INTERVAL_ONCE_A_DAY, + (GSourceFunc) do_cleanup, + manager); + mate_settings_profile_end (NULL); + + return TRUE; +} + + +void +gsd_housekeeping_manager_stop (GsdHousekeepingManager *manager) +{ + GsdHousekeepingManagerPrivate *p = manager->priv; + + g_debug ("Stopping housekeeping manager"); + + if (p->mateconf_notify != 0) { + MateConfClient *client = mateconf_client_get_default (); + + mateconf_client_remove_dir (client, MATECONF_THUMB_BINDING_DIR, NULL); + mateconf_client_notify_remove (client, p->mateconf_notify); + + g_object_unref (client); + p->mateconf_notify = 0; + } + + if (p->short_term_cb) { + g_source_remove (p->short_term_cb); + p->short_term_cb = 0; + } + + if (p->long_term_cb) { + g_source_remove (p->long_term_cb); + p->long_term_cb = 0; + + /* Do a clean-up on shutdown if and only if the size or age + limits have been set to paranoid levels (zero) */ + if ((get_mateconf_int_with_default (MATECONF_THUMB_AGE, DEFAULT_MAX_AGE_IN_DAYS) == 0) || + (get_mateconf_int_with_default (MATECONF_THUMB_SIZE, DEFAULT_MAX_SIZE_IN_MB) == 0)) { + do_cleanup (manager); + } + } + + gsd_ldsm_clean (); +} + + +static void +gsd_housekeeping_manager_class_init (GsdHousekeepingManagerClass *klass) +{ + g_type_class_add_private (klass, sizeof (GsdHousekeepingManagerPrivate)); +} + + +static void +gsd_housekeeping_manager_init (GsdHousekeepingManager *manager) +{ + manager->priv = GSD_HOUSEKEEPING_MANAGER_GET_PRIVATE (manager); +} + + +GsdHousekeepingManager * +gsd_housekeeping_manager_new (void) +{ + if (manager_object != NULL) { + g_object_ref (manager_object); + } else { + manager_object = g_object_new (GSD_TYPE_HOUSEKEEPING_MANAGER, NULL); + g_object_add_weak_pointer (manager_object, + (gpointer *) &manager_object); + } + + return GSD_HOUSEKEEPING_MANAGER (manager_object); +} diff --git a/plugins/housekeeping/gsd-housekeeping-manager.h b/plugins/housekeeping/gsd-housekeeping-manager.h new file mode 100644 index 0000000..3cba840 --- /dev/null +++ b/plugins/housekeeping/gsd-housekeeping-manager.h @@ -0,0 +1,59 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Michael J. Chudobiak <[email protected]> + * + * 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_HOUSEKEEPING_MANAGER_H +#define __GSD_HOUSEKEEPING_MANAGER_H + +#include <glib-object.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_HOUSEKEEPING_MANAGER (gsd_housekeeping_manager_get_type ()) +#define GSD_HOUSEKEEPING_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_HOUSEKEEPING_MANAGER, GsdHousekeepingManager)) +#define GSD_HOUSEKEEPING_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_HOUSEKEEPING_MANAGER, GsdHousekeepingManagerClass)) +#define GSD_IS_HOUSEKEEPING_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_HOUSEKEEPING_MANAGER)) +#define GSD_IS_HOUSEKEEPING_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_HOUSEKEEPING_MANAGER)) +#define GSD_HOUSEKEEPING_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_HOUSEKEEPING_MANAGER, GsdHousekeepingManagerClass)) + +typedef struct GsdHousekeepingManagerPrivate GsdHousekeepingManagerPrivate; + +typedef struct { + GObject parent; + GsdHousekeepingManagerPrivate *priv; +} GsdHousekeepingManager; + +typedef struct { + GObjectClass parent_class; +} GsdHousekeepingManagerClass; + +GType gsd_housekeeping_manager_get_type (void); + +GsdHousekeepingManager * gsd_housekeeping_manager_new (void); +gboolean gsd_housekeeping_manager_start (GsdHousekeepingManager *manager, + GError **error); +void gsd_housekeeping_manager_stop (GsdHousekeepingManager *manager); + +#ifdef __cplusplus +} +#endif + +#endif /* __GSD_HOUSEKEEPING_MANAGER_H */ diff --git a/plugins/housekeeping/gsd-housekeeping-plugin.c b/plugins/housekeeping/gsd-housekeeping-plugin.c new file mode 100644 index 0000000..1bbddb0 --- /dev/null +++ b/plugins/housekeeping/gsd-housekeeping-plugin.c @@ -0,0 +1,104 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Michael J. Chudobiak <[email protected]> + * + * 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 <glib/gi18n-lib.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" +#include "gsd-housekeeping-plugin.h" +#include "gsd-housekeeping-manager.h" + +struct GsdHousekeepingPluginPrivate { + GsdHousekeepingManager *manager; +}; + +#define GSD_HOUSEKEEPING_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSD_TYPE_HOUSEKEEPING_PLUGIN, GsdHousekeepingPluginPrivate)) + +MATE_SETTINGS_PLUGIN_REGISTER (GsdHousekeepingPlugin, gsd_housekeeping_plugin) + +static void +gsd_housekeeping_plugin_init (GsdHousekeepingPlugin *plugin) +{ + plugin->priv = GSD_HOUSEKEEPING_PLUGIN_GET_PRIVATE (plugin); + + g_debug ("GsdHousekeepingPlugin initializing"); + + plugin->priv->manager = gsd_housekeeping_manager_new (); +} + +static void +gsd_housekeeping_plugin_finalize (GObject *object) +{ + GsdHousekeepingPlugin *plugin; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_HOUSEKEEPING_PLUGIN (object)); + + g_debug ("GsdHousekeepingPlugin finalizing"); + + plugin = GSD_HOUSEKEEPING_PLUGIN (object); + + g_return_if_fail (plugin->priv != NULL); + + if (plugin->priv->manager != NULL) { + g_object_unref (plugin->priv->manager); + } + + G_OBJECT_CLASS (gsd_housekeeping_plugin_parent_class)->finalize (object); +} + +static void +impl_activate (MateSettingsPlugin *plugin) +{ + gboolean res; + GError *error; + + g_debug ("Activating housekeeping plugin"); + + error = NULL; + res = gsd_housekeeping_manager_start (GSD_HOUSEKEEPING_PLUGIN (plugin)->priv->manager, &error); + if (! res) { + g_warning ("Unable to start housekeeping manager: %s", error->message); + g_error_free (error); + } +} + +static void +impl_deactivate (MateSettingsPlugin *plugin) +{ + g_debug ("Deactivating housekeeping plugin"); + gsd_housekeeping_manager_stop (GSD_HOUSEKEEPING_PLUGIN (plugin)->priv->manager); +} + +static void +gsd_housekeeping_plugin_class_init (GsdHousekeepingPluginClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MateSettingsPluginClass *plugin_class = MATE_SETTINGS_PLUGIN_CLASS (klass); + + object_class->finalize = gsd_housekeeping_plugin_finalize; + + plugin_class->activate = impl_activate; + plugin_class->deactivate = impl_deactivate; + + g_type_class_add_private (klass, sizeof (GsdHousekeepingPluginPrivate)); +} diff --git a/plugins/housekeeping/gsd-housekeeping-plugin.h b/plugins/housekeeping/gsd-housekeeping-plugin.h new file mode 100644 index 0000000..daca16b --- /dev/null +++ b/plugins/housekeeping/gsd-housekeeping-plugin.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Michael J. Chudobiak <[email protected]> + * + * 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_HOUSEKEEPING_PLUGIN_H__ +#define __GSD_HOUSEKEEPING_PLUGIN_H__ + +#include <glib.h> +#include <glib-object.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_HOUSEKEEPING_PLUGIN (gsd_housekeeping_plugin_get_type ()) +#define GSD_HOUSEKEEPING_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_HOUSEKEEPING_PLUGIN, GsdHousekeepingPlugin)) +#define GSD_HOUSEKEEPING_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_HOUSEKEEPING_PLUGIN, GsdHousekeepingPluginClass)) +#define GSD_IS_HOUSEKEEPING_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_HOUSEKEEPING_PLUGIN)) +#define GSD_IS_HOUSEKEEPING_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_HOUSEKEEPING_PLUGIN)) +#define GSD_HOUSEKEEPING_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_HOUSEKEEPING_PLUGIN, GsdHousekeepingPluginClass)) + +typedef struct GsdHousekeepingPluginPrivate GsdHousekeepingPluginPrivate; + +typedef struct { + MateSettingsPlugin parent; + GsdHousekeepingPluginPrivate *priv; +} GsdHousekeepingPlugin; + +typedef struct { + MateSettingsPluginClass parent_class; +} GsdHousekeepingPluginClass; + +GType gsd_housekeeping_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_HOUSEKEEPING_PLUGIN_H__ */ diff --git a/plugins/housekeeping/gsd-ldsm-dialog.c b/plugins/housekeeping/gsd-ldsm-dialog.c new file mode 100644 index 0000000..695db91 --- /dev/null +++ b/plugins/housekeeping/gsd-ldsm-dialog.c @@ -0,0 +1,476 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * gsd-ldsm-dialog.c + * Copyright (C) Chris Coulson 2009 <[email protected]> + * + * gsd-ldsm-dialog.c 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 3 of the License, or + * (at your option) any later version. + * + * gsd-ldsm-dialog.c is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <glib/gi18n.h> +#include <mateconf/mateconf-client.h> + +#include "gsd-ldsm-dialog.h" + +#define MATECONF_CLIENT_IGNORE_PATHS "/apps/mate_settings_daemon/plugins/housekeeping/ignore_paths" + +enum +{ + PROP_0, + PROP_OTHER_USABLE_PARTITIONS, + PROP_OTHER_PARTITIONS, + PROP_HAS_TRASH, + PROP_SPACE_REMAINING, + PROP_PARTITION_NAME, + PROP_MOUNT_PATH +}; + +struct GsdLdsmDialogPrivate +{ + GtkWidget *primary_label; + GtkWidget *secondary_label; + GtkWidget *ignore_check_button; + gboolean other_usable_partitions; + gboolean other_partitions; + gboolean has_trash; + gint64 space_remaining; + gchar *partition_name; + gchar *mount_path; +}; + +#define GSD_LDSM_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_LDSM_DIALOG, GsdLdsmDialogPrivate)) + +static void gsd_ldsm_dialog_class_init (GsdLdsmDialogClass *klass); +static void gsd_ldsm_dialog_init (GsdLdsmDialog *dialog); + +G_DEFINE_TYPE (GsdLdsmDialog, gsd_ldsm_dialog, GTK_TYPE_DIALOG); + +static const gchar* +gsd_ldsm_dialog_get_checkbutton_text (GsdLdsmDialog *dialog) +{ + g_return_val_if_fail (GSD_IS_LDSM_DIALOG (dialog), NULL); + + if (dialog->priv->other_partitions) + return _("Don't show any warnings again for this file system"); + else + return _("Don't show any warnings again"); +} + +static gchar* +gsd_ldsm_dialog_get_primary_text (GsdLdsmDialog *dialog) +{ + gchar *primary_text, *free_space; + + g_return_val_if_fail (GSD_IS_LDSM_DIALOG (dialog), NULL); + + free_space = g_format_size_for_display (dialog->priv->space_remaining); + + if (dialog->priv->other_partitions) { + primary_text = g_strdup_printf (_("The volume \"%s\" has only %s disk space remaining."), + dialog->priv->partition_name, free_space); + } else { + primary_text = g_strdup_printf (_("This computer has only %s disk space remaining."), + free_space); + } + + g_free (free_space); + + return primary_text; +} + +static const gchar* +gsd_ldsm_dialog_get_secondary_text (GsdLdsmDialog *dialog) +{ + g_return_val_if_fail (GSD_IS_LDSM_DIALOG (dialog), NULL); + + if (dialog->priv->other_usable_partitions) { + if (dialog->priv->has_trash) { + return _("You can free up disk space by emptying the Trash, removing " \ + "unused programs or files, or moving files to another disk or partition."); + } else { + return _("You can free up disk space by removing unused programs or files, " \ + "or by moving files to another disk or partition."); + } + } else { + if (dialog->priv->has_trash) { + return _("You can free up disk space by emptying the Trash, removing unused " \ + "programs or files, or moving files to an external disk."); + } else { + return _("You can free up disk space by removing unused programs or files, " \ + "or by moving files to an external disk."); + } + } +} + +static gint +ignore_path_compare (gconstpointer a, + gconstpointer b) +{ + return g_strcmp0 ((const gchar *)a, (const gchar *)b); +} + +static gboolean +update_ignore_paths (GSList **ignore_paths, + const gchar *mount_path, + gboolean ignore) +{ + GSList *found; + gchar *path_to_remove; + + found = g_slist_find_custom (*ignore_paths, mount_path, (GCompareFunc) ignore_path_compare); + + if (ignore && (found == NULL)) { + *ignore_paths = g_slist_prepend (*ignore_paths, g_strdup (mount_path)); + return TRUE; + } + + if (!ignore && (found != NULL)) { + path_to_remove = found->data; + *ignore_paths = g_slist_remove (*ignore_paths, path_to_remove); + g_free (path_to_remove); + return TRUE; + } + + return FALSE; +} + +static void +ignore_check_button_toggled_cb (GtkToggleButton *button, + gpointer user_data) +{ + GsdLdsmDialog *dialog = (GsdLdsmDialog *)user_data; + MateConfClient *client; + GSList *ignore_paths; + GError *error = NULL; + gboolean ignore, ret, updated; + + client = mateconf_client_get_default (); + if (client != NULL) { + ignore_paths = mateconf_client_get_list (client, + MATECONF_CLIENT_IGNORE_PATHS, + MATECONF_VALUE_STRING, &error); + if (error != NULL) { + g_warning ("Cannot change ignore preference - failed to read existing configuration: %s", + error->message ? error->message : "Unkown error"); + g_clear_error (&error); + return; + } else { + ignore = gtk_toggle_button_get_active (button); + updated = update_ignore_paths (&ignore_paths, dialog->priv->mount_path, ignore); + } + + if (!updated) + return; + + ret = mateconf_client_set_list (client, + MATECONF_CLIENT_IGNORE_PATHS, + MATECONF_VALUE_STRING, + ignore_paths, &error); + if (!ret || error != NULL) { + g_warning ("Cannot change ignore preference - failed to commit changes: %s", + error->message ? error->message : "Unkown error"); + g_clear_error (&error); + } + + g_slist_foreach (ignore_paths, (GFunc) g_free, NULL); + g_slist_free (ignore_paths); + g_object_unref (client); + } else { + g_warning ("Cannot change ignore preference - failed to get MateConfClient"); + } +} + +static void +gsd_ldsm_dialog_init (GsdLdsmDialog *dialog) +{ + GtkWidget *main_vbox, *text_vbox, *hbox; + GtkWidget *image; + + dialog->priv = GSD_LDSM_DIALOG_GET_PRIVATE (dialog); + + main_vbox = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); + + /* Set up all the window stuff here */ + gtk_window_set_title (GTK_WINDOW (dialog), _("Low Disk Space")); + gtk_window_set_icon_name (GTK_WINDOW (dialog), + GTK_STOCK_DIALOG_WARNING); + gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); + gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER); + gtk_window_set_urgency_hint (GTK_WINDOW (dialog), TRUE); + gtk_window_set_focus_on_map (GTK_WINDOW (dialog), FALSE); + gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); + + /* We don't want a separator - they're really ugly */ + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); + + /* Create the image */ + image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG); + gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0); + + /* Create the labels */ + dialog->priv->primary_label = gtk_label_new (NULL); + gtk_label_set_line_wrap (GTK_LABEL (dialog->priv->primary_label), TRUE); + gtk_label_set_single_line_mode (GTK_LABEL (dialog->priv->primary_label), FALSE); + gtk_misc_set_alignment (GTK_MISC (dialog->priv->primary_label), 0.0, 0.0); + + dialog->priv->secondary_label = gtk_label_new (NULL); + gtk_label_set_line_wrap (GTK_LABEL (dialog->priv->secondary_label), TRUE); + gtk_label_set_single_line_mode (GTK_LABEL (dialog->priv->secondary_label), FALSE); + gtk_misc_set_alignment (GTK_MISC (dialog->priv->secondary_label), 0.0, 0.0); + + /* Create the check button to ignore future warnings */ + dialog->priv->ignore_check_button = gtk_check_button_new (); + /* The button should be inactive if the dialog was just called. + * I suppose it could be possible for the user to manually edit the MateConf key between + * the mount being checked and the dialog appearing, but I don't think it matters + * too much */ + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->ignore_check_button), FALSE); + g_signal_connect (dialog->priv->ignore_check_button, "toggled", + G_CALLBACK (ignore_check_button_toggled_cb), dialog); + + /* Now set up the dialog's GtkBox's' */ + gtk_box_set_spacing (GTK_BOX (main_vbox), 14); + + hbox = gtk_hbox_new (FALSE, 12); + gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); + + text_vbox = gtk_vbox_new (FALSE, 12); + + gtk_box_pack_start (GTK_BOX (text_vbox), dialog->priv->primary_label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (text_vbox), dialog->priv->secondary_label, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (text_vbox), dialog->priv->ignore_check_button, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (hbox), text_vbox, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0); + + /* Set up the action area */ + gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_action_area (GTK_DIALOG (dialog))), 6); + gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_action_area (GTK_DIALOG (dialog))), 5); + + gtk_widget_show_all (hbox); +} + +static void +gsd_ldsm_dialog_finalize (GObject *object) +{ + GsdLdsmDialog *self; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_LDSM_DIALOG (object)); + + self = GSD_LDSM_DIALOG (object); + + if (self->priv->partition_name) + g_free (self->priv->partition_name); + + if (self->priv->mount_path) + g_free (self->priv->mount_path); + + G_OBJECT_CLASS (gsd_ldsm_dialog_parent_class)->finalize (object); +} + +static void +gsd_ldsm_dialog_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + GsdLdsmDialog *self; + + g_return_if_fail (GSD_IS_LDSM_DIALOG (object)); + + self = GSD_LDSM_DIALOG (object); + + switch (prop_id) + { + case PROP_OTHER_USABLE_PARTITIONS: + self->priv->other_usable_partitions = g_value_get_boolean (value); + break; + case PROP_OTHER_PARTITIONS: + self->priv->other_partitions = g_value_get_boolean (value); + break; + case PROP_HAS_TRASH: + self->priv->has_trash = g_value_get_boolean (value); + break; + case PROP_SPACE_REMAINING: + self->priv->space_remaining = g_value_get_int64 (value); + break; + case PROP_PARTITION_NAME: + self->priv->partition_name = g_value_dup_string (value); + break; + case PROP_MOUNT_PATH: + self->priv->mount_path = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gsd_ldsm_dialog_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + GsdLdsmDialog *self; + + g_return_if_fail (GSD_IS_LDSM_DIALOG (object)); + + self = GSD_LDSM_DIALOG (object); + + switch (prop_id) + { + case PROP_OTHER_USABLE_PARTITIONS: + g_value_set_boolean (value, self->priv->other_usable_partitions); + break; + case PROP_OTHER_PARTITIONS: + g_value_set_boolean (value, self->priv->other_partitions); + break; + case PROP_HAS_TRASH: + g_value_set_boolean (value, self->priv->has_trash); + break; + case PROP_SPACE_REMAINING: + g_value_set_int64 (value, self->priv->space_remaining); + break; + case PROP_PARTITION_NAME: + g_value_set_string (value, self->priv->partition_name); + break; + case PROP_MOUNT_PATH: + g_value_set_string (value, self->priv->mount_path); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gsd_ldsm_dialog_class_init (GsdLdsmDialogClass *klass) +{ + GObjectClass* object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gsd_ldsm_dialog_finalize; + object_class->set_property = gsd_ldsm_dialog_set_property; + object_class->get_property = gsd_ldsm_dialog_get_property; + + g_object_class_install_property (object_class, + PROP_OTHER_USABLE_PARTITIONS, + g_param_spec_boolean ("other-usable-partitions", + "other-usable-partitions", + "Set to TRUE if there are other usable partitions on the system", + FALSE, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, + PROP_OTHER_PARTITIONS, + g_param_spec_boolean ("other-partitions", + "other-partitions", + "Set to TRUE if there are other partitions on the system", + FALSE, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, + PROP_HAS_TRASH, + g_param_spec_boolean ("has-trash", + "has-trash", + "Set to TRUE if the partition has files in it's trash folder that can be deleted", + FALSE, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, + PROP_SPACE_REMAINING, + g_param_spec_int64 ("space-remaining", + "space-remaining", + "Specify how much space is remaining in bytes", + G_MININT64, G_MAXINT64, 0, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, + PROP_PARTITION_NAME, + g_param_spec_string ("partition-name", + "partition-name", + "Specify the name of the partition", + "Unknown", + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, + PROP_MOUNT_PATH, + g_param_spec_string ("mount-path", + "mount-path", + "Specify the mount path for the partition", + "Unknown", + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + + g_type_class_add_private (klass, sizeof (GsdLdsmDialogPrivate)); +} + +GsdLdsmDialog* +gsd_ldsm_dialog_new (gboolean other_usable_partitions, + gboolean other_partitions, + gboolean display_baobab, + gboolean display_empty_trash, + gint64 space_remaining, + const gchar *partition_name, + const gchar *mount_path) +{ + GsdLdsmDialog *dialog; + GtkWidget *button_empty_trash, *button_ignore, *button_analyze; + GtkWidget *empty_trash_image, *analyze_image, *ignore_image; + gchar *primary_text, *primary_text_markup; + const gchar *secondary_text, *checkbutton_text; + + dialog = GSD_LDSM_DIALOG (g_object_new (GSD_TYPE_LDSM_DIALOG, + "other-usable-partitions", other_usable_partitions, + "other-partitions", other_partitions, + "has-trash", display_empty_trash, + "space-remaining", space_remaining, + "partition-name", partition_name, + "mount-path", mount_path, + NULL)); + + /* Add some buttons */ + if (dialog->priv->has_trash) { + button_empty_trash = gtk_dialog_add_button (GTK_DIALOG (dialog), + _("Empty Trash"), + GSD_LDSM_DIALOG_RESPONSE_EMPTY_TRASH); + empty_trash_image = gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_BUTTON); + gtk_button_set_image (GTK_BUTTON (button_empty_trash), empty_trash_image); + } + + if (display_baobab) { + button_analyze = gtk_dialog_add_button (GTK_DIALOG (dialog), + _("Examine…"), + GSD_LDSM_DIALOG_RESPONSE_ANALYZE); + analyze_image = gtk_image_new_from_icon_name ("baobab", GTK_ICON_SIZE_BUTTON); + gtk_button_set_image (GTK_BUTTON (button_analyze), analyze_image); + } + + button_ignore = gtk_dialog_add_button (GTK_DIALOG (dialog), + _("Ignore"), + GTK_RESPONSE_CANCEL); + ignore_image = gtk_image_new_from_stock (GTK_STOCK_CANCEL, GTK_ICON_SIZE_BUTTON); + gtk_button_set_image (GTK_BUTTON (button_ignore), ignore_image); + + gtk_widget_grab_default (button_ignore); + + /* Set the label text */ + primary_text = gsd_ldsm_dialog_get_primary_text (dialog); + primary_text_markup = g_markup_printf_escaped ("<big><b>%s</b></big>", primary_text); + gtk_label_set_markup (GTK_LABEL (dialog->priv->primary_label), primary_text_markup); + + secondary_text = gsd_ldsm_dialog_get_secondary_text (dialog); + gtk_label_set_text (GTK_LABEL (dialog->priv->secondary_label), secondary_text); + + checkbutton_text = gsd_ldsm_dialog_get_checkbutton_text (dialog); + gtk_button_set_label (GTK_BUTTON (dialog->priv->ignore_check_button), checkbutton_text); + + g_free (primary_text); + g_free (primary_text_markup); + + return dialog; +} diff --git a/plugins/housekeeping/gsd-ldsm-dialog.h b/plugins/housekeeping/gsd-ldsm-dialog.h new file mode 100644 index 0000000..81e2f1b --- /dev/null +++ b/plugins/housekeeping/gsd-ldsm-dialog.h @@ -0,0 +1,72 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * gsd-ldsm-dialog.c + * Copyright (C) Chris Coulson 2009 <[email protected]> + * + * gsd-ldsm-dialog.c 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 3 of the License, or + * (at your option) any later version. + * + * gsd-ldsm-dialog.c is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _GSD_LDSM_DIALOG_H_ +#define _GSD_LDSM_DIALOG_H_ + +#include <glib-object.h> +#include <gtk/gtk.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_LDSM_DIALOG (gsd_ldsm_dialog_get_type ()) +#define GSD_LDSM_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSD_TYPE_LDSM_DIALOG, GsdLdsmDialog)) +#define GSD_LDSM_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSD_TYPE_LDSM_DIALOG, GsdLdsmDialogClass)) +#define GSD_IS_LDSM_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSD_TYPE_LDSM_DIALOG)) +#define GSD_IS_LDSM_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSD_TYPE_LDSM_DIALOG)) +#define GSD_LDSM_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSD_TYPE_LDSM_DIALOG, GsdLdsmDialogClass)) + +enum +{ + GSD_LDSM_DIALOG_RESPONSE_EMPTY_TRASH = -20, + GSD_LDSM_DIALOG_RESPONSE_ANALYZE = -21 +}; + +typedef struct GsdLdsmDialogPrivate GsdLdsmDialogPrivate; +typedef struct _GsdLdsmDialogClass GsdLdsmDialogClass; +typedef struct _GsdLdsmDialog GsdLdsmDialog; + +struct _GsdLdsmDialogClass +{ + GtkDialogClass parent_class; +}; + +struct _GsdLdsmDialog +{ + GtkDialog parent_instance; + GsdLdsmDialogPrivate *priv; +}; + +GType gsd_ldsm_dialog_get_type (void) G_GNUC_CONST; + +GsdLdsmDialog * gsd_ldsm_dialog_new (gboolean other_usable_partitions, + gboolean other_partitions, + gboolean display_baobab, + gboolean display_empty_trash, + gint64 space_remaining, + const gchar *partition_name, + const gchar *mount_path); + +#ifdef __cplusplus +} +#endif + +#endif /* _GSD_LDSM_DIALOG_H_ */ diff --git a/plugins/housekeeping/gsd-ldsm-trash-empty.c b/plugins/housekeeping/gsd-ldsm-trash-empty.c new file mode 100644 index 0000000..d4ea183 --- /dev/null +++ b/plugins/housekeeping/gsd-ldsm-trash-empty.c @@ -0,0 +1,398 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * gsd-ldsm-trash-empty.c + * Copyright (C) Chris Coulson 2009 <[email protected]> + * (C) Ryan Lortie 2008 + * + * gsd-ldsm-trash-empty.c 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 3 of the License, or + * (at your option) any later version. + * + * gsd-ldsm-trash-empty.c is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <mateconf/mateconf-client.h> +#include <glib/gi18n.h> +#include <gio/gio.h> + +#include "gsd-ldsm-trash-empty.h" + +#define CAJA_CONFIRM_TRASH_KEY "/apps/caja/preferences/confirm_trash" + +/* Some of this code has been borrowed from the trash-applet, courtesy of Ryan Lortie */ + +static GtkWidget *trash_empty_confirm_dialog = NULL; +static GtkWidget *trash_empty_dialog = NULL; +static GtkWidget *location_label; +static GtkWidget *file_label; +static GtkWidget *progressbar; + +static gsize trash_empty_total_files; +static gboolean trash_empty_update_pending = FALSE; +static GFile *trash_empty_current_file = NULL; +static gsize trash_empty_deleted_files; +static GTimer *timer = NULL; +static gboolean trash_empty_actually_deleting; + +static gboolean +trash_empty_done (gpointer data) +{ + gtk_widget_destroy (trash_empty_dialog); + trash_empty_dialog = NULL; + if (timer) { + g_timer_destroy (timer); + timer = NULL; + } + + return FALSE; +} + +static gboolean +trash_empty_update_dialog (gpointer user_data) +{ + gsize deleted, total; + GFile *file; + gboolean actually_deleting; + + g_assert (trash_empty_update_pending); + + deleted = trash_empty_deleted_files; + total = trash_empty_total_files; + file = trash_empty_current_file; + actually_deleting = trash_empty_actually_deleting; + + /* maybe the done() got processed first. */ + if (!trash_empty_dialog) + goto out; + + if (!actually_deleting) { + /* If we havent finished counting yet, then pulse the progressbar every 100ms. + * This stops the user from thinking the dialog has frozen if there are + * a lot of files to delete. We don't pulse it every time we are called from the + * worker thread, otherwise it moves to fast and looks hideous + */ + if (timer) { + if (g_timer_elapsed (timer, NULL) > 0.1) { + gtk_progress_bar_pulse (GTK_PROGRESS_BAR (progressbar)); + g_timer_start (timer); + } + } else { + timer = g_timer_new (); + g_timer_start (timer); + gtk_progress_bar_pulse (GTK_PROGRESS_BAR (progressbar)); + } + } else { + gchar *text; + gchar *tmp; + gchar *markup; + GFile *parent; + + text = g_strdup_printf (_("Removing item %lu of %lu"), + deleted, total); + gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar), text); + + g_free (text); + + if (deleted > total) + gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progressbar), 1.0); + else + gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progressbar), + (gdouble) deleted / (gdouble) total); + + parent = g_file_get_parent (file); + text = g_file_get_uri (parent); + g_object_unref (parent); + + gtk_label_set_text (GTK_LABEL (location_label), text); + g_free (text); + + tmp = g_file_get_basename (file); + text = g_markup_printf_escaped (_("Removing: %s"), tmp); + markup = g_strdup_printf ("<i>%s</i>", text); + gtk_label_set_markup (GTK_LABEL (file_label), text); + g_free (markup); + g_free (text); + g_free (tmp); + + /* unhide the labels */ + gtk_widget_show_all (GTK_WIDGET (trash_empty_dialog)); + } + +out: + trash_empty_current_file = NULL; + g_object_unref (file); + + trash_empty_update_pending = FALSE; + + return FALSE; +} + +/* Worker thread begin */ + +static void +trash_empty_maybe_schedule_update (GIOSchedulerJob *job, + GFile *file, + gsize deleted, + gboolean actually_deleting) +{ + if (!trash_empty_update_pending) { + g_assert (trash_empty_current_file == NULL); + + trash_empty_current_file = g_object_ref (file); + trash_empty_deleted_files = deleted; + trash_empty_actually_deleting = actually_deleting; + + trash_empty_update_pending = TRUE; + g_io_scheduler_job_send_to_mainloop_async (job, + trash_empty_update_dialog, + NULL, NULL); + } +} + +static void +trash_empty_delete_contents (GIOSchedulerJob *job, + GCancellable *cancellable, + GFile *file, + gboolean actually_delete, + gsize *deleted) +{ + GFileEnumerator *enumerator; + GFileInfo *info; + GFile *child; + + if (g_cancellable_is_cancelled (cancellable)) + return; + + enumerator = g_file_enumerate_children (file, + G_FILE_ATTRIBUTE_STANDARD_NAME "," + G_FILE_ATTRIBUTE_STANDARD_TYPE, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + cancellable, NULL); + + if (enumerator) { + while ((info = g_file_enumerator_next_file (enumerator, + cancellable, NULL)) != NULL) { + child = g_file_get_child (file, g_file_info_get_name (info)); + + if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) + trash_empty_delete_contents (job, cancellable, child, + actually_delete, deleted); + + trash_empty_maybe_schedule_update (job, child, *deleted, actually_delete); + if (actually_delete) + g_file_delete (child, cancellable, NULL); + + (*deleted)++; + + g_object_unref (child); + g_object_unref (info); + + if (g_cancellable_is_cancelled (cancellable)) + break; + } + + g_object_unref (enumerator); + } +} + +static gboolean +trash_empty_job (GIOSchedulerJob *job, + GCancellable *cancellable, + gpointer user_data) +{ + gsize deleted; + GFile *trash; + + trash = g_file_new_for_uri ("trash:///"); + + /* first do a dry run to count the number of files */ + deleted = 0; + trash_empty_delete_contents (job, cancellable, trash, FALSE, &deleted); + trash_empty_total_files = deleted; + + /* now do the real thing */ + deleted = 0; + trash_empty_delete_contents (job, cancellable, trash, TRUE, &deleted); + + /* done */ + g_object_unref (trash); + g_io_scheduler_job_send_to_mainloop_async (job, + trash_empty_done, + NULL, NULL); + + return FALSE; +} + +/* Worker thread end */ + +static void +trash_empty_start () +{ + GtkWidget *vbox1, *vbox2, *hbox; + GtkWidget *label1, *label3; + gchar *markup; + GCancellable *cancellable; + + trash_empty_dialog = gtk_dialog_new (); + gtk_window_set_default_size (GTK_WINDOW (trash_empty_dialog), 400, -1); + gtk_window_set_icon_name (GTK_WINDOW (trash_empty_dialog), "user-trash"); + gtk_window_set_title (GTK_WINDOW (trash_empty_dialog), + _("Emptying the trash")); + + vbox1 = gtk_vbox_new (FALSE, 12); + vbox2 = gtk_vbox_new (FALSE, 0); + hbox = gtk_hbox_new (FALSE, 0); + + label1 = gtk_label_new (NULL); + gtk_label_set_line_wrap (GTK_LABEL (label1), TRUE); + gtk_misc_set_alignment (GTK_MISC (label1), 0.0, 0.5); + + label3 = gtk_label_new (NULL); + gtk_label_set_line_wrap (GTK_LABEL (label3), TRUE); + gtk_misc_set_alignment (GTK_MISC (label3), 0.0, 0.5); + gtk_widget_hide (label3); + + location_label = gtk_label_new (NULL); + gtk_label_set_line_wrap (GTK_LABEL (location_label), TRUE); + gtk_misc_set_alignment (GTK_MISC (location_label), 0.0, 0.5); + + file_label = gtk_label_new (NULL); + gtk_label_set_line_wrap (GTK_LABEL (file_label), TRUE); + gtk_misc_set_alignment (GTK_MISC (file_label), 0.0, 0.5); + + progressbar = gtk_progress_bar_new (); + gtk_progress_bar_set_pulse_step (GTK_PROGRESS_BAR (progressbar), 0.1); + gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar), _("Preparing to empty trash…")); + + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (trash_empty_dialog))), vbox1, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox1), label1, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (hbox), label3, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (hbox), location_label, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox1), hbox, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox2), progressbar, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox2), file_label, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox1), vbox2, TRUE, TRUE, 0); + + gtk_widget_show (label1); + gtk_widget_show (vbox1); + gtk_widget_show_all (vbox2); + gtk_widget_show (hbox); + gtk_widget_show (location_label); + + gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (trash_empty_dialog))), 6); + gtk_container_set_border_width (GTK_CONTAINER (vbox1), 6); + + gtk_dialog_add_button (GTK_DIALOG (trash_empty_dialog), + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL); + + markup = g_markup_printf_escaped ("<big><b>%s</b></big>", _("Emptying the trash")); + gtk_label_set_markup (GTK_LABEL (label1), markup); + /* Translators: "Emptying trash from <device>" */ + gtk_label_set_text (GTK_LABEL (label3), _("From: ")); + + cancellable = g_cancellable_new (); + g_signal_connect_object (trash_empty_dialog, "response", + G_CALLBACK (g_cancellable_cancel), + cancellable, G_CONNECT_SWAPPED); + g_io_scheduler_push_job (trash_empty_job, NULL, NULL, 0, cancellable); + + gtk_widget_show (trash_empty_dialog); + + g_free (markup); + g_object_unref (cancellable); +} + +static void +trash_empty_confirmation_response (GtkDialog *dialog, + gint response_id, + gpointer user_data) +{ + if (response_id == GTK_RESPONSE_YES) + trash_empty_start (); + + gtk_object_destroy (GTK_OBJECT (dialog)); + trash_empty_confirm_dialog = NULL; +} + +static gboolean +trash_empty_require_confirmation () +{ + MateConfClient *client; + gboolean require_confirmation = TRUE; + GError *error = NULL; + + client = mateconf_client_get_default (); + if (client) { + require_confirmation = mateconf_client_get_bool (client, CAJA_CONFIRM_TRASH_KEY, &error); + if (error) { + g_warning ("Failed to read confirm_trash key from MateConf: %s", error->message ? error->message : "Unknown error"); + /* It's safest to assume that confirmation is required here */ + require_confirmation = TRUE; + g_error_free (error); + } + g_object_unref (client); + } + + return require_confirmation; +} + +static void +trash_empty_show_confirmation_dialog () +{ + GtkWidget *button; + + if (!trash_empty_require_confirmation ()) { + trash_empty_start (); + return; + } + + trash_empty_confirm_dialog = gtk_message_dialog_new (NULL, 0, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_NONE, + _("Empty all of the items from the trash?")); + + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (trash_empty_confirm_dialog), + _("If you choose to empty the trash, all items in " + "it will be permanently lost. Please note that " + "you can also delete them separately.")); + + gtk_dialog_add_button (GTK_DIALOG (trash_empty_confirm_dialog), GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL); + + button = gtk_button_new_with_mnemonic (_("_Empty Trash")); + gtk_widget_show (button); + gtk_widget_set_can_default (button, TRUE); + + gtk_dialog_add_action_widget (GTK_DIALOG (trash_empty_confirm_dialog), + button, GTK_RESPONSE_YES); + + gtk_dialog_set_default_response (GTK_DIALOG (trash_empty_confirm_dialog), + GTK_RESPONSE_YES); + + gtk_window_set_icon_name (GTK_WINDOW (trash_empty_confirm_dialog), + "user-trash"); + + gtk_widget_show (trash_empty_confirm_dialog); + + g_signal_connect (trash_empty_confirm_dialog, "response", + G_CALLBACK (trash_empty_confirmation_response), NULL); +} + +void +gsd_ldsm_trash_empty () +{ + if (trash_empty_confirm_dialog) + gtk_window_present (GTK_WINDOW (trash_empty_confirm_dialog)); + else if (trash_empty_dialog) + gtk_window_present (GTK_WINDOW (trash_empty_dialog)); + else + trash_empty_show_confirmation_dialog (); +} diff --git a/plugins/housekeeping/gsd-ldsm-trash-empty.h b/plugins/housekeeping/gsd-ldsm-trash-empty.h new file mode 100644 index 0000000..4d46a5b --- /dev/null +++ b/plugins/housekeeping/gsd-ldsm-trash-empty.h @@ -0,0 +1,27 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * gsd-ldsm-trash-empty.h + * Copyright (C) Chris Coulson 2009 <[email protected]> + * + * gsd-ldsm-trash-empty.h 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 3 of the License, or + * (at your option) any later version. + * + * gsd-ldsm-trash-empty.h is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _gsd_ldsm_trash_empty_h_ +#define _gsd_ldsm_trash_empty_h_ + +#include <gtk/gtk.h> + +void gsd_ldsm_trash_empty (); + +#endif /* _gsd_ldsm_trash_empty_h_ */ diff --git a/plugins/housekeeping/housekeeping.mate-settings-plugin.in b/plugins/housekeeping/housekeeping.mate-settings-plugin.in new file mode 100644 index 0000000..d10c36c --- /dev/null +++ b/plugins/housekeeping/housekeeping.mate-settings-plugin.in @@ -0,0 +1,8 @@ +[MATE Settings Plugin] +Module=housekeeping +IAge=0 +_Name=Housekeeping +_Description=Automatically prunes thumbnail caches and other transient files, and warns about low disk space +Authors=Michael J. Chudobiak +Copyright=Copyright © 2008 Michael J. Chudobiak +Website= diff --git a/plugins/keybindings/Makefile.am b/plugins/keybindings/Makefile.am new file mode 100644 index 0000000..c4fe7b2 --- /dev/null +++ b/plugins/keybindings/Makefile.am @@ -0,0 +1,51 @@ +NULL = + +plugin_LTLIBRARIES = \ + libkeybindings.la \ + $(NULL) + +libkeybindings_la_SOURCES = \ + gsd-keybindings-plugin.h \ + gsd-keybindings-plugin.c \ + gsd-keybindings-manager.h \ + gsd-keybindings-manager.c \ + $(NULL) + +libkeybindings_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -I$(top_srcdir)/plugins/common \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libkeybindings_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libkeybindings_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) \ + $(NULL) + +libkeybindings_la_LIBADD = \ + $(top_builddir)/plugins/common/libcommon.la \ + $(SETTINGS_PLUGIN_LIBS) \ + $(NULL) + +plugin_in_files = \ + keybindings.mate-settings-plugin.in \ + $(NULL) + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) + +EXTRA_DIST = \ + $(plugin_in_files) \ + $(NULL) + +CLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +DISTCLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +@GSD_INTLTOOL_PLUGIN_RULE@ diff --git a/plugins/keybindings/Makefile.in b/plugins/keybindings/Makefile.in new file mode 100644 index 0000000..698ff16 --- /dev/null +++ b/plugins/keybindings/Makefile.in @@ -0,0 +1,682 @@ +# 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/keybindings +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)$(plugindir)" +LTLIBRARIES = $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +libkeybindings_la_DEPENDENCIES = \ + $(top_builddir)/plugins/common/libcommon.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am__objects_1 = +am_libkeybindings_la_OBJECTS = \ + libkeybindings_la-gsd-keybindings-plugin.lo \ + libkeybindings_la-gsd-keybindings-manager.lo $(am__objects_1) +libkeybindings_la_OBJECTS = $(am_libkeybindings_la_OBJECTS) +libkeybindings_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libkeybindings_la_CFLAGS) $(CFLAGS) \ + $(libkeybindings_la_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 = $(libkeybindings_la_SOURCES) +DIST_SOURCES = $(libkeybindings_la_SOURCES) +DATA = $(plugin_DATA) +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 = +plugin_LTLIBRARIES = \ + libkeybindings.la \ + $(NULL) + +libkeybindings_la_SOURCES = \ + gsd-keybindings-plugin.h \ + gsd-keybindings-plugin.c \ + gsd-keybindings-manager.h \ + gsd-keybindings-manager.c \ + $(NULL) + +libkeybindings_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -I$(top_srcdir)/plugins/common \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libkeybindings_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libkeybindings_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) \ + $(NULL) + +libkeybindings_la_LIBADD = \ + $(top_builddir)/plugins/common/libcommon.la \ + $(SETTINGS_PLUGIN_LIBS) \ + $(NULL) + +plugin_in_files = \ + keybindings.mate-settings-plugin.in \ + $(NULL) + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) +EXTRA_DIST = \ + $(plugin_in_files) \ + $(NULL) + +CLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +DISTCLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +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/keybindings/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plugins/keybindings/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 +libkeybindings.la: $(libkeybindings_la_OBJECTS) $(libkeybindings_la_DEPENDENCIES) + $(libkeybindings_la_LINK) -rpath $(plugindir) $(libkeybindings_la_OBJECTS) $(libkeybindings_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeybindings_la-gsd-keybindings-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeybindings_la-gsd-keybindings-plugin.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 $@ $< + +libkeybindings_la-gsd-keybindings-plugin.lo: gsd-keybindings-plugin.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeybindings_la_CPPFLAGS) $(CPPFLAGS) $(libkeybindings_la_CFLAGS) $(CFLAGS) -MT libkeybindings_la-gsd-keybindings-plugin.lo -MD -MP -MF $(DEPDIR)/libkeybindings_la-gsd-keybindings-plugin.Tpo -c -o libkeybindings_la-gsd-keybindings-plugin.lo `test -f 'gsd-keybindings-plugin.c' || echo '$(srcdir)/'`gsd-keybindings-plugin.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libkeybindings_la-gsd-keybindings-plugin.Tpo $(DEPDIR)/libkeybindings_la-gsd-keybindings-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-keybindings-plugin.c' object='libkeybindings_la-gsd-keybindings-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) $(libkeybindings_la_CPPFLAGS) $(CPPFLAGS) $(libkeybindings_la_CFLAGS) $(CFLAGS) -c -o libkeybindings_la-gsd-keybindings-plugin.lo `test -f 'gsd-keybindings-plugin.c' || echo '$(srcdir)/'`gsd-keybindings-plugin.c + +libkeybindings_la-gsd-keybindings-manager.lo: gsd-keybindings-manager.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeybindings_la_CPPFLAGS) $(CPPFLAGS) $(libkeybindings_la_CFLAGS) $(CFLAGS) -MT libkeybindings_la-gsd-keybindings-manager.lo -MD -MP -MF $(DEPDIR)/libkeybindings_la-gsd-keybindings-manager.Tpo -c -o libkeybindings_la-gsd-keybindings-manager.lo `test -f 'gsd-keybindings-manager.c' || echo '$(srcdir)/'`gsd-keybindings-manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libkeybindings_la-gsd-keybindings-manager.Tpo $(DEPDIR)/libkeybindings_la-gsd-keybindings-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-keybindings-manager.c' object='libkeybindings_la-gsd-keybindings-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) $(libkeybindings_la_CPPFLAGS) $(CPPFLAGS) $(libkeybindings_la_CFLAGS) $(CFLAGS) -c -o libkeybindings_la-gsd-keybindings-manager.lo `test -f 'gsd-keybindings-manager.c' || echo '$(srcdir)/'`gsd-keybindings-manager.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +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 + +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) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -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." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ + 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-pluginDATA install-pluginLTLIBRARIES + +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: uninstall-pluginDATA uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-pluginLTLIBRARIES 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-pluginDATA \ + install-pluginLTLIBRARIES 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 \ + uninstall-pluginDATA uninstall-pluginLTLIBRARIES + + +@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/keybindings/gsd-keybindings-manager.c b/plugins/keybindings/gsd-keybindings-manager.c new file mode 100644 index 0000000..74014cc --- /dev/null +++ b/plugins/keybindings/gsd-keybindings-manager.c @@ -0,0 +1,758 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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 <sys/types.h> +#include <sys/wait.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> + +#include <locale.h> + +#include <glib.h> +#include <glib/gi18n.h> +#include <gdk/gdk.h> +#include <gdk/gdkx.h> +#include <gtk/gtk.h> +#include <X11/keysym.h> +#include <mateconf/mateconf-client.h> + +#include "mate-settings-profile.h" +#include "gsd-keybindings-manager.h" + +#include "gsd-keygrab.h" +#include "eggaccelerators.h" + +#define MATECONF_BINDING_DIR "/desktop/mate/keybindings" +#define ALLOWED_KEYS_KEY MATECONF_BINDING_DIR "/allowed_keys" + +#define GSD_KEYBINDINGS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_KEYBINDINGS_MANAGER, GsdKeybindingsManagerPrivate)) + +typedef struct { + char *binding_str; + char *action; + char *mateconf_key; + Key key; + Key previous_key; +} Binding; + +struct GsdKeybindingsManagerPrivate +{ + GSList *binding_list; + GSList *allowed_keys; + GSList *screens; + guint notify; +}; + +static void gsd_keybindings_manager_class_init (GsdKeybindingsManagerClass *klass); +static void gsd_keybindings_manager_init (GsdKeybindingsManager *keybindings_manager); +static void gsd_keybindings_manager_finalize (GObject *object); + +G_DEFINE_TYPE (GsdKeybindingsManager, gsd_keybindings_manager, G_TYPE_OBJECT) + +static gpointer manager_object = NULL; + +static GSList * +get_screens_list (void) +{ + GdkDisplay *display = gdk_display_get_default(); + int n_screens; + GSList *list = NULL; + int i; + + n_screens = gdk_display_get_n_screens (display); + + if (n_screens == 1) { + list = g_slist_append (list, gdk_screen_get_default ()); + } else { + for (i = 0; i < n_screens; i++) { + GdkScreen *screen; + + screen = gdk_display_get_screen (display, i); + if (screen != NULL) { + list = g_slist_prepend (list, screen); + } + } + list = g_slist_reverse (list); + } + + return list; +} + +static char * +entry_get_string (MateConfEntry *entry) +{ + MateConfValue *value = mateconf_entry_get_value (entry); + + if (value == NULL || value->type != MATECONF_VALUE_STRING) { + return NULL; + } + + return g_strdup (mateconf_value_get_string (value)); +} + +static gboolean +parse_binding (Binding *binding) +{ + gboolean success; + + g_return_val_if_fail (binding != NULL, FALSE); + + binding->key.keysym = 0; + binding->key.state = 0; + g_free (binding->key.keycodes); + binding->key.keycodes = NULL; + + if (binding->binding_str == NULL || + binding->binding_str[0] == '\0' || + strcmp (binding->binding_str, "Disabled") == 0) { + return FALSE; + } + + success = egg_accelerator_parse_virtual (binding->binding_str, + &binding->key.keysym, + &binding->key.keycodes, + &binding->key.state); + + if (!success) + g_warning (_("Key binding (%s) is invalid"), binding->mateconf_key); + + return success; +} + +static gint +compare_bindings (gconstpointer a, + gconstpointer b) +{ + Binding *key_a = (Binding *) a; + char *key_b = (char *) b; + + return strcmp (key_b, key_a->mateconf_key); +} + +static gboolean +bindings_get_entry (GsdKeybindingsManager *manager, + MateConfClient *client, + const char *subdir) +{ + Binding *new_binding; + GSList *tmp_elem; + GSList *list; + GSList *li; + char *mateconf_key; + char *action = NULL; + char *key = NULL; + + g_return_val_if_fail (subdir != NULL, FALSE); + + mateconf_key = g_path_get_basename (subdir); + + if (!mateconf_key) { + return FALSE; + } + + /* Get entries for this binding */ + list = mateconf_client_all_entries (client, subdir, NULL); + + for (li = list; li != NULL; li = li->next) { + MateConfEntry *entry = li->data; + char *key_name = g_path_get_basename (mateconf_entry_get_key (entry)); + + if (key_name == NULL) { + /* ignore entry */ + } else if (strcmp (key_name, "action") == 0) { + action = entry_get_string (entry); + } else if (strcmp (key_name, "binding") == 0) { + key = entry_get_string (entry); + } + + g_free (key_name); + mateconf_entry_free (entry); + } + + g_slist_free (list); + + if (!action || !key) { + g_warning (_("Key binding (%s) is incomplete"), mateconf_key); + g_free (mateconf_key); + g_free (action); + g_free (key); + return FALSE; + } + + tmp_elem = g_slist_find_custom (manager->priv->binding_list, + mateconf_key, + compare_bindings); + + if (!tmp_elem) { + new_binding = g_new0 (Binding, 1); + } else { + new_binding = (Binding *) tmp_elem->data; + g_free (new_binding->binding_str); + g_free (new_binding->action); + g_free (new_binding->mateconf_key); + + new_binding->previous_key.keysym = new_binding->key.keysym; + new_binding->previous_key.state = new_binding->key.state; + new_binding->previous_key.keycodes = new_binding->key.keycodes; + new_binding->key.keycodes = NULL; + } + + new_binding->binding_str = key; + new_binding->action = action; + new_binding->mateconf_key = mateconf_key; + + if (parse_binding (new_binding)) { + if (!tmp_elem) + manager->priv->binding_list = g_slist_prepend (manager->priv->binding_list, new_binding); + } else { + g_free (new_binding->binding_str); + g_free (new_binding->action); + g_free (new_binding->mateconf_key); + g_free (new_binding->previous_key.keycodes); + g_free (new_binding); + + if (tmp_elem) + manager->priv->binding_list = g_slist_delete_link (manager->priv->binding_list, tmp_elem); + return FALSE; + } + + return TRUE; +} + +static gboolean +same_keycode (const Key *key, const Key *other) +{ + if (key->keycodes != NULL && other->keycodes != NULL) { + guint *c; + + for (c = key->keycodes; *c; ++c) { + if (key_uses_keycode (other, *c)) + return TRUE; + } + } + return FALSE; +} + +static gboolean +same_key (const Key *key, const Key *other) +{ + if (key->state == other->state) { + if (key->keycodes != NULL && other->keycodes != NULL) { + guint *c1, *c2; + + for (c1 = key->keycodes, c2 = other->keycodes; + *c1 || *c2; ++c1, ++c2) { + if (*c1 != *c2) + return FALSE; + } + } else if (key->keycodes != NULL || other->keycodes != NULL) + return FALSE; + + + return TRUE; + } + + return FALSE; +} + +static gboolean +key_already_used (GsdKeybindingsManager *manager, + Binding *binding) +{ + GSList *li; + + for (li = manager->priv->binding_list; li != NULL; li = li->next) { + Binding *tmp_binding = (Binding*) li->data; + + if (tmp_binding != binding && + same_keycode (&tmp_binding->key, &binding->key) && + tmp_binding->key.state == binding->key.state) { + return TRUE; + } + } + + return FALSE; +} + +static void +binding_unregister_keys (GsdKeybindingsManager *manager) +{ + GSList *li; + gboolean need_flush = FALSE; + + gdk_error_trap_push (); + + for (li = manager->priv->binding_list; li != NULL; li = li->next) { + Binding *binding = (Binding *) li->data; + + if (binding->key.keycodes) { + need_flush = TRUE; + grab_key_unsafe (&binding->key, FALSE, manager->priv->screens); + } + } + + if (need_flush) + gdk_flush (); + gdk_error_trap_pop (); +} + +static void +binding_register_keys (GsdKeybindingsManager *manager) +{ + GSList *li; + gboolean need_flush = FALSE; + + gdk_error_trap_push (); + + /* Now check for changes and grab new key if not already used */ + for (li = manager->priv->binding_list; li != NULL; li = li->next) { + Binding *binding = (Binding *) li->data; + + if (manager->priv->allowed_keys != NULL && + !g_slist_find_custom (manager->priv->allowed_keys, + binding->mateconf_key, + (GCompareFunc) g_strcmp0)) { + continue; + } + + if (!same_key (&binding->previous_key, &binding->key)) { + /* Ungrab key if it changed and not clashing with previously set binding */ + if (!key_already_used (manager, binding)) { + gint i; + + need_flush = TRUE; + if (binding->previous_key.keycodes) { + grab_key_unsafe (&binding->previous_key, FALSE, manager->priv->screens); + } + grab_key_unsafe (&binding->key, TRUE, manager->priv->screens); + + binding->previous_key.keysym = binding->key.keysym; + binding->previous_key.state = binding->key.state; + g_free (binding->previous_key.keycodes); + for (i = 0; binding->key.keycodes[i]; ++i); + binding->previous_key.keycodes = g_new0 (guint, i); + for (i = 0; binding->key.keycodes[i]; ++i) + binding->previous_key.keycodes[i] = binding->key.keycodes[i]; + } else + g_warning ("Key binding (%s) is already in use", binding->binding_str); + } + } + + 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."); +} + +extern char **environ; + +static char * +screen_exec_display_string (GdkScreen *screen) +{ + GString *str; + const char *old_display; + char *p; + + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + old_display = gdk_display_get_name (gdk_screen_get_display (screen)); + + str = g_string_new ("DISPLAY="); + g_string_append (str, old_display); + + p = strrchr (str->str, '.'); + if (p && p > strchr (str->str, ':')) { + g_string_truncate (str, p - str->str); + } + + g_string_append_printf (str, ".%d", gdk_screen_get_number (screen)); + + return g_string_free (str, FALSE); +} + +/** + * get_exec_environment: + * + * Description: Modifies the current program environment to + * ensure that $DISPLAY is set such that a launched application + * inheriting this environment would appear on screen. + * + * Returns: a newly-allocated %NULL-terminated array of strings or + * %NULL on error. Use g_strfreev() to free it. + * + * mainly ripped from egg_screen_exec_display_string in + * mate-panel/egg-screen-exec.c + **/ +static char ** +get_exec_environment (XEvent *xevent) +{ + char **retval = NULL; + int i; + int display_index = -1; + GdkScreen *screen = NULL; + GdkWindow *window = gdk_xid_table_lookup (xevent->xkey.root); + + if (window) { + screen = gdk_drawable_get_screen (GDK_DRAWABLE (window)); + } + + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + for (i = 0; environ [i]; i++) { + if (!strncmp (environ [i], "DISPLAY", 7)) { + display_index = i; + } + } + + if (display_index == -1) { + display_index = i++; + } + + retval = g_new (char *, i + 1); + + for (i = 0; environ [i]; i++) { + if (i == display_index) { + retval [i] = screen_exec_display_string (screen); + } else { + retval [i] = g_strdup (environ [i]); + } + } + + retval [i] = NULL; + + return retval; +} + +static GdkFilterReturn +keybindings_filter (GdkXEvent *gdk_xevent, + GdkEvent *event, + GsdKeybindingsManager *manager) +{ + XEvent *xevent = (XEvent *) gdk_xevent; + GSList *li; + + if (xevent->type != KeyPress) { + return GDK_FILTER_CONTINUE; + } + + for (li = manager->priv->binding_list; li != NULL; li = li->next) { + Binding *binding = (Binding *) li->data; + + if (match_key (&binding->key, xevent)) { + GError *error = NULL; + gboolean retval; + gchar **argv = NULL; + gchar **envp = NULL; + + g_return_val_if_fail (binding->action != NULL, GDK_FILTER_CONTINUE); + + if (!g_shell_parse_argv (binding->action, + NULL, &argv, + &error)) { + return GDK_FILTER_CONTINUE; + } + + envp = get_exec_environment (xevent); + + retval = g_spawn_async (NULL, + argv, + envp, + G_SPAWN_SEARCH_PATH, + NULL, + NULL, + NULL, + &error); + g_strfreev (argv); + g_strfreev (envp); + + if (!retval) { + GtkWidget *dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_WARNING, + GTK_BUTTONS_CLOSE, + _("Error while trying to run (%s)\n"\ + "which is linked to the key (%s)"), + binding->action, + binding->binding_str); + g_signal_connect (dialog, + "response", + G_CALLBACK (gtk_widget_destroy), + NULL); + gtk_widget_show (dialog); + } + return GDK_FILTER_REMOVE; + } + } + return GDK_FILTER_CONTINUE; +} + +static void +bindings_callback (MateConfClient *client, + guint cnxn_id, + MateConfEntry *entry, + GsdKeybindingsManager *manager) +{ + char** key_elems; + char* binding_entry; + + if (strcmp (mateconf_entry_get_key (entry), ALLOWED_KEYS_KEY) == 0) { + g_slist_foreach (manager->priv->allowed_keys, (GFunc)g_free, NULL); + g_slist_free (manager->priv->allowed_keys); + manager->priv->allowed_keys = mateconf_client_get_list (client, + ALLOWED_KEYS_KEY, + MATECONF_VALUE_STRING, + NULL); + } + else { + /* ensure we get binding dir not a sub component */ + key_elems = g_strsplit (mateconf_entry_get_key (entry), "/", 15); + binding_entry = g_strdup_printf ("/%s/%s/%s/%s", + key_elems[1], + key_elems[2], + key_elems[3], + key_elems[4]); + g_strfreev (key_elems); + + bindings_get_entry (manager, client, binding_entry); + g_free (binding_entry); + } + + binding_register_keys (manager); +} + +static guint +register_config_callback (GsdKeybindingsManager *manager, + MateConfClient *client, + const char *path, + MateConfClientNotifyFunc func) +{ + mateconf_client_add_dir (client, path, MATECONF_CLIENT_PRELOAD_RECURSIVE, NULL); + return mateconf_client_notify_add (client, path, func, manager, NULL, NULL); +} + +gboolean +gsd_keybindings_manager_start (GsdKeybindingsManager *manager, + GError **error) +{ + MateConfClient *client; + GSList *list; + GSList *li; + GdkDisplay *dpy; + GdkScreen *screen; + int screen_num; + int i; + + g_debug ("Starting keybindings manager"); + mate_settings_profile_start (NULL); + + client = mateconf_client_get_default (); + + manager->priv->notify = register_config_callback (manager, + client, + MATECONF_BINDING_DIR, + (MateConfClientNotifyFunc) bindings_callback); + + manager->priv->allowed_keys = mateconf_client_get_list (client, + ALLOWED_KEYS_KEY, + MATECONF_VALUE_STRING, + NULL); + + dpy = gdk_display_get_default (); + screen_num = gdk_display_get_n_screens (dpy); + + for (i = 0; i < screen_num; i++) { + screen = gdk_display_get_screen (dpy, i); + gdk_window_add_filter (gdk_screen_get_root_window (screen), + (GdkFilterFunc) keybindings_filter, + manager); + } + + list = mateconf_client_all_dirs (client, MATECONF_BINDING_DIR, NULL); + manager->priv->screens = get_screens_list (); + + for (li = list; li != NULL; li = li->next) { + bindings_get_entry (manager, client, li->data); + g_free (li->data); + } + + g_slist_free (list); + g_object_unref (client); + + binding_register_keys (manager); + + mate_settings_profile_end (NULL); + + return TRUE; +} + +void +gsd_keybindings_manager_stop (GsdKeybindingsManager *manager) +{ + GsdKeybindingsManagerPrivate *p = manager->priv; + GSList *l; + + g_debug ("Stopping keybindings manager"); + + if (p->notify != 0) { + MateConfClient *client = mateconf_client_get_default (); + mateconf_client_remove_dir (client, MATECONF_BINDING_DIR, NULL); + mateconf_client_notify_remove (client, p->notify); + g_object_unref (client); + p->notify = 0; + } + + for (l = p->screens; l; l = l->next) { + GdkScreen *screen = l->data; + gdk_window_remove_filter (gdk_screen_get_root_window (screen), + (GdkFilterFunc) keybindings_filter, + manager); + } + + binding_unregister_keys (manager); + + g_slist_free (p->screens); + p->screens = NULL; + + for (l = p->binding_list; l; l = l->next) { + Binding *b = l->data; + g_free (b->binding_str); + g_free (b->action); + g_free (b->mateconf_key); + g_free (b->previous_key.keycodes); + g_free (b->key.keycodes); + g_free (b); + } + g_slist_free (p->binding_list); + p->binding_list = NULL; +} + +static void +gsd_keybindings_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GsdKeybindingsManager *self; + + self = GSD_KEYBINDINGS_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gsd_keybindings_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GsdKeybindingsManager *self; + + self = GSD_KEYBINDINGS_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +gsd_keybindings_manager_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GsdKeybindingsManager *keybindings_manager; + GsdKeybindingsManagerClass *klass; + + klass = GSD_KEYBINDINGS_MANAGER_CLASS (g_type_class_peek (GSD_TYPE_KEYBINDINGS_MANAGER)); + + keybindings_manager = GSD_KEYBINDINGS_MANAGER (G_OBJECT_CLASS (gsd_keybindings_manager_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + + return G_OBJECT (keybindings_manager); +} + +static void +gsd_keybindings_manager_dispose (GObject *object) +{ + GsdKeybindingsManager *keybindings_manager; + + keybindings_manager = GSD_KEYBINDINGS_MANAGER (object); + + G_OBJECT_CLASS (gsd_keybindings_manager_parent_class)->dispose (object); +} + +static void +gsd_keybindings_manager_class_init (GsdKeybindingsManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gsd_keybindings_manager_get_property; + object_class->set_property = gsd_keybindings_manager_set_property; + object_class->constructor = gsd_keybindings_manager_constructor; + object_class->dispose = gsd_keybindings_manager_dispose; + object_class->finalize = gsd_keybindings_manager_finalize; + + g_type_class_add_private (klass, sizeof (GsdKeybindingsManagerPrivate)); +} + +static void +gsd_keybindings_manager_init (GsdKeybindingsManager *manager) +{ + manager->priv = GSD_KEYBINDINGS_MANAGER_GET_PRIVATE (manager); + +} + +static void +gsd_keybindings_manager_finalize (GObject *object) +{ + GsdKeybindingsManager *keybindings_manager; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_KEYBINDINGS_MANAGER (object)); + + keybindings_manager = GSD_KEYBINDINGS_MANAGER (object); + + g_return_if_fail (keybindings_manager->priv != NULL); + + G_OBJECT_CLASS (gsd_keybindings_manager_parent_class)->finalize (object); +} + +GsdKeybindingsManager * +gsd_keybindings_manager_new (void) +{ + if (manager_object != NULL) { + g_object_ref (manager_object); + } else { + manager_object = g_object_new (GSD_TYPE_KEYBINDINGS_MANAGER, NULL); + g_object_add_weak_pointer (manager_object, + (gpointer *) &manager_object); + } + + return GSD_KEYBINDINGS_MANAGER (manager_object); +} diff --git a/plugins/keybindings/gsd-keybindings-manager.h b/plugins/keybindings/gsd-keybindings-manager.h new file mode 100644 index 0000000..7de64d9 --- /dev/null +++ b/plugins/keybindings/gsd-keybindings-manager.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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_KEYBINDINGS_MANAGER_H +#define __GSD_KEYBINDINGS_MANAGER_H + +#include <glib-object.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_KEYBINDINGS_MANAGER (gsd_keybindings_manager_get_type ()) +#define GSD_KEYBINDINGS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_KEYBINDINGS_MANAGER, GsdKeybindingsManager)) +#define GSD_KEYBINDINGS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_KEYBINDINGS_MANAGER, GsdKeybindingsManagerClass)) +#define GSD_IS_KEYBINDINGS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_KEYBINDINGS_MANAGER)) +#define GSD_IS_KEYBINDINGS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_KEYBINDINGS_MANAGER)) +#define GSD_KEYBINDINGS_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_KEYBINDINGS_MANAGER, GsdKeybindingsManagerClass)) + +typedef struct GsdKeybindingsManagerPrivate GsdKeybindingsManagerPrivate; + +typedef struct +{ + GObject parent; + GsdKeybindingsManagerPrivate *priv; +} GsdKeybindingsManager; + +typedef struct +{ + GObjectClass parent_class; +} GsdKeybindingsManagerClass; + +GType gsd_keybindings_manager_get_type (void); + +GsdKeybindingsManager * gsd_keybindings_manager_new (void); +gboolean gsd_keybindings_manager_start (GsdKeybindingsManager *manager, + GError **error); +void gsd_keybindings_manager_stop (GsdKeybindingsManager *manager); + +#ifdef __cplusplus +} +#endif + +#endif /* __GSD_KEYBINDINGS_MANAGER_H */ diff --git a/plugins/keybindings/gsd-keybindings-plugin.c b/plugins/keybindings/gsd-keybindings-plugin.c new file mode 100644 index 0000000..a96f420 --- /dev/null +++ b/plugins/keybindings/gsd-keybindings-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 <[email protected]> + * + * 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 <glib/gi18n-lib.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" +#include "gsd-keybindings-plugin.h" +#include "gsd-keybindings-manager.h" + +struct GsdKeybindingsPluginPrivate { + GsdKeybindingsManager *manager; +}; + +#define GSD_KEYBINDINGS_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSD_TYPE_KEYBINDINGS_PLUGIN, GsdKeybindingsPluginPrivate)) + +MATE_SETTINGS_PLUGIN_REGISTER (GsdKeybindingsPlugin, gsd_keybindings_plugin) + +static void +gsd_keybindings_plugin_init (GsdKeybindingsPlugin *plugin) +{ + plugin->priv = GSD_KEYBINDINGS_PLUGIN_GET_PRIVATE (plugin); + + g_debug ("GsdKeybindingsPlugin initializing"); + + plugin->priv->manager = gsd_keybindings_manager_new (); +} + +static void +gsd_keybindings_plugin_finalize (GObject *object) +{ + GsdKeybindingsPlugin *plugin; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_KEYBINDINGS_PLUGIN (object)); + + g_debug ("GsdKeybindingsPlugin finalizing"); + + plugin = GSD_KEYBINDINGS_PLUGIN (object); + + g_return_if_fail (plugin->priv != NULL); + + if (plugin->priv->manager != NULL) { + g_object_unref (plugin->priv->manager); + } + + G_OBJECT_CLASS (gsd_keybindings_plugin_parent_class)->finalize (object); +} + +static void +impl_activate (MateSettingsPlugin *plugin) +{ + gboolean res; + GError *error; + + g_debug ("Activating keybindings plugin"); + + error = NULL; + res = gsd_keybindings_manager_start (GSD_KEYBINDINGS_PLUGIN (plugin)->priv->manager, &error); + if (! res) { + g_warning ("Unable to start keybindings manager: %s", error->message); + g_error_free (error); + } +} + +static void +impl_deactivate (MateSettingsPlugin *plugin) +{ + g_debug ("Deactivating keybindings plugin"); + gsd_keybindings_manager_stop (GSD_KEYBINDINGS_PLUGIN (plugin)->priv->manager); +} + +static void +gsd_keybindings_plugin_class_init (GsdKeybindingsPluginClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MateSettingsPluginClass *plugin_class = MATE_SETTINGS_PLUGIN_CLASS (klass); + + object_class->finalize = gsd_keybindings_plugin_finalize; + + plugin_class->activate = impl_activate; + plugin_class->deactivate = impl_deactivate; + + g_type_class_add_private (klass, sizeof (GsdKeybindingsPluginPrivate)); +} diff --git a/plugins/keybindings/gsd-keybindings-plugin.h b/plugins/keybindings/gsd-keybindings-plugin.h new file mode 100644 index 0000000..dea237d --- /dev/null +++ b/plugins/keybindings/gsd-keybindings-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 <[email protected]> + * + * 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_KEYBINDINGS_PLUGIN_H__ +#define __GSD_KEYBINDINGS_PLUGIN_H__ + +#include <glib.h> +#include <glib-object.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_KEYBINDINGS_PLUGIN (gsd_keybindings_plugin_get_type ()) +#define GSD_KEYBINDINGS_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_KEYBINDINGS_PLUGIN, GsdKeybindingsPlugin)) +#define GSD_KEYBINDINGS_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_KEYBINDINGS_PLUGIN, GsdKeybindingsPluginClass)) +#define GSD_IS_KEYBINDINGS_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_KEYBINDINGS_PLUGIN)) +#define GSD_IS_KEYBINDINGS_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_KEYBINDINGS_PLUGIN)) +#define GSD_KEYBINDINGS_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_KEYBINDINGS_PLUGIN, GsdKeybindingsPluginClass)) + +typedef struct GsdKeybindingsPluginPrivate GsdKeybindingsPluginPrivate; + +typedef struct +{ + MateSettingsPlugin parent; + GsdKeybindingsPluginPrivate *priv; +} GsdKeybindingsPlugin; + +typedef struct +{ + MateSettingsPluginClass parent_class; +} GsdKeybindingsPluginClass; + +GType gsd_keybindings_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_KEYBINDINGS_PLUGIN_H__ */ diff --git a/plugins/keybindings/keybindings.mate-settings-plugin.in b/plugins/keybindings/keybindings.mate-settings-plugin.in new file mode 100644 index 0000000..f9c7208 --- /dev/null +++ b/plugins/keybindings/keybindings.mate-settings-plugin.in @@ -0,0 +1,8 @@ +[MATE Settings Plugin] +Module=keybindings +IAge=0 +_Name=Keybindings +_Description=Keybindings plugin +Authors=AUTHOR +Copyright=Copyright © 2007 AUTHOR +Website= diff --git a/plugins/keyboard/Makefile.am b/plugins/keyboard/Makefile.am new file mode 100644 index 0000000..fdad2a8 --- /dev/null +++ b/plugins/keyboard/Makefile.am @@ -0,0 +1,73 @@ +NULL = + +plugin_LTLIBRARIES = \ + libkeyboard.la \ + $(NULL) + +themedir = $(pkgdatadir)/icons/hicolor +size = 64x64 +context = devices + +iconsdir = $(themedir)/$(size)/$(context) +icons_DATA = \ + kbd-capslock-off.png kbd-numlock-off.png kbd-scrolllock-off.png \ + kbd-capslock-on.png kbd-numlock-on.png kbd-scrolllock-on.png + +uidir = $(pkgdatadir) +ui_DATA = modmap-dialog.ui + +libkeyboard_la_SOURCES = \ + gsd-keyboard-plugin.h \ + gsd-keyboard-plugin.c \ + gsd-keyboard-manager.h \ + gsd-keyboard-manager.c \ + gsd-keyboard-xkb.h \ + gsd-keyboard-xkb.c \ + gsd-xmodmap.h \ + gsd-xmodmap.c \ + delayed-dialog.h \ + delayed-dialog.c \ + $(NULL) + +libkeyboard_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DDATADIR=\""$(pkgdatadir)"\" \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libkeyboard_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(LIBMATEKBDUI_CFLAGS) \ + $(AM_CFLAGS) + +libkeyboard_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) \ + $(NULL) + +libkeyboard_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(XF86MISC_LIBS) \ + $(LIBMATEKBDUI_LIBS) \ + $(NULL) + +plugin_in_files = \ + keyboard.mate-settings-plugin.in \ + $(NULL) + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) + +EXTRA_DIST = \ + $(icons_DATA) \ + $(plugin_in_files) \ + $(ui_DATA) \ + $(NULL) + +CLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +DISTCLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +@GSD_INTLTOOL_PLUGIN_RULE@ diff --git a/plugins/keyboard/Makefile.in b/plugins/keyboard/Makefile.in new file mode 100644 index 0000000..021ac11 --- /dev/null +++ b/plugins/keyboard/Makefile.in @@ -0,0 +1,771 @@ +# 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/keyboard +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)$(iconsdir)" \ + "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(uidir)" +LTLIBRARIES = $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +libkeyboard_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__objects_1 = +am_libkeyboard_la_OBJECTS = libkeyboard_la-gsd-keyboard-plugin.lo \ + libkeyboard_la-gsd-keyboard-manager.lo \ + libkeyboard_la-gsd-keyboard-xkb.lo \ + libkeyboard_la-gsd-xmodmap.lo libkeyboard_la-delayed-dialog.lo \ + $(am__objects_1) +libkeyboard_la_OBJECTS = $(am_libkeyboard_la_OBJECTS) +libkeyboard_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libkeyboard_la_CFLAGS) \ + $(CFLAGS) $(libkeyboard_la_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 = $(libkeyboard_la_SOURCES) +DIST_SOURCES = $(libkeyboard_la_SOURCES) +DATA = $(icons_DATA) $(plugin_DATA) $(ui_DATA) +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 = +plugin_LTLIBRARIES = \ + libkeyboard.la \ + $(NULL) + +themedir = $(pkgdatadir)/icons/hicolor +size = 64x64 +context = devices +iconsdir = $(themedir)/$(size)/$(context) +icons_DATA = \ + kbd-capslock-off.png kbd-numlock-off.png kbd-scrolllock-off.png \ + kbd-capslock-on.png kbd-numlock-on.png kbd-scrolllock-on.png + +uidir = $(pkgdatadir) +ui_DATA = modmap-dialog.ui +libkeyboard_la_SOURCES = \ + gsd-keyboard-plugin.h \ + gsd-keyboard-plugin.c \ + gsd-keyboard-manager.h \ + gsd-keyboard-manager.c \ + gsd-keyboard-xkb.h \ + gsd-keyboard-xkb.c \ + gsd-xmodmap.h \ + gsd-xmodmap.c \ + delayed-dialog.h \ + delayed-dialog.c \ + $(NULL) + +libkeyboard_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DDATADIR=\""$(pkgdatadir)"\" \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libkeyboard_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(LIBMATEKBDUI_CFLAGS) \ + $(AM_CFLAGS) + +libkeyboard_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) \ + $(NULL) + +libkeyboard_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(XF86MISC_LIBS) \ + $(LIBMATEKBDUI_LIBS) \ + $(NULL) + +plugin_in_files = \ + keyboard.mate-settings-plugin.in \ + $(NULL) + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) +EXTRA_DIST = \ + $(icons_DATA) \ + $(plugin_in_files) \ + $(ui_DATA) \ + $(NULL) + +CLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +DISTCLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +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/keyboard/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plugins/keyboard/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 +libkeyboard.la: $(libkeyboard_la_OBJECTS) $(libkeyboard_la_DEPENDENCIES) + $(libkeyboard_la_LINK) -rpath $(plugindir) $(libkeyboard_la_OBJECTS) $(libkeyboard_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeyboard_la-delayed-dialog.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeyboard_la-gsd-keyboard-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeyboard_la-gsd-keyboard-plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeyboard_la-gsd-keyboard-xkb.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libkeyboard_la-gsd-xmodmap.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 $@ $< + +libkeyboard_la-gsd-keyboard-plugin.lo: gsd-keyboard-plugin.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeyboard_la_CPPFLAGS) $(CPPFLAGS) $(libkeyboard_la_CFLAGS) $(CFLAGS) -MT libkeyboard_la-gsd-keyboard-plugin.lo -MD -MP -MF $(DEPDIR)/libkeyboard_la-gsd-keyboard-plugin.Tpo -c -o libkeyboard_la-gsd-keyboard-plugin.lo `test -f 'gsd-keyboard-plugin.c' || echo '$(srcdir)/'`gsd-keyboard-plugin.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libkeyboard_la-gsd-keyboard-plugin.Tpo $(DEPDIR)/libkeyboard_la-gsd-keyboard-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-keyboard-plugin.c' object='libkeyboard_la-gsd-keyboard-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) $(libkeyboard_la_CPPFLAGS) $(CPPFLAGS) $(libkeyboard_la_CFLAGS) $(CFLAGS) -c -o libkeyboard_la-gsd-keyboard-plugin.lo `test -f 'gsd-keyboard-plugin.c' || echo '$(srcdir)/'`gsd-keyboard-plugin.c + +libkeyboard_la-gsd-keyboard-manager.lo: gsd-keyboard-manager.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeyboard_la_CPPFLAGS) $(CPPFLAGS) $(libkeyboard_la_CFLAGS) $(CFLAGS) -MT libkeyboard_la-gsd-keyboard-manager.lo -MD -MP -MF $(DEPDIR)/libkeyboard_la-gsd-keyboard-manager.Tpo -c -o libkeyboard_la-gsd-keyboard-manager.lo `test -f 'gsd-keyboard-manager.c' || echo '$(srcdir)/'`gsd-keyboard-manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libkeyboard_la-gsd-keyboard-manager.Tpo $(DEPDIR)/libkeyboard_la-gsd-keyboard-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-keyboard-manager.c' object='libkeyboard_la-gsd-keyboard-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) $(libkeyboard_la_CPPFLAGS) $(CPPFLAGS) $(libkeyboard_la_CFLAGS) $(CFLAGS) -c -o libkeyboard_la-gsd-keyboard-manager.lo `test -f 'gsd-keyboard-manager.c' || echo '$(srcdir)/'`gsd-keyboard-manager.c + +libkeyboard_la-gsd-keyboard-xkb.lo: gsd-keyboard-xkb.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeyboard_la_CPPFLAGS) $(CPPFLAGS) $(libkeyboard_la_CFLAGS) $(CFLAGS) -MT libkeyboard_la-gsd-keyboard-xkb.lo -MD -MP -MF $(DEPDIR)/libkeyboard_la-gsd-keyboard-xkb.Tpo -c -o libkeyboard_la-gsd-keyboard-xkb.lo `test -f 'gsd-keyboard-xkb.c' || echo '$(srcdir)/'`gsd-keyboard-xkb.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libkeyboard_la-gsd-keyboard-xkb.Tpo $(DEPDIR)/libkeyboard_la-gsd-keyboard-xkb.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-keyboard-xkb.c' object='libkeyboard_la-gsd-keyboard-xkb.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) $(libkeyboard_la_CPPFLAGS) $(CPPFLAGS) $(libkeyboard_la_CFLAGS) $(CFLAGS) -c -o libkeyboard_la-gsd-keyboard-xkb.lo `test -f 'gsd-keyboard-xkb.c' || echo '$(srcdir)/'`gsd-keyboard-xkb.c + +libkeyboard_la-gsd-xmodmap.lo: gsd-xmodmap.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeyboard_la_CPPFLAGS) $(CPPFLAGS) $(libkeyboard_la_CFLAGS) $(CFLAGS) -MT libkeyboard_la-gsd-xmodmap.lo -MD -MP -MF $(DEPDIR)/libkeyboard_la-gsd-xmodmap.Tpo -c -o libkeyboard_la-gsd-xmodmap.lo `test -f 'gsd-xmodmap.c' || echo '$(srcdir)/'`gsd-xmodmap.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libkeyboard_la-gsd-xmodmap.Tpo $(DEPDIR)/libkeyboard_la-gsd-xmodmap.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-xmodmap.c' object='libkeyboard_la-gsd-xmodmap.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) $(libkeyboard_la_CPPFLAGS) $(CPPFLAGS) $(libkeyboard_la_CFLAGS) $(CFLAGS) -c -o libkeyboard_la-gsd-xmodmap.lo `test -f 'gsd-xmodmap.c' || echo '$(srcdir)/'`gsd-xmodmap.c + +libkeyboard_la-delayed-dialog.lo: delayed-dialog.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libkeyboard_la_CPPFLAGS) $(CPPFLAGS) $(libkeyboard_la_CFLAGS) $(CFLAGS) -MT libkeyboard_la-delayed-dialog.lo -MD -MP -MF $(DEPDIR)/libkeyboard_la-delayed-dialog.Tpo -c -o libkeyboard_la-delayed-dialog.lo `test -f 'delayed-dialog.c' || echo '$(srcdir)/'`delayed-dialog.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libkeyboard_la-delayed-dialog.Tpo $(DEPDIR)/libkeyboard_la-delayed-dialog.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='delayed-dialog.c' object='libkeyboard_la-delayed-dialog.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) $(libkeyboard_la_CPPFLAGS) $(CPPFLAGS) $(libkeyboard_la_CFLAGS) $(CFLAGS) -c -o libkeyboard_la-delayed-dialog.lo `test -f 'delayed-dialog.c' || echo '$(srcdir)/'`delayed-dialog.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-iconsDATA: $(icons_DATA) + @$(NORMAL_INSTALL) + test -z "$(iconsdir)" || $(MKDIR_P) "$(DESTDIR)$(iconsdir)" + @list='$(icons_DATA)'; test -n "$(iconsdir)" || 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)$(iconsdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(iconsdir)" || exit $$?; \ + done + +uninstall-iconsDATA: + @$(NORMAL_UNINSTALL) + @list='$(icons_DATA)'; test -n "$(iconsdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(iconsdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(iconsdir)" && 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 +install-uiDATA: $(ui_DATA) + @$(NORMAL_INSTALL) + test -z "$(uidir)" || $(MKDIR_P) "$(DESTDIR)$(uidir)" + @list='$(ui_DATA)'; test -n "$(uidir)" || 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)$(uidir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(uidir)" || exit $$?; \ + done + +uninstall-uiDATA: + @$(NORMAL_UNINSTALL) + @list='$(ui_DATA)'; test -n "$(uidir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(uidir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(uidir)" && rm -f $$files + +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) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(iconsdir)" "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(uidir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -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." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ + 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-iconsDATA install-pluginDATA \ + install-pluginLTLIBRARIES install-uiDATA + +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: uninstall-iconsDATA uninstall-pluginDATA \ + uninstall-pluginLTLIBRARIES uninstall-uiDATA + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-pluginLTLIBRARIES 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-iconsDATA install-info install-info-am \ + install-man install-pdf install-pdf-am install-pluginDATA \ + install-pluginLTLIBRARIES install-ps install-ps-am \ + install-strip install-uiDATA 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 uninstall-iconsDATA uninstall-pluginDATA \ + uninstall-pluginLTLIBRARIES uninstall-uiDATA + + +@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/keyboard/delayed-dialog.c b/plugins/keyboard/delayed-dialog.c new file mode 100644 index 0000000..1aa13e1 --- /dev/null +++ b/plugins/keyboard/delayed-dialog.c @@ -0,0 +1,122 @@ +/* + * Copyright © 2006 Novell, 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, 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 <stdlib.h> +#include <string.h> + +#include <gtk/gtk.h> +#include <gdk/gdkx.h> + +#include "delayed-dialog.h" + +static gboolean delayed_show_timeout (gpointer data); +static GdkFilterReturn message_filter (GdkXEvent *xevent, + GdkEvent *event, + gpointer data); + +static GSList *dialogs = NULL; + +/** + * gsd_delayed_show_dialog: + * @dialog: the dialog + * + * Shows the dialog as with gtk_widget_show(), unless a window manager + * hasn't been started yet, in which case it will wait up to 5 seconds + * for that to happen before showing the dialog. + **/ +void +gsd_delayed_show_dialog (GtkWidget *dialog) +{ + GdkDisplay *display = gtk_widget_get_display (dialog); + Display *xdisplay = GDK_DISPLAY_XDISPLAY (display); + GdkScreen *screen = gtk_widget_get_screen (dialog); + GdkAtom manager_atom; + char selection_name[10]; + Atom selection_atom; + + /* We can't use gdk_selection_owner_get() for this, because + * it's an unknown out-of-process window. + */ + snprintf (selection_name, sizeof (selection_name), "WM_S%d", + gdk_screen_get_number (screen)); + selection_atom = XInternAtom (xdisplay, selection_name, True); + if (selection_atom && + XGetSelectionOwner (xdisplay, selection_atom) != None) { + gtk_widget_show (dialog); + return; + } + + dialogs = g_slist_prepend (dialogs, dialog); + + manager_atom = gdk_atom_intern ("MANAGER", FALSE); + gdk_display_add_client_message_filter (display, manager_atom, + message_filter, NULL); + + g_timeout_add (5000, delayed_show_timeout, NULL); +} + +static gboolean +delayed_show_timeout (gpointer data) +{ + GSList *l; + + for (l = dialogs; l; l = l->next) + gtk_widget_show (l->data); + g_slist_free (dialogs); + dialogs = NULL; + + /* FIXME: There's no gdk_display_remove_client_message_filter */ + + return FALSE; +} + +static GdkFilterReturn +message_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data) +{ + XClientMessageEvent *evt = (XClientMessageEvent *)xevent; + char *selection_name = XGetAtomName (evt->display, evt->data.l[1]); + int screen; + GSList *l, *next; + + if (!dialogs) + return GDK_FILTER_CONTINUE; + + if (strncmp (selection_name, "WM_S", 4) != 0) { + XFree (selection_name); + return GDK_FILTER_CONTINUE; + } + + screen = atoi (selection_name + 4); + + for (l = dialogs; l; l = next) { + GtkWidget *dialog = l->data; + next = l->next; + + if (gdk_screen_get_number (gtk_widget_get_screen (dialog)) == screen) { + gtk_widget_show (dialog); + dialogs = g_slist_remove (dialogs, dialog); + } + } + + if (!dialogs) { + /* FIXME: There's no gdk_display_remove_client_message_filter */ + } + + return GDK_FILTER_CONTINUE; +} diff --git a/plugins/keyboard/delayed-dialog.h b/plugins/keyboard/delayed-dialog.h new file mode 100644 index 0000000..353dbe6 --- /dev/null +++ b/plugins/keyboard/delayed-dialog.h @@ -0,0 +1,36 @@ +/* + * Copyright © 2006 Novell, 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, 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 __DELAYED_DIALOG_H +#define __DELAYED_DIALOG_H + +#include <gtk/gtk.h> + +#ifdef __cplusplus +extern "C" { +#endif + +void gsd_delayed_show_dialog (GtkWidget *dialog); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/plugins/keyboard/gsd-keyboard-manager.c b/plugins/keyboard/gsd-keyboard-manager.c new file mode 100644 index 0000000..343706d --- /dev/null +++ b/plugins/keyboard/gsd-keyboard-manager.c @@ -0,0 +1,570 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright © 2001 Ximian, Inc. + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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 <sys/types.h> +#include <sys/wait.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> + +#include <locale.h> + +#include <glib.h> +#include <glib/gi18n.h> +#include <gdk/gdk.h> +#include <gdk/gdkx.h> +#include <gtk/gtk.h> + +#ifdef HAVE_X11_EXTENSIONS_XF86MISC_H +# include <X11/extensions/xf86misc.h> +#endif +#ifdef HAVE_X11_EXTENSIONS_XKB_H +#include <X11/XKBlib.h> +#include <X11/keysym.h> +#endif + +#include "mate-settings-profile.h" +#include "gsd-keyboard-manager.h" + +#include "gsd-keyboard-xkb.h" +#include "gsd-xmodmap.h" + +#define GSD_KEYBOARD_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_KEYBOARD_MANAGER, GsdKeyboardManagerPrivate)) + +#ifndef HOST_NAME_MAX +# define HOST_NAME_MAX 255 +#endif + +#define GSD_KEYBOARD_KEY "/desktop/mate/peripherals/keyboard" + +#define KEY_REPEAT GSD_KEYBOARD_KEY "/repeat" +#define KEY_CLICK GSD_KEYBOARD_KEY "/click" +#define KEY_RATE GSD_KEYBOARD_KEY "/rate" +#define KEY_DELAY GSD_KEYBOARD_KEY "/delay" +#define KEY_CLICK_VOLUME GSD_KEYBOARD_KEY "/click_volume" + +#define KEY_BELL_VOLUME GSD_KEYBOARD_KEY "/bell_volume" +#define KEY_BELL_PITCH GSD_KEYBOARD_KEY "/bell_pitch" +#define KEY_BELL_DURATION GSD_KEYBOARD_KEY "/bell_duration" +#define KEY_BELL_MODE GSD_KEYBOARD_KEY "/bell_mode" + +struct GsdKeyboardManagerPrivate +{ + gboolean have_xkb; + gint xkb_event_base; + guint notify; +}; + +static void gsd_keyboard_manager_class_init (GsdKeyboardManagerClass *klass); +static void gsd_keyboard_manager_init (GsdKeyboardManager *keyboard_manager); +static void gsd_keyboard_manager_finalize (GObject *object); + +G_DEFINE_TYPE (GsdKeyboardManager, gsd_keyboard_manager, G_TYPE_OBJECT) + +static gpointer manager_object = NULL; + + +#ifdef HAVE_X11_EXTENSIONS_XF86MISC_H +static gboolean +xfree86_set_keyboard_autorepeat_rate (int delay, int rate) +{ + gboolean res = FALSE; + int event_base_return; + int error_base_return; + + if (XF86MiscQueryExtension (GDK_DISPLAY (), + &event_base_return, + &error_base_return) == True) { + /* load the current settings */ + XF86MiscKbdSettings kbdsettings; + XF86MiscGetKbdSettings (GDK_DISPLAY (), &kbdsettings); + + /* assign the new values */ + kbdsettings.delay = delay; + kbdsettings.rate = rate; + XF86MiscSetKbdSettings (GDK_DISPLAY (), &kbdsettings); + res = TRUE; + } + + return res; +} +#endif /* HAVE_X11_EXTENSIONS_XF86MISC_H */ + +#ifdef HAVE_X11_EXTENSIONS_XKB_H +static gboolean +xkb_set_keyboard_autorepeat_rate (int delay, int rate) +{ + int interval = (rate <= 0) ? 1000000 : 1000/rate; + if (delay <= 0) + delay = 1; + return XkbSetAutoRepeatRate (GDK_DISPLAY (), + XkbUseCoreKbd, + delay, + interval); +} +#endif + +static char * +gsd_keyboard_get_hostname_key (const char *subkey) +{ + char hostname[HOST_NAME_MAX + 1]; + + if (gethostname (hostname, sizeof (hostname)) == 0 && + strcmp (hostname, "localhost") != 0 && + strcmp (hostname, "localhost.localdomain") != 0) { + char *escaped; + char *key; + + escaped = mateconf_escape_key (hostname, -1); + key = g_strconcat (GSD_KEYBOARD_KEY + "/host-", + escaped, + "/0/", + subkey, + NULL); + g_free (escaped); + return key; + } else + return NULL; +} + +#ifdef HAVE_X11_EXTENSIONS_XKB_H + +typedef enum { + NUMLOCK_STATE_OFF = 0, + NUMLOCK_STATE_ON = 1, + NUMLOCK_STATE_UNKNOWN = 2 +} NumLockState; + +static void +numlock_xkb_init (GsdKeyboardManager *manager) +{ + Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + gboolean have_xkb; + int opcode, error_base, major, minor; + + have_xkb = XkbQueryExtension (dpy, + &opcode, + &manager->priv->xkb_event_base, + &error_base, + &major, + &minor) + && XkbUseExtension (dpy, &major, &minor); + + if (have_xkb) { + XkbSelectEventDetails (dpy, + XkbUseCoreKbd, + XkbStateNotifyMask, + XkbModifierLockMask, + XkbModifierLockMask); + } else { + g_warning ("XKB extension not available"); + } + + manager->priv->have_xkb = have_xkb; +} + +static unsigned +numlock_NumLock_modifier_mask (void) +{ + Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + return XkbKeysymToModifiers (dpy, XK_Num_Lock); +} + +static void +numlock_set_xkb_state (NumLockState new_state) +{ + unsigned int num_mask; + Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + if (new_state != NUMLOCK_STATE_ON && new_state != NUMLOCK_STATE_OFF) + return; + num_mask = numlock_NumLock_modifier_mask (); + XkbLockModifiers (dpy, XkbUseCoreKbd, num_mask, new_state ? num_mask : 0); +} + +static char * +numlock_mateconf_state_key (void) +{ + char *key = gsd_keyboard_get_hostname_key ("numlock_on"); + if (!key) { + g_message ("NumLock remembering disabled because hostname is set to \"localhost\""); + } + return key; +} + +static NumLockState +numlock_get_mateconf_state (MateConfClient *client) +{ + int curr_state; + GError *err = NULL; + char *key = numlock_mateconf_state_key (); + + if (!key) { + return NUMLOCK_STATE_UNKNOWN; + } + + curr_state = mateconf_client_get_bool (client, key, &err); + if (err) { + curr_state = NUMLOCK_STATE_UNKNOWN; + g_error_free (err); + } + + g_free (key); + return curr_state; +} + +static void +numlock_set_mateconf_state (MateConfClient *client, + NumLockState new_state) +{ + char *key; + + if (new_state != NUMLOCK_STATE_ON && new_state != NUMLOCK_STATE_OFF) { + return; + } + + key = numlock_mateconf_state_key (); + if (key) { + mateconf_client_set_bool (client, key, new_state, NULL); + g_free (key); + } +} + +static GdkFilterReturn +numlock_xkb_callback (GdkXEvent *xev_, + GdkEvent *gdkev_, + gpointer xkb_event_code) +{ + XEvent *xev = (XEvent *) xev_; + + if (xev->type == GPOINTER_TO_INT (xkb_event_code)) { + XkbEvent *xkbev = (XkbEvent *)xev; + if (xkbev->any.xkb_type == XkbStateNotify) + if (xkbev->state.changed & XkbModifierLockMask) { + unsigned num_mask = numlock_NumLock_modifier_mask (); + unsigned locked_mods = xkbev->state.locked_mods; + int numlock_state = !! (num_mask & locked_mods); + MateConfClient *client = mateconf_client_get_default (); + numlock_set_mateconf_state (client, numlock_state); + g_object_unref (client); + } + } + return GDK_FILTER_CONTINUE; +} + +static void +numlock_install_xkb_callback (GsdKeyboardManager *manager) +{ + if (!manager->priv->have_xkb) + return; + + gdk_window_add_filter (NULL, + numlock_xkb_callback, + GINT_TO_POINTER (manager->priv->xkb_event_base)); +} + +#endif /* HAVE_X11_EXTENSIONS_XKB_H */ + +static void +apply_settings (MateConfClient *client, + guint cnxn_id, + MateConfEntry *entry, + GsdKeyboardManager *manager) +{ + XKeyboardControl kbdcontrol; + gboolean repeat; + gboolean click; + int rate; + int delay; + int click_volume; + int bell_volume; + int bell_pitch; + int bell_duration; + char *volume_string; +#ifdef HAVE_X11_EXTENSIONS_XKB_H + gboolean rnumlock; +#endif /* HAVE_X11_EXTENSIONS_XKB_H */ + + repeat = mateconf_client_get_bool (client, KEY_REPEAT, NULL); + click = mateconf_client_get_bool (client, KEY_CLICK, NULL); + rate = mateconf_client_get_int (client, KEY_RATE, NULL); + delay = mateconf_client_get_int (client, KEY_DELAY, NULL); + click_volume = mateconf_client_get_int (client, KEY_CLICK_VOLUME, NULL); +#if 0 + bell_volume = mateconf_client_get_int (client, KEY_BELL_VOLUME, NULL); +#endif + bell_pitch = mateconf_client_get_int (client, KEY_BELL_PITCH, NULL); + bell_duration = mateconf_client_get_int (client, KEY_BELL_DURATION, NULL); + + volume_string = mateconf_client_get_string (client, KEY_BELL_MODE, NULL); + bell_volume = (volume_string && !strcmp (volume_string, "on")) ? 50 : 0; + g_free (volume_string); + +#ifdef HAVE_X11_EXTENSIONS_XKB_H + rnumlock = mateconf_client_get_bool (client, GSD_KEYBOARD_KEY "/remember_numlock_state", NULL); +#endif /* HAVE_X11_EXTENSIONS_XKB_H */ + + gdk_error_trap_push (); + if (repeat) { + gboolean rate_set = FALSE; + + XAutoRepeatOn (GDK_DISPLAY ()); + /* Use XKB in preference */ +#ifdef HAVE_X11_EXTENSIONS_XKB_H + rate_set = xkb_set_keyboard_autorepeat_rate (delay, rate); +#endif +#ifdef HAVE_X11_EXTENSIONS_XF86MISC_H + if (!rate_set) + rate_set = xfree86_set_keyboard_autorepeat_rate (delay, rate); +#endif + if (!rate_set) + g_warning ("Neither XKeyboard not Xfree86's keyboard extensions are available,\n" + "no way to support keyboard autorepeat rate settings"); + } else { + XAutoRepeatOff (GDK_DISPLAY ()); + } + + /* as percentage from 0..100 inclusive */ + if (click_volume < 0) { + click_volume = 0; + } else if (click_volume > 100) { + click_volume = 100; + } + kbdcontrol.key_click_percent = click ? click_volume : 0; + kbdcontrol.bell_percent = bell_volume; + kbdcontrol.bell_pitch = bell_pitch; + kbdcontrol.bell_duration = bell_duration; + XChangeKeyboardControl (GDK_DISPLAY (), + KBKeyClickPercent | KBBellPercent | KBBellPitch | KBBellDuration, + &kbdcontrol); + +#ifdef HAVE_X11_EXTENSIONS_XKB_H + if (manager->priv->have_xkb && rnumlock) { + numlock_set_xkb_state (numlock_get_mateconf_state (client)); + } +#endif /* HAVE_X11_EXTENSIONS_XKB_H */ + + XSync (GDK_DISPLAY (), FALSE); + gdk_error_trap_pop (); +} + +void +gsd_keyboard_manager_apply_settings (GsdKeyboardManager *manager) +{ + MateConfClient *client; + + client = mateconf_client_get_default (); + apply_settings (client, 0, NULL, manager); + g_object_unref (client); +} + +static gboolean +start_keyboard_idle_cb (GsdKeyboardManager *manager) +{ + MateConfClient *client; + + mate_settings_profile_start (NULL); + + g_debug ("Starting keyboard manager"); + + manager->priv->have_xkb = 0; + client = mateconf_client_get_default (); + + mateconf_client_add_dir (client, GSD_KEYBOARD_KEY, MATECONF_CLIENT_PRELOAD_RECURSIVE, NULL); + + /* Essential - xkb initialization should happen before */ + gsd_keyboard_xkb_set_post_activation_callback ((PostActivationCallback) gsd_load_modmap_files, NULL); + gsd_keyboard_xkb_init (client, manager); + +#ifdef HAVE_X11_EXTENSIONS_XKB_H + numlock_xkb_init (manager); +#endif /* HAVE_X11_EXTENSIONS_XKB_H */ + + /* apply current settings before we install the callback */ + gsd_keyboard_manager_apply_settings (manager); + + manager->priv->notify = mateconf_client_notify_add (client, GSD_KEYBOARD_KEY, + (MateConfClientNotifyFunc) apply_settings, manager, + NULL, NULL); + + g_object_unref (client); + +#ifdef HAVE_X11_EXTENSIONS_XKB_H + numlock_install_xkb_callback (manager); +#endif /* HAVE_X11_EXTENSIONS_XKB_H */ + + mate_settings_profile_end (NULL); + + return FALSE; +} + +gboolean +gsd_keyboard_manager_start (GsdKeyboardManager *manager, + GError **error) +{ + mate_settings_profile_start (NULL); + + g_idle_add ((GSourceFunc) start_keyboard_idle_cb, manager); + + mate_settings_profile_end (NULL); + + return TRUE; +} + +void +gsd_keyboard_manager_stop (GsdKeyboardManager *manager) +{ + GsdKeyboardManagerPrivate *p = manager->priv; + + g_debug ("Stopping keyboard manager"); + + if (p->notify != 0) { + MateConfClient *client = mateconf_client_get_default (); + mateconf_client_remove_dir (client, GSD_KEYBOARD_KEY, NULL); + mateconf_client_notify_remove (client, p->notify); + g_object_unref (client); + p->notify = 0; + } + +#if HAVE_X11_EXTENSIONS_XKB_H + if (p->have_xkb) { + gdk_window_remove_filter (NULL, + numlock_xkb_callback, + GINT_TO_POINTER (p->xkb_event_base)); + } +#endif /* HAVE_X11_EXTENSIONS_XKB_H */ + + gsd_keyboard_xkb_shutdown (); +} + +static void +gsd_keyboard_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GsdKeyboardManager *self; + + self = GSD_KEYBOARD_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gsd_keyboard_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GsdKeyboardManager *self; + + self = GSD_KEYBOARD_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +gsd_keyboard_manager_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GsdKeyboardManager *keyboard_manager; + GsdKeyboardManagerClass *klass; + + klass = GSD_KEYBOARD_MANAGER_CLASS (g_type_class_peek (GSD_TYPE_KEYBOARD_MANAGER)); + + keyboard_manager = GSD_KEYBOARD_MANAGER (G_OBJECT_CLASS (gsd_keyboard_manager_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + + return G_OBJECT (keyboard_manager); +} + +static void +gsd_keyboard_manager_dispose (GObject *object) +{ + GsdKeyboardManager *keyboard_manager; + + keyboard_manager = GSD_KEYBOARD_MANAGER (object); + + G_OBJECT_CLASS (gsd_keyboard_manager_parent_class)->dispose (object); +} + +static void +gsd_keyboard_manager_class_init (GsdKeyboardManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gsd_keyboard_manager_get_property; + object_class->set_property = gsd_keyboard_manager_set_property; + object_class->constructor = gsd_keyboard_manager_constructor; + object_class->dispose = gsd_keyboard_manager_dispose; + object_class->finalize = gsd_keyboard_manager_finalize; + + g_type_class_add_private (klass, sizeof (GsdKeyboardManagerPrivate)); +} + +static void +gsd_keyboard_manager_init (GsdKeyboardManager *manager) +{ + manager->priv = GSD_KEYBOARD_MANAGER_GET_PRIVATE (manager); +} + +static void +gsd_keyboard_manager_finalize (GObject *object) +{ + GsdKeyboardManager *keyboard_manager; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_KEYBOARD_MANAGER (object)); + + keyboard_manager = GSD_KEYBOARD_MANAGER (object); + + g_return_if_fail (keyboard_manager->priv != NULL); + + G_OBJECT_CLASS (gsd_keyboard_manager_parent_class)->finalize (object); +} + +GsdKeyboardManager * +gsd_keyboard_manager_new (void) +{ + if (manager_object != NULL) { + g_object_ref (manager_object); + } else { + manager_object = g_object_new (GSD_TYPE_KEYBOARD_MANAGER, NULL); + g_object_add_weak_pointer (manager_object, + (gpointer *) &manager_object); + } + + return GSD_KEYBOARD_MANAGER (manager_object); +} diff --git a/plugins/keyboard/gsd-keyboard-manager.h b/plugins/keyboard/gsd-keyboard-manager.h new file mode 100644 index 0000000..a518e9a --- /dev/null +++ b/plugins/keyboard/gsd-keyboard-manager.h @@ -0,0 +1,62 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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_KEYBOARD_MANAGER_H +#define __GSD_KEYBOARD_MANAGER_H + +#include <glib-object.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_KEYBOARD_MANAGER (gsd_keyboard_manager_get_type ()) +#define GSD_KEYBOARD_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_KEYBOARD_MANAGER, GsdKeyboardManager)) +#define GSD_KEYBOARD_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_KEYBOARD_MANAGER, GsdKeyboardManagerClass)) +#define GSD_IS_KEYBOARD_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_KEYBOARD_MANAGER)) +#define GSD_IS_KEYBOARD_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_KEYBOARD_MANAGER)) +#define GSD_KEYBOARD_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_KEYBOARD_MANAGER, GsdKeyboardManagerClass)) + +typedef struct GsdKeyboardManagerPrivate GsdKeyboardManagerPrivate; + +typedef struct +{ + GObject parent; + GsdKeyboardManagerPrivate *priv; +} GsdKeyboardManager; + +typedef struct +{ + GObjectClass parent_class; +} GsdKeyboardManagerClass; + +GType gsd_keyboard_manager_get_type (void); + +GsdKeyboardManager * gsd_keyboard_manager_new (void); +gboolean gsd_keyboard_manager_start (GsdKeyboardManager *manager, + GError **error); +void gsd_keyboard_manager_stop (GsdKeyboardManager *manager); +void gsd_keyboard_manager_apply_settings (GsdKeyboardManager *manager); + +#ifdef __cplusplus +} +#endif + +#endif /* __GSD_KEYBOARD_MANAGER_H */ diff --git a/plugins/keyboard/gsd-keyboard-plugin.c b/plugins/keyboard/gsd-keyboard-plugin.c new file mode 100644 index 0000000..b501d80 --- /dev/null +++ b/plugins/keyboard/gsd-keyboard-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 <[email protected]> + * + * 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 <glib/gi18n-lib.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" +#include "gsd-keyboard-plugin.h" +#include "gsd-keyboard-manager.h" + +struct GsdKeyboardPluginPrivate { + GsdKeyboardManager *manager; +}; + +#define GSD_KEYBOARD_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSD_TYPE_KEYBOARD_PLUGIN, GsdKeyboardPluginPrivate)) + +MATE_SETTINGS_PLUGIN_REGISTER (GsdKeyboardPlugin, gsd_keyboard_plugin) + +static void +gsd_keyboard_plugin_init (GsdKeyboardPlugin *plugin) +{ + plugin->priv = GSD_KEYBOARD_PLUGIN_GET_PRIVATE (plugin); + + g_debug ("GsdKeyboardPlugin initializing"); + + plugin->priv->manager = gsd_keyboard_manager_new (); +} + +static void +gsd_keyboard_plugin_finalize (GObject *object) +{ + GsdKeyboardPlugin *plugin; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_KEYBOARD_PLUGIN (object)); + + g_debug ("GsdKeyboardPlugin finalizing"); + + plugin = GSD_KEYBOARD_PLUGIN (object); + + g_return_if_fail (plugin->priv != NULL); + + if (plugin->priv->manager != NULL) { + g_object_unref (plugin->priv->manager); + } + + G_OBJECT_CLASS (gsd_keyboard_plugin_parent_class)->finalize (object); +} + +static void +impl_activate (MateSettingsPlugin *plugin) +{ + gboolean res; + GError *error; + + g_debug ("Activating keyboard plugin"); + + error = NULL; + res = gsd_keyboard_manager_start (GSD_KEYBOARD_PLUGIN (plugin)->priv->manager, &error); + if (! res) { + g_warning ("Unable to start keyboard manager: %s", error->message); + g_error_free (error); + } +} + +static void +impl_deactivate (MateSettingsPlugin *plugin) +{ + g_debug ("Deactivating keyboard plugin"); + gsd_keyboard_manager_stop (GSD_KEYBOARD_PLUGIN (plugin)->priv->manager); +} + +static void +gsd_keyboard_plugin_class_init (GsdKeyboardPluginClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MateSettingsPluginClass *plugin_class = MATE_SETTINGS_PLUGIN_CLASS (klass); + + object_class->finalize = gsd_keyboard_plugin_finalize; + + plugin_class->activate = impl_activate; + plugin_class->deactivate = impl_deactivate; + + g_type_class_add_private (klass, sizeof (GsdKeyboardPluginPrivate)); +} diff --git a/plugins/keyboard/gsd-keyboard-plugin.h b/plugins/keyboard/gsd-keyboard-plugin.h new file mode 100644 index 0000000..3d25861 --- /dev/null +++ b/plugins/keyboard/gsd-keyboard-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 <[email protected]> + * + * 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_KEYBOARD_PLUGIN_H__ +#define __GSD_KEYBOARD_PLUGIN_H__ + +#include <glib.h> +#include <glib-object.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_KEYBOARD_PLUGIN (gsd_keyboard_plugin_get_type ()) +#define GSD_KEYBOARD_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_KEYBOARD_PLUGIN, GsdKeyboardPlugin)) +#define GSD_KEYBOARD_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_KEYBOARD_PLUGIN, GsdKeyboardPluginClass)) +#define GSD_IS_KEYBOARD_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_KEYBOARD_PLUGIN)) +#define GSD_IS_KEYBOARD_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_KEYBOARD_PLUGIN)) +#define GSD_KEYBOARD_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_KEYBOARD_PLUGIN, GsdKeyboardPluginClass)) + +typedef struct GsdKeyboardPluginPrivate GsdKeyboardPluginPrivate; + +typedef struct +{ + MateSettingsPlugin parent; + GsdKeyboardPluginPrivate *priv; +} GsdKeyboardPlugin; + +typedef struct +{ + MateSettingsPluginClass parent_class; +} GsdKeyboardPluginClass; + +GType gsd_keyboard_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_KEYBOARD_PLUGIN_H__ */ diff --git a/plugins/keyboard/gsd-keyboard-xkb.c b/plugins/keyboard/gsd-keyboard-xkb.c new file mode 100644 index 0000000..681c665 --- /dev/null +++ b/plugins/keyboard/gsd-keyboard-xkb.c @@ -0,0 +1,924 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2001 Udaltsoft + * + * Written by Sergey V. Oudaltsov <[email protected]> + * + * 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 <string.h> +#include <time.h> + +#include <glib/gi18n.h> +#include <gdk/gdk.h> +#include <gdk/gdkx.h> +#include <gtk/gtk.h> +#include <mateconf/mateconf-client.h> + +#include <libmatekbd/matekbd-status.h> +#include <libmatekbd/matekbd-keyboard-drawing.h> +#include <libmatekbd/matekbd-desktop-config.h> +#include <libmatekbd/matekbd-keyboard-config.h> +#include <libmatekbd/matekbd-util.h> + +#include "gsd-xmodmap.h" +#include "gsd-keyboard-xkb.h" +#include "delayed-dialog.h" +#include "mate-settings-profile.h" + +#define GTK_RESPONSE_PRINT 2 + +static GsdKeyboardManager *manager = NULL; + +static XklEngine *xkl_engine; +static XklConfigRegistry *xkl_registry = NULL; + +static MatekbdDesktopConfig current_config; +static MatekbdKeyboardConfig current_kbd_config; + +/* never terminated */ +static MatekbdKeyboardConfig initial_sys_kbd_config; + +static gboolean inited_ok = FALSE; + +static guint notify_desktop = 0; +static guint notify_keyboard = 0; + +static PostActivationCallback pa_callback = NULL; +static void *pa_callback_user_data = NULL; + +static const char KNOWN_FILES_KEY[] = + "/desktop/mate/peripherals/keyboard/general/known_file_list"; + +static const char DISABLE_INDICATOR_KEY[] = + "/desktop/mate/peripherals/keyboard/general/disable_indicator"; + +static const char DUPLICATE_LEDS_KEY[] = + "/desktop/mate/peripherals/keyboard/general/duplicate_leds"; + +static const char *mdm_keyboard_layout = NULL; + +static GtkStatusIcon *icon = NULL; + +static GHashTable *preview_dialogs = NULL; + +static Atom caps_lock; +static Atom num_lock; +static Atom scroll_lock; + +static GtkStatusIcon *indicator_icons[3]; +static const gchar *indicator_on_icon_names[] = { + "kbd-scrolllock-on", + "kbd-numlock-on", + "kbd-capslock-on" +}; + +static const gchar *indicator_off_icon_names[] = { + "kbd-scrolllock-off", + "kbd-numlock-off", + "kbd-capslock-off" +}; + +#define noGSDKX + +#ifdef GSDKX +static FILE *logfile; + +static void +gsd_keyboard_log_appender (const char file[], + const char function[], + int level, const char format[], va_list args) +{ + time_t now = time (NULL); + fprintf (logfile, "[%08ld,%03d,%s:%s/] \t", now, + level, file, function); + vfprintf (logfile, format, args); + fflush (logfile); +} +#endif + +static void +activation_error (void) +{ + char const *vendor = ServerVendor (GDK_DISPLAY ()); + int release = VendorRelease (GDK_DISPLAY ()); + GtkWidget *dialog; + gboolean badXFree430Release; + + badXFree430Release = (vendor != NULL) + && (0 == strcmp (vendor, "The XFree86 Project, Inc")) + && (release / 100000 == 403); + + /* VNC viewers will not work, do not barrage them with warnings */ + if (NULL != vendor && NULL != strstr (vendor, "VNC")) + return; + + dialog = gtk_message_dialog_new_with_markup (NULL, + 0, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + _ + ("Error activating XKB configuration.\n" + "It can happen under various circumstances:\n" + " • a bug in libxklavier library\n" + " • a bug in X server (xkbcomp, xmodmap utilities)\n" + " • X server with incompatible libxkbfile implementation\n\n" + "X server version data:\n%s\n%d\n%s\n" + "If you report this situation as a bug, please include:\n" + " • The result of <b>%s</b>\n" + " • The result of <b>%s</b>"), + vendor, + release, + badXFree430Release + ? + _ + ("You are using XFree 4.3.0.\n" + "There are known problems with complex XKB configurations.\n" + "Try using a simpler configuration or using a later version of the XFree software.") + : "", + "xprop -root | grep XKB", + "mateconftool-2 -R /desktop/mate/peripherals/keyboard/kbd"); + g_signal_connect (dialog, "response", + G_CALLBACK (gtk_widget_destroy), NULL); + gsd_delayed_show_dialog (dialog); +} + +static void +apply_desktop_settings (void) +{ + MateConfClient *conf_client; + gboolean show_leds; + int i; + if (!inited_ok) + return; + + gsd_keyboard_manager_apply_settings (manager); + matekbd_desktop_config_load_from_mateconf (¤t_config); + /* again, probably it would be nice to compare things + before activating them */ + matekbd_desktop_config_activate (¤t_config); + + conf_client = mateconf_client_get_default (); + show_leds = + mateconf_client_get_bool (conf_client, DUPLICATE_LEDS_KEY, NULL); + g_object_unref (conf_client); + for (i = sizeof (indicator_icons) / sizeof (indicator_icons[0]); + --i >= 0;) { + gtk_status_icon_set_visible (indicator_icons[i], + show_leds); + } +} + +static void +popup_menu_launch_capplet () +{ + GError *error = NULL; + + gdk_spawn_command_line_on_screen (gdk_screen_get_default (), + "mate-keyboard-properties", + &error); + + if (error != NULL) { + g_warning + ("Could not execute keyboard properties capplet: [%s]\n", + error->message); + g_error_free (error); + } +} + +static void +show_layout_destroy (GtkWidget * dialog, gint group) +{ + g_hash_table_remove (preview_dialogs, GINT_TO_POINTER (group)); +} + +static void +popup_menu_show_layout () +{ + GtkWidget *dialog; + XklEngine *engine = xkl_engine_get_instance (GDK_DISPLAY ()); + XklState *xkl_state = xkl_engine_get_current_state (engine); + gpointer p = g_hash_table_lookup (preview_dialogs, + GINT_TO_POINTER + (xkl_state->group)); + gchar **group_names = matekbd_status_get_group_names (); + + if (xkl_state->group < 0 + || xkl_state->group >= g_strv_length (group_names)) { + return; + } + + if (p != NULL) { + /* existing window */ + gtk_window_present (GTK_WINDOW (p)); + return; + } + + dialog = + matekbd_keyboard_drawing_new_dialog (xkl_state->group, + group_names + [xkl_state->group]); + g_signal_connect (GTK_OBJECT (dialog), "destroy", + G_CALLBACK (show_layout_destroy), + GINT_TO_POINTER (xkl_state->group)); + g_hash_table_insert (preview_dialogs, + GINT_TO_POINTER (xkl_state->group), dialog); +} + +static void +popup_menu_set_group (GtkMenuItem * item, gpointer param) +{ + gint group_number = GPOINTER_TO_INT (param); + XklEngine *engine = matekbd_status_get_xkl_engine (); + XklState st; + Window cur; + + st.group = group_number; + xkl_engine_allow_one_switch_to_secondary_group (engine); + cur = xkl_engine_get_current_window (engine); + if (cur != (Window) NULL) { + xkl_debug (150, "Enforcing the state %d for window %lx\n", + st.group, cur); + xkl_engine_save_state (engine, + xkl_engine_get_current_window + (engine), &st); +/* XSetInputFocus( GDK_DISPLAY(), cur, RevertToNone, CurrentTime );*/ + } else { + xkl_debug (150, + "??? Enforcing the state %d for unknown window\n", + st.group); + /* strange situation - bad things can happen */ + } + xkl_engine_lock_group (engine, st.group); +} + +static void +status_icon_popup_menu_cb (GtkStatusIcon * icon, guint button, guint time) +{ + GtkMenu *popup_menu = GTK_MENU (gtk_menu_new ()); + GtkMenu *groups_menu = GTK_MENU (gtk_menu_new ()); + int i = 0; + gchar **current_name = matekbd_status_get_group_names (); + + GtkWidget *item = gtk_menu_item_new_with_mnemonic (_("_Layouts")); + gtk_widget_show (item); + gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), + GTK_WIDGET (groups_menu)); + + item = + gtk_menu_item_new_with_mnemonic (_("Keyboard _Preferences")); + gtk_widget_show (item); + g_signal_connect (item, "activate", popup_menu_launch_capplet, + NULL); + gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item); + + item = gtk_menu_item_new_with_mnemonic (_("Show _Current Layout")); + gtk_widget_show (item); + g_signal_connect (item, "activate", popup_menu_show_layout, NULL); + gtk_menu_shell_append (GTK_MENU_SHELL (popup_menu), item); + + for (i = 0; *current_name; i++, current_name++) { + gchar *image_file = matekbd_status_get_image_filename (i); + + if (image_file == NULL) { + item = + gtk_menu_item_new_with_label (*current_name); + } else { + GdkPixbuf *pixbuf = + gdk_pixbuf_new_from_file_at_size (image_file, + 24, 24, + NULL); + GtkWidget *img = + gtk_image_new_from_pixbuf (pixbuf); + item = + gtk_image_menu_item_new_with_label + (*current_name); + gtk_widget_show (img); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM + (item), img); + gtk_image_menu_item_set_always_show_image + (GTK_IMAGE_MENU_ITEM (item), TRUE); + g_free (image_file); + } + gtk_widget_show (item); + gtk_menu_shell_append (GTK_MENU_SHELL (groups_menu), item); + g_signal_connect (item, "activate", + G_CALLBACK (popup_menu_set_group), + GINT_TO_POINTER (i)); + } + + gtk_menu_popup (popup_menu, NULL, NULL, + gtk_status_icon_position_menu, + (gpointer) icon, button, time); +} + +static void +show_hide_icon () +{ + if (g_slist_length (current_kbd_config.layouts_variants) > 1) { + if (icon == NULL) { + MateConfClient *conf_client = + mateconf_client_get_default (); + gboolean disable = + mateconf_client_get_bool (conf_client, + DISABLE_INDICATOR_KEY, + NULL); + g_object_unref (conf_client); + if (disable) + return; + + xkl_debug (150, "Creating new icon\n"); + icon = matekbd_status_new (); + g_signal_connect (icon, "popup-menu", + G_CALLBACK + (status_icon_popup_menu_cb), + NULL); + + } + } else { + if (icon != NULL) { + xkl_debug (150, "Destroying icon\n"); + g_object_unref (icon); + icon = NULL; + } + } +} + +static gboolean +try_activating_xkb_config_if_new (MatekbdKeyboardConfig * + current_sys_kbd_config) +{ + /* Activate - only if different! */ + if (!matekbd_keyboard_config_equals + (¤t_kbd_config, current_sys_kbd_config)) { + if (matekbd_keyboard_config_activate (¤t_kbd_config)) { + if (pa_callback != NULL) { + (*pa_callback) (pa_callback_user_data); + return TRUE; + } + } else { + return FALSE; + } + } + return TRUE; +} + +static gboolean +filter_xkb_config (void) +{ + XklConfigItem *item; + gchar *lname; + gchar *vname; + GSList *lv; + GSList *filtered; + gboolean any_change = FALSE; + + xkl_debug (100, "Filtering configuration against the registry\n"); + if (!xkl_registry) { + xkl_registry = + xkl_config_registry_get_instance (xkl_engine); + /* load all materials, unconditionally! */ + if (!xkl_config_registry_load (xkl_registry, TRUE)) { + g_object_unref (xkl_registry); + xkl_registry = NULL; + return FALSE; + } + } + lv = current_kbd_config.layouts_variants; + item = xkl_config_item_new (); + while (lv) { + xkl_debug (100, "Checking [%s]\n", lv->data); + if (matekbd_keyboard_config_split_items + (lv->data, &lname, &vname)) { + g_snprintf (item->name, sizeof (item->name), "%s", + lname); + if (!xkl_config_registry_find_layout + (xkl_registry, item)) { + xkl_debug (100, "Bad layout [%s]\n", + lname); + filtered = lv; + lv = lv->next; + g_free (filtered->data); + current_kbd_config.layouts_variants = + g_slist_delete_link + (current_kbd_config.layouts_variants, + filtered); + any_change = TRUE; + continue; + } + if (vname) { + g_snprintf (item->name, + sizeof (item->name), "%s", + vname); + if (!xkl_config_registry_find_variant + (xkl_registry, lname, item)) { + xkl_debug (100, + "Bad variant [%s(%s)]\n", + lname, vname); + filtered = lv; + lv = lv->next; + g_free (filtered->data); + current_kbd_config.layouts_variants + = + g_slist_delete_link + (current_kbd_config.layouts_variants, + filtered); + any_change = TRUE; + continue; + } + } + } + lv = lv->next; + } + g_object_unref (item); + return any_change; +} + +static void +apply_xkb_settings (void) +{ + MateConfClient *conf_client; + MatekbdKeyboardConfig current_sys_kbd_config; + int group_to_activate = -1; + char *mdm_layout; + char *s; + + if (!inited_ok) + return; + + conf_client = mateconf_client_get_default (); + + /* With MDM the user can already set a layout from the login + * screen. Try to keep that setting. + * We clear mdm_keyboard_layout early, so we don't risk + * recursion from mateconf notification. + */ + mdm_layout = g_strdup (mdm_keyboard_layout); + mdm_keyboard_layout = NULL; + + /* mdm's configuration and $MDM_KEYBOARD_LAYOUT separates layout and + * variant with a space, but mateconf uses tabs; so convert to be robust + * with both */ + for (s = mdm_layout; s && *s; ++s) { + if (*s == ' ') { + *s = '\t'; + } + } + + if (mdm_layout != NULL) { + GSList *layouts; + GSList *found_node; + int max_groups; + + max_groups = + MAX (xkl_engine_get_max_num_groups (xkl_engine), 1); + layouts = + mateconf_client_get_list (conf_client, + MATEKBD_KEYBOARD_CONFIG_KEY_LAYOUTS, + MATECONF_VALUE_STRING, NULL); + + /* Use system layouts as a default if we do not have + * user configuration */ + if (layouts == NULL) { + GSList *i; + int len; + + for (i = initial_sys_kbd_config.layouts_variants; + i; i = g_slist_next (i)) { + s = g_strdup (i->data); + + /* chop off empty variants to avoid duplicates */ + len = strlen (s); + if (s[len - 1] == '\t') + s[len - 1] = '\0'; + layouts = g_slist_append (layouts, s); + } + } + + /* Add the layout if it doesn't already exist. XKB limits the + * total number of layouts. If we already have the maximum + * number of layouts configured, we replace the last one. This + * prevents the list from becoming full if the user has a habit + * of selecting many different keyboard layouts in MDM. */ + + found_node = + g_slist_find_custom (layouts, mdm_layout, + (GCompareFunc) g_strcmp0); + + if (!found_node) { + /* Insert at the last valid place, or at the end of + * list, whichever comes first */ + layouts = + g_slist_insert (layouts, g_strdup (mdm_layout), + max_groups - 1); + if (g_slist_length (layouts) > max_groups) { + GSList *last; + GSList *free_layouts; + + last = + g_slist_nth (layouts, max_groups - 1); + free_layouts = last->next; + last->next = NULL; + + g_slist_foreach (free_layouts, + (GFunc) g_free, NULL); + g_slist_free (free_layouts); + } + + mateconf_client_set_list (conf_client, + MATEKBD_KEYBOARD_CONFIG_KEY_LAYOUTS, + MATECONF_VALUE_STRING, layouts, + NULL); + } + + g_slist_foreach (layouts, (GFunc) g_free, NULL); + g_slist_free (layouts); + } + + matekbd_keyboard_config_init (¤t_sys_kbd_config, + conf_client, xkl_engine); + + matekbd_keyboard_config_load_from_mateconf (¤t_kbd_config, + &initial_sys_kbd_config); + + matekbd_keyboard_config_load_from_x_current (¤t_sys_kbd_config, + NULL); + + if (!try_activating_xkb_config_if_new (¤t_sys_kbd_config)) { + if (filter_xkb_config ()) { + if (!try_activating_xkb_config_if_new + (¤t_sys_kbd_config)) { + g_warning + ("Could not activate the filtered XKB configuration"); + activation_error (); + } + } else { + g_warning + ("Could not activate the XKB configuration"); + activation_error (); + } + } else + xkl_debug (100, + "Actual KBD configuration was not changed: redundant notification\n"); + + if (mdm_layout != NULL) { + /* If there are multiple layouts, + * try to find the one closest to the mdm layout + */ + GSList *l; + int i; + size_t len = strlen (mdm_layout); + for (i = 0, l = current_kbd_config.layouts_variants; l; + i++, l = l->next) { + char *lv = l->data; + if (strncmp (lv, mdm_layout, len) == 0 + && (lv[len] == '\0' || lv[len] == '\t')) { + group_to_activate = i; + break; + } + } + } + + g_free (mdm_layout); + + if (group_to_activate != -1) + xkl_engine_lock_group (current_config.engine, + group_to_activate); + matekbd_keyboard_config_term (¤t_sys_kbd_config); + show_hide_icon (); +} + +static void +gsd_keyboard_xkb_analyze_sysconfig (void) +{ + MateConfClient *conf_client; + + if (!inited_ok) + return; + + conf_client = mateconf_client_get_default (); + matekbd_keyboard_config_init (&initial_sys_kbd_config, + conf_client, xkl_engine); + matekbd_keyboard_config_load_from_x_initial (&initial_sys_kbd_config, + NULL); + g_object_unref (conf_client); +} + +static gboolean +gsd_chk_file_list (void) +{ + GDir *home_dir; + const char *fname; + GSList *file_list = NULL; + GSList *last_login_file_list = NULL; + GSList *tmp = NULL; + GSList *tmp_l = NULL; + gboolean new_file_exist = FALSE; + MateConfClient *conf_client; + + home_dir = g_dir_open (g_get_home_dir (), 0, NULL); + while ((fname = g_dir_read_name (home_dir)) != NULL) { + if (g_strrstr (fname, "modmap")) { + file_list = + g_slist_append (file_list, g_strdup (fname)); + } + } + g_dir_close (home_dir); + + conf_client = mateconf_client_get_default (); + + last_login_file_list = mateconf_client_get_list (conf_client, + KNOWN_FILES_KEY, + MATECONF_VALUE_STRING, + NULL); + + /* Compare between the two file list, currently available modmap files + and the files available in the last log in */ + tmp = file_list; + while (tmp != NULL) { + tmp_l = last_login_file_list; + new_file_exist = TRUE; + while (tmp_l != NULL) { + if (strcmp (tmp->data, tmp_l->data) == 0) { + new_file_exist = FALSE; + break; + } else { + tmp_l = tmp_l->next; + } + } + if (new_file_exist) { + break; + } else { + tmp = tmp->next; + } + } + + if (new_file_exist) { + mateconf_client_set_list (conf_client, + KNOWN_FILES_KEY, + MATECONF_VALUE_STRING, + file_list, NULL); + } + + g_object_unref (conf_client); + + g_slist_foreach (file_list, (GFunc) g_free, NULL); + g_slist_free (file_list); + + g_slist_foreach (last_login_file_list, (GFunc) g_free, NULL); + g_slist_free (last_login_file_list); + + return new_file_exist; + +} + +static void +gsd_keyboard_xkb_chk_lcl_xmm (void) +{ + if (gsd_chk_file_list ()) { + gsd_modmap_dialog_call (); + } + gsd_load_modmap_files (); +} + +void +gsd_keyboard_xkb_set_post_activation_callback (PostActivationCallback fun, + void *user_data) +{ + pa_callback = fun; + pa_callback_user_data = user_data; +} + +static GdkFilterReturn +gsd_keyboard_xkb_evt_filter (GdkXEvent * xev, GdkEvent * event) +{ + XEvent *xevent = (XEvent *) xev; + xkl_engine_filter_events (xkl_engine, xevent); + return GDK_FILTER_CONTINUE; +} + +static guint +register_config_callback (MateConfClient * client, + const char *path, MateConfClientNotifyFunc func) +{ + mateconf_client_add_dir (client, path, MATECONF_CLIENT_PRELOAD_ONELEVEL, + NULL); + return mateconf_client_notify_add (client, path, func, NULL, NULL, + NULL); +} + +/* When new Keyboard is plugged in - reload the settings */ +static void +gsd_keyboard_new_device (XklEngine * engine) +{ + apply_desktop_settings (); + apply_xkb_settings (); +} + +static void +gsd_keyboard_update_indicator_icons () +{ + Bool state; + int new_state, i; + Display *display = GDK_DISPLAY (); + XkbGetNamedIndicator (display, caps_lock, NULL, &state, + NULL, NULL); + new_state = state ? 1 : 0; + XkbGetNamedIndicator (display, num_lock, NULL, &state, NULL, NULL); + new_state <<= 1; + new_state |= (state ? 1 : 0); + XkbGetNamedIndicator (display, scroll_lock, NULL, &state, + NULL, NULL); + new_state <<= 1; + new_state |= (state ? 1 : 0); + xkl_debug (160, "Indicators state: %d\n", new_state); + + + for (i = sizeof (indicator_icons) / sizeof (indicator_icons[0]); + --i >= 0;) { + gtk_status_icon_set_from_icon_name (indicator_icons[i], + (new_state & (1 << i)) + ? + indicator_on_icon_names + [i] : + indicator_off_icon_names + [i]); + } +} + +static void +gsd_keyboard_state_changed (XklEngine * engine, XklEngineStateChange type, + gint new_group, gboolean restore) +{ + xkl_debug (160, + "State changed: type %d, new group: %d, restore: %d.\n", + type, new_group, restore); + if (type == INDICATORS_CHANGED) { + gsd_keyboard_update_indicator_icons (); + } +} + +void +gsd_keyboard_xkb_init (MateConfClient * client, + GsdKeyboardManager * kbd_manager) +{ + int i; + Display *display = GDK_DISPLAY (); + mate_settings_profile_start (NULL); + + gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), + DATADIR G_DIR_SEPARATOR_S + "icons"); + + caps_lock = XInternAtom (display, "Caps Lock", False); + num_lock = XInternAtom (display, "Num Lock", False); + scroll_lock = XInternAtom (display, "Scroll Lock", False); + + for (i = sizeof (indicator_icons) / sizeof (indicator_icons[0]); + --i >= 0;) { + indicator_icons[i] = + gtk_status_icon_new_from_icon_name + (indicator_off_icon_names[i]); + } + + gsd_keyboard_update_indicator_icons (); + +#ifdef GSDKX + xkl_set_debug_level (200); + logfile = fopen ("/tmp/gsdkx.log", "a"); + xkl_set_log_appender (gsd_keyboard_log_appender); +#endif + manager = kbd_manager; + mate_settings_profile_start ("xkl_engine_get_instance"); + xkl_engine = xkl_engine_get_instance (display); + mate_settings_profile_end ("xkl_engine_get_instance"); + if (xkl_engine) { + inited_ok = TRUE; + + mdm_keyboard_layout = g_getenv ("MDM_KEYBOARD_LAYOUT"); + + matekbd_desktop_config_init (¤t_config, + client, xkl_engine); + matekbd_keyboard_config_init (¤t_kbd_config, + client, xkl_engine); + xkl_engine_backup_names_prop (xkl_engine); + gsd_keyboard_xkb_analyze_sysconfig (); + mate_settings_profile_start + ("gsd_keyboard_xkb_chk_lcl_xmm"); + gsd_keyboard_xkb_chk_lcl_xmm (); + mate_settings_profile_end + ("gsd_keyboard_xkb_chk_lcl_xmm"); + + notify_desktop = + register_config_callback (client, + MATEKBD_DESKTOP_CONFIG_DIR, + (MateConfClientNotifyFunc) + apply_desktop_settings); + + notify_keyboard = + register_config_callback (client, + MATEKBD_KEYBOARD_CONFIG_DIR, + (MateConfClientNotifyFunc) + apply_xkb_settings); + + gdk_window_add_filter (NULL, (GdkFilterFunc) + gsd_keyboard_xkb_evt_filter, NULL); + + if (xkl_engine_get_features (xkl_engine) & + XKLF_DEVICE_DISCOVERY) + g_signal_connect (xkl_engine, "X-new-device", + G_CALLBACK + (gsd_keyboard_new_device), NULL); + g_signal_connect (xkl_engine, "X-state-changed", + G_CALLBACK + (gsd_keyboard_state_changed), NULL); + + mate_settings_profile_start ("xkl_engine_start_listen"); + xkl_engine_start_listen (xkl_engine, + XKLL_MANAGE_LAYOUTS | + XKLL_MANAGE_WINDOW_STATES); + mate_settings_profile_end ("xkl_engine_start_listen"); + + mate_settings_profile_start ("apply_desktop_settings"); + apply_desktop_settings (); + mate_settings_profile_end ("apply_desktop_settings"); + mate_settings_profile_start ("apply_xkb_settings"); + apply_xkb_settings (); + mate_settings_profile_end ("apply_xkb_settings"); + } + preview_dialogs = g_hash_table_new (g_direct_hash, g_direct_equal); + + mate_settings_profile_end (NULL); +} + +void +gsd_keyboard_xkb_shutdown (void) +{ + MateConfClient *client; + int i; + + pa_callback = NULL; + pa_callback_user_data = NULL; + manager = NULL; + + for (i = sizeof (indicator_icons) / sizeof (indicator_icons[0]); + --i >= 0;) { + g_object_unref (G_OBJECT (indicator_icons[i])); + indicator_icons[i] = NULL; + } + + g_hash_table_destroy (preview_dialogs); + + if (!inited_ok) + return; + + xkl_engine_stop_listen (xkl_engine, + XKLL_MANAGE_LAYOUTS | + XKLL_MANAGE_WINDOW_STATES); + + gdk_window_remove_filter (NULL, (GdkFilterFunc) + gsd_keyboard_xkb_evt_filter, NULL); + + client = mateconf_client_get_default (); + + if (notify_desktop != 0) { + mateconf_client_remove_dir (client, MATEKBD_DESKTOP_CONFIG_DIR, + NULL); + mateconf_client_notify_remove (client, notify_desktop); + notify_desktop = 0; + } + + if (notify_keyboard != 0) { + mateconf_client_remove_dir (client, MATEKBD_KEYBOARD_CONFIG_DIR, + NULL); + mateconf_client_notify_remove (client, notify_keyboard); + notify_keyboard = 0; + } + + if (xkl_registry) { + g_object_unref (xkl_registry); + } + + g_object_unref (client); + g_object_unref (xkl_engine); + + xkl_engine = NULL; + inited_ok = FALSE; +} diff --git a/plugins/keyboard/gsd-keyboard-xkb.h b/plugins/keyboard/gsd-keyboard-xkb.h new file mode 100644 index 0000000..12b2846 --- /dev/null +++ b/plugins/keyboard/gsd-keyboard-xkb.h @@ -0,0 +1,42 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * mate-settings-keyboard-xkb.h + * + * Copyright (C) 2001 Udaltsoft + * + * Written by Sergey V. Oudaltsov <[email protected]> + * + * 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_KEYBOARD_XKB_H +#define __GSD_KEYBOARD_XKB_H + +#include <mateconf/mateconf.h> +#include <mateconf/mateconf-client.h> + +#include <libxklavier/xklavier.h> +#include "gsd-keyboard-manager.h" + +void gsd_keyboard_xkb_init (MateConfClient *client, GsdKeyboardManager *manager); +void gsd_keyboard_xkb_shutdown (void); + +typedef void (*PostActivationCallback) (void *userData); + +void +gsd_keyboard_xkb_set_post_activation_callback (PostActivationCallback fun, + void *userData); + +#endif diff --git a/plugins/keyboard/gsd-xmodmap.c b/plugins/keyboard/gsd-xmodmap.c new file mode 100644 index 0000000..b9ffc9c --- /dev/null +++ b/plugins/keyboard/gsd-xmodmap.c @@ -0,0 +1,399 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright © 2005 Novell Inc. + * + * Written by Shakti Sen <[email protected]> + * + * 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 <string.h> + +#include <glib.h> +#include <gtk/gtk.h> +#include <mateconf/mateconf-client.h> + +#include "gsd-xmodmap.h" + +static const char DISABLE_XMM_WARNING_KEY[] = + "/desktop/mate/peripherals/keyboard/disable_xmm_and_xkb_warning"; + +static const char LOADED_FILES_KEY[] = + "/desktop/mate/peripherals/keyboard/general/update_handlers"; + + +static void +check_button_callback (GtkWidget *chk_button, + gpointer data) +{ + MateConfClient *client; + + client = mateconf_client_get_default (); + + mateconf_client_set_bool (client, + DISABLE_XMM_WARNING_KEY, + gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (chk_button)), + NULL); + + g_object_unref (client); +} + +void +gsd_load_modmap_files (void) +{ + MateConfClient *client; + GSList *tmp; + GSList *loaded_file_list; + + client = mateconf_client_get_default (); + + loaded_file_list = mateconf_client_get_list (client, LOADED_FILES_KEY, MATECONF_VALUE_STRING, NULL); + + for (tmp = loaded_file_list; tmp != NULL; tmp = tmp->next) { + gchar *file; + gchar *command; + + file = g_build_filename (g_get_home_dir (), (gchar *) tmp->data, NULL); + command = g_strconcat ("xmodmap ", file, NULL); + g_free (file); + + g_spawn_command_line_async (command, NULL); + + g_free (command); + g_free (tmp->data); + } + + g_slist_free (loaded_file_list); + g_object_unref (client); +} + +static void +response_callback (GtkWidget *dialog, + int id, + void *data) +{ + if (id == GTK_RESPONSE_OK) { + GtkWidget *chk_button = g_object_get_data (G_OBJECT (dialog), "check_button"); + check_button_callback (chk_button, NULL); + gsd_load_modmap_files (); + } + gtk_widget_destroy (dialog); +} + +static void +get_selected_files_func (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer data) +{ + GSList **list = data; + gchar *filename; + + filename = NULL; + gtk_tree_model_get (model, + iter, + 0, + &filename, + -1); + + *list = g_slist_prepend (*list, filename); +} + +static GSList* +remove_string_from_list (GSList *list, + const char *str) +{ + GSList *tmp; + + for (tmp = list; tmp != NULL; tmp = tmp->next) { + if (strcmp (tmp->data, str) == 0) { + g_free (tmp->data); + list = g_slist_delete_link (list, tmp); + break; + } + } + + return list; +} + + +static void +remove_button_clicked_callback (GtkWidget *button, + void *data) +{ + GtkWidget *dialog; + GtkListStore *tree = NULL; + GtkTreeSelection *selection; + GtkWidget *treeview; + MateConfClient *client; + GSList *filenames = NULL; + GSList *tmp = NULL; + GSList *loaded_files = NULL; + + dialog = data; + + treeview = g_object_get_data (G_OBJECT (dialog), "treeview1"); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); + gtk_tree_selection_selected_foreach (selection, + get_selected_files_func, + &filenames); + + if (!filenames) + return; + + /* Remove the selected file */ + + client = mateconf_client_get_default (); + + loaded_files = mateconf_client_get_list (client, + LOADED_FILES_KEY, + MATECONF_VALUE_STRING, + NULL); + loaded_files = remove_string_from_list (loaded_files, (char *)filenames->data); + + mateconf_client_set_list (client, + LOADED_FILES_KEY, + MATECONF_VALUE_STRING, + loaded_files, + NULL); + g_object_unref (client); + + tree = g_object_get_data (G_OBJECT (dialog), "tree"); + + gtk_list_store_clear (tree); + for (tmp = loaded_files; tmp != NULL; tmp = tmp->next) { + GtkTreeIter iter; + gtk_list_store_append (tree, &iter); + gtk_list_store_set (tree, &iter, + 0, + tmp->data, + -1); + } + + g_slist_foreach (loaded_files, (GFunc) g_free, NULL); + g_slist_free (loaded_files); +} + +static void +load_button_clicked_callback (GtkWidget *button, + void *data) +{ + GtkWidget *dialog; + GtkListStore *tree = NULL; + GtkTreeSelection *selection; + GtkWidget *treeview; + GSList *filenames = NULL; + GSList *tmp = NULL; + GSList *loaded_files = NULL; + MateConfClient *client; + + dialog = data; + + treeview = g_object_get_data (G_OBJECT (dialog), + "loaded-treeview"); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); + gtk_tree_selection_selected_foreach (selection, + get_selected_files_func, + &filenames); + + if (!filenames) + return; + + /* Add the files to left-tree-view */ + client = mateconf_client_get_default (); + + loaded_files = mateconf_client_get_list (client, + LOADED_FILES_KEY, + MATECONF_VALUE_STRING, + NULL); + + if (g_slist_find_custom (loaded_files, filenames->data, (GCompareFunc) strcmp)) { + g_free (filenames->data); + g_slist_free (filenames); + goto out; + } + + loaded_files = g_slist_append (loaded_files, filenames->data); + mateconf_client_set_list (client, + LOADED_FILES_KEY, + MATECONF_VALUE_STRING, + loaded_files, + NULL); + + + tree = g_object_get_data (G_OBJECT (dialog), "tree"); + + gtk_list_store_clear (tree); + for (tmp = loaded_files; tmp != NULL; tmp = tmp->next) { + GtkTreeIter iter; + gtk_list_store_append (tree, &iter); + gtk_list_store_set (tree, &iter, + 0, + tmp->data, + -1); + } + +out: + g_object_unref (client); + g_slist_foreach (loaded_files, (GFunc) g_free, NULL); + g_slist_free (loaded_files); +} + +void +gsd_modmap_dialog_call (void) +{ + GtkBuilder *builder; + guint res; + GError *error; + GtkWidget *load_dialog; + GtkListStore *tree; + GtkCellRenderer *cell_renderer; + GtkTreeIter parent_iter; + GtkTreeIter iter; + GtkTreeModel *sort_model; + GtkTreeSelection *selection; + GtkWidget *treeview; + GtkWidget *treeview1; + GtkTreeViewColumn *column; + GtkWidget *add_button; + GtkWidget *remove_button; + GtkWidget *chk_button; + GSList *tmp; + GDir *homeDir; + GSList *loaded_files; + const char *fname; + MateConfClient *client; + + homeDir = g_dir_open (g_get_home_dir (), 0, NULL); + if (homeDir == NULL) + return; + + error = NULL; + builder = gtk_builder_new (); + res = gtk_builder_add_from_file (builder, + DATADIR "/modmap-dialog.ui", + &error); + + if (res == 0) { + g_warning ("Could not load UI file: %s", error->message); + g_error_free (error); + g_object_unref (builder); + g_dir_close (homeDir); + return; + } + + load_dialog = GTK_WIDGET (gtk_builder_get_object (builder, "dialog1")); + gtk_window_set_modal (GTK_WINDOW (load_dialog), TRUE); + g_signal_connect (load_dialog, + "response", + G_CALLBACK (response_callback), + builder); + add_button = GTK_WIDGET (gtk_builder_get_object (builder, "button7")); + g_signal_connect (add_button, + "clicked", + G_CALLBACK (load_button_clicked_callback), + load_dialog); + remove_button = GTK_WIDGET (gtk_builder_get_object (builder, + "button6")); + g_signal_connect (remove_button, + "clicked", + G_CALLBACK (remove_button_clicked_callback), + load_dialog); + chk_button = GTK_WIDGET (gtk_builder_get_object (builder, + "checkbutton1")); + g_signal_connect (chk_button, + "toggled", + G_CALLBACK (check_button_callback), + NULL); + g_object_set_data (G_OBJECT (load_dialog), "check_button", chk_button); + treeview = GTK_WIDGET (gtk_builder_get_object (builder, "treeview1")); + g_object_set_data (G_OBJECT (load_dialog), "treeview1", treeview); + treeview = GTK_WIDGET (gtk_builder_get_object (builder, "treeview2")); + g_object_set_data (G_OBJECT (load_dialog), "loaded-treeview", treeview); + tree = gtk_list_store_new (1, G_TYPE_STRING); + cell_renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ("modmap", + cell_renderer, + "text", 0, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); + gtk_tree_view_column_set_sort_column_id (column, 0); + + /* Add the data */ + while ((fname = g_dir_read_name (homeDir)) != NULL) { + if (g_strrstr (fname, "modmap")) { + gtk_list_store_append (tree, &parent_iter); + gtk_list_store_set (tree, &parent_iter, + 0, + fname, + -1); + } + } + sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree)); + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model), + 0, + GTK_SORT_ASCENDING); + gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), sort_model); + g_object_unref (G_OBJECT (tree)); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); + gtk_tree_selection_set_mode (GTK_TREE_SELECTION (selection), + GTK_SELECTION_MULTIPLE); + gtk_widget_show (load_dialog); + + g_dir_close (homeDir); + + /* Left treeview */ + treeview1 = GTK_WIDGET (gtk_builder_get_object (builder, "treeview1")); + tree = gtk_list_store_new (1, G_TYPE_STRING); + cell_renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ("modmap", + cell_renderer, + "text", 0, + NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (treeview1), column); + gtk_tree_view_column_set_sort_column_id (column, 0); + + client = mateconf_client_get_default (); + loaded_files = mateconf_client_get_list (client, LOADED_FILES_KEY, MATECONF_VALUE_STRING, NULL); + g_object_unref (client); + + /* Add the data */ + for (tmp = loaded_files; tmp != NULL; tmp = tmp->next) { + gtk_list_store_append (tree, &iter); + gtk_list_store_set (tree, &iter, + 0, + tmp->data, + -1); + } + + g_slist_foreach (loaded_files, (GFunc) g_free, NULL); + g_slist_free (loaded_files); + + sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (tree)); + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model), + 0, + GTK_SORT_ASCENDING); + gtk_tree_view_set_model (GTK_TREE_VIEW (treeview1), sort_model); + g_object_unref (G_OBJECT (tree)); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview1)); + gtk_tree_selection_set_mode (GTK_TREE_SELECTION (selection), + GTK_SELECTION_MULTIPLE); + g_object_set_data (G_OBJECT (load_dialog), "tree", tree); + g_object_unref (builder); +} diff --git a/plugins/keyboard/gsd-xmodmap.h b/plugins/keyboard/gsd-xmodmap.h new file mode 100644 index 0000000..7cfff74 --- /dev/null +++ b/plugins/keyboard/gsd-xmodmap.h @@ -0,0 +1,29 @@ +/* mate-settings-xmodmap.h + * + * Copyright © 2005 Novell Inc. + * + * Written by Shakti Sen <[email protected]> + * + * 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 XMODMAP_H +#define XMODMAP_H + +void gsd_load_modmap_files (void); +void gsd_modmap_dialog_call (void); + +#endif diff --git a/plugins/keyboard/kbd-capslock-off.png b/plugins/keyboard/kbd-capslock-off.png Binary files differnew file mode 100644 index 0000000..828cfa8 --- /dev/null +++ b/plugins/keyboard/kbd-capslock-off.png diff --git a/plugins/keyboard/kbd-capslock-on.png b/plugins/keyboard/kbd-capslock-on.png Binary files differnew file mode 100644 index 0000000..32ea0c9 --- /dev/null +++ b/plugins/keyboard/kbd-capslock-on.png diff --git a/plugins/keyboard/kbd-numlock-off.png b/plugins/keyboard/kbd-numlock-off.png Binary files differnew file mode 100644 index 0000000..21cac59 --- /dev/null +++ b/plugins/keyboard/kbd-numlock-off.png diff --git a/plugins/keyboard/kbd-numlock-on.png b/plugins/keyboard/kbd-numlock-on.png Binary files differnew file mode 100644 index 0000000..bd9b9fc --- /dev/null +++ b/plugins/keyboard/kbd-numlock-on.png diff --git a/plugins/keyboard/kbd-scrolllock-off.png b/plugins/keyboard/kbd-scrolllock-off.png Binary files differnew file mode 100644 index 0000000..2ff8748 --- /dev/null +++ b/plugins/keyboard/kbd-scrolllock-off.png diff --git a/plugins/keyboard/kbd-scrolllock-on.png b/plugins/keyboard/kbd-scrolllock-on.png Binary files differnew file mode 100644 index 0000000..77a4794 --- /dev/null +++ b/plugins/keyboard/kbd-scrolllock-on.png diff --git a/plugins/keyboard/keyboard.mate-settings-plugin.in b/plugins/keyboard/keyboard.mate-settings-plugin.in new file mode 100644 index 0000000..2ced59c --- /dev/null +++ b/plugins/keyboard/keyboard.mate-settings-plugin.in @@ -0,0 +1,8 @@ +[MATE Settings Plugin] +Module=keyboard +IAge=0 +_Name=Keyboard +_Description=Keyboard plugin +Authors= +Copyright=Copyright © 2007 +Website= diff --git a/plugins/keyboard/modmap-dialog.ui b/plugins/keyboard/modmap-dialog.ui new file mode 100644 index 0000000..12c34a6 --- /dev/null +++ b/plugins/keyboard/modmap-dialog.ui @@ -0,0 +1,273 @@ +<?xml version="1.0"?> +<interface> + <!-- interface-requires gtk+ 2.6 --> + <!-- interface-naming-policy toplevel-contextual --> + <object class="GtkDialog" id="dialog1"> + <property name="visible">True</property> + <property name="title" translatable="yes">Load modmap files</property> + <property name="type_hint">dialog</property> + <child internal-child="vbox"> + <object class="GtkVBox" id="dialog-vbox4"> + <property name="visible">True</property> + <child> + <object class="GtkVBox" id="vbox44"> + <property name="visible">True</property> + <child> + <object class="GtkLabel" id="label62"> + <property name="visible">True</property> + <property name="label" translatable="yes">Would you like to load the modmap files?</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkHBox" id="hbox32"> + <property name="visible">True</property> + <property name="border_width">12</property> + <property name="spacing">6</property> + <child> + <object class="GtkVBox" id="vbox45"> + <property name="visible">True</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="label63"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Loaded files:</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow7"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">automatic</property> + <property name="vscrollbar_policy">automatic</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkTreeView" id="treeview1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="headers_visible">False</property> + </object> + </child> + </object> + <packing> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkVBox" id="vbox46"> + <property name="visible">True</property> + <property name="border_width">6</property> + <property name="spacing">12</property> + <child> + <object class="GtkLabel" id="label64"> + <property name="visible">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="button7"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <child> + <object class="GtkAlignment" id="alignment1"> + <property name="visible">True</property> + <property name="xscale">0</property> + <property name="yscale">0</property> + <child> + <object class="GtkHBox" id="hbox33"> + <property name="visible">True</property> + <property name="spacing">2</property> + <child> + <object class="GtkImage" id="image1"> + <property name="visible">True</property> + <property name="stock">gtk-add</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label66"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Load</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkButton" id="button6"> + <property name="label">gtk-remove</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> + </packing> + </child> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkVBox" id="vbox47"> + <property name="visible">True</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="label65"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">A_vailable files:</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow8"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">automatic</property> + <property name="vscrollbar_policy">automatic</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkTreeView" id="treeview2"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="headers_visible">False</property> + </object> + </child> + </object> + <packing> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="position">2</property> + </packing> + </child> + </object> + <packing> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="checkbutton1"> + <property name="label" translatable="yes">_Do not show this message again</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_underline">True</property> + <property name="active">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> + </packing> + </child> + </object> + <packing> + <property name="position">2</property> + </packing> + </child> + <child internal-child="action_area"> + <object class="GtkHButtonBox" id="dialog-action_area3"> + <property name="visible">True</property> + <property name="layout_style">end</property> + <child> + <object class="GtkButton" id="helpbutton2"> + <property name="label">gtk-help</property> + <property name="can_focus">True</property> + <property name="can_default">True</property> + <property name="receives_default">False</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="okbutton1"> + <property name="label">gtk-ok</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="can_default">True</property> + <property name="receives_default">False</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="pack_type">end</property> + <property name="position">0</property> + </packing> + </child> + </object> + </child> + <action-widgets> + <action-widget response="-11">helpbutton2</action-widget> + <action-widget response="-5">okbutton1</action-widget> + </action-widgets> + </object> +</interface> 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 <[email protected]> + * + * 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 @@ +<?xml version="1.0"?> +<interface> + <!-- interface-requires gtk+ 2.6 --> + <!-- interface-naming-policy toplevel-contextual --> + <object class="GtkWindow" id="dialog"> + <child> + <object class="GtkVBox" id="acme_box"> + <property name="visible">True</property> + <property name="spacing">6</property> + <child> + <object class="GtkImage" id="acme_image"> + <property name="visible">True</property> + <property name="icon_name">audio-volume-high</property> + <property name="icon-size">6</property> + </object> + <packing> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkProgressBar" id="acme_volume_progressbar"> + <property name="visible">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> +</interface> 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 <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +#include <glib.h> +#include <glib/gi18n.h> + +#include <pulse/pulseaudio.h> + +#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 <glib-object.h> +#include <pulse/pulseaudio.h> + +#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 <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +#include <glib.h> +#include <glib/gi18n.h> + +#include <pulse/pulseaudio.h> + +#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 <glib-object.h> +#include <pulse/pulseaudio.h> + +#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 <[email protected]> + * 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 <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +#include <glib.h> +#include <glib/gi18n.h> + +#include <pulse/pulseaudio.h> +#include <pulse/glib-mainloop.h> +#include <pulse/ext-stream-restore.h> + +#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 <glib-object.h> +#include <pulse/pulseaudio.h> +#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 <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +#include <glib.h> +#include <glib/gi18n.h> + +#include <pulse/pulseaudio.h> +#include <pulse/ext-stream-restore.h> + +#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 <glib-object.h> +#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 <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +#include <glib.h> +#include <glib/gi18n.h> + +#include <pulse/pulseaudio.h> + +#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 <glib-object.h> +#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 <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +#include <glib.h> +#include <glib/gi18n.h> + +#include <pulse/pulseaudio.h> + +#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 <glib-object.h> +#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 <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +#include <glib.h> +#include <glib/gi18n.h> + +#include <pulse/pulseaudio.h> + +#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 <glib-object.h> +#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 <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +#include <glib.h> +#include <glib/gi18n.h> + +#include <pulse/pulseaudio.h> + +#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 <glib-object.h> +#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 <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +#include <glib.h> +#include <glib/gi18n.h> + +#include <pulse/pulseaudio.h> + +#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 <glib-object.h> +#include <pulse/pulseaudio.h> + +#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 <[email protected]> + * Copyright (C) 2006-2007 William Jon McCann <[email protected]> + * + * 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 <sys/types.h> +#include <sys/wait.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> + +#include <locale.h> + +#include <glib.h> +#include <glib/gi18n.h> +#include <gdk/gdk.h> +#include <gdk/gdkx.h> +#include <gtk/gtk.h> +#include <mateconf/mateconf-client.h> + +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> + +#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 <canberra-gtk.h> +#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 <[email protected]> + * + * 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 <glib-object.h> + +#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 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node> + <interface name="org.mate.SettingsDaemon.MediaKeys"> + <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="gsd_media_keys_manager"/> + <method name="GrabMediaPlayerKeys"> + <arg name="application" direction="in" type="s"/> + <arg name="time" direction="in" type="u"/> + </method> + <method name="ReleaseMediaPlayerKeys"> + <arg name="application" direction="in" type="s"/> + </method> + <signal name="MediaPlayerKeyPressed"/> + </interface> +</node> 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 <[email protected]> + * + * 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 <glib/gi18n-lib.h> +#include <gmodule.h> + +#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 <[email protected]> + * + * 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 <glib.h> +#include <glib-object.h> +#include <gmodule.h> + +#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 <[email protected]> + * + * + * 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 <stdlib.h> +#include <string.h> +#include <math.h> +#include <glib.h> +#include <glib/gi18n.h> +#include <gtk/gtk.h> + +#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 <[email protected]> + * + * 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 <glib-object.h> +#include <gtk/gtk.h> + +#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 <[email protected]> + * + * 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 <stdlib.h> + +#include <glib/gi18n.h> +#include <gtk/gtk.h> + +#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 <[email protected]> + * + * 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 <stdlib.h> + +#include <glib/gi18n.h> +#include <gtk/gtk.h> + +#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 Binary files differnew file mode 100644 index 0000000..c8355de --- /dev/null +++ b/plugins/media-keys/touchpad-disabled-16.png diff --git a/plugins/media-keys/touchpad-disabled-22.png b/plugins/media-keys/touchpad-disabled-22.png Binary files differnew file mode 100644 index 0000000..706fbc7 --- /dev/null +++ b/plugins/media-keys/touchpad-disabled-22.png diff --git a/plugins/media-keys/touchpad-disabled-24.png b/plugins/media-keys/touchpad-disabled-24.png Binary files differnew file mode 100644 index 0000000..fc0bac7 --- /dev/null +++ b/plugins/media-keys/touchpad-disabled-24.png diff --git a/plugins/media-keys/touchpad-disabled-32.png b/plugins/media-keys/touchpad-disabled-32.png Binary files differnew file mode 100644 index 0000000..1311c60 --- /dev/null +++ b/plugins/media-keys/touchpad-disabled-32.png diff --git a/plugins/media-keys/touchpad-disabled-48.png b/plugins/media-keys/touchpad-disabled-48.png Binary files differnew file mode 100644 index 0000000..8f6ee03 --- /dev/null +++ b/plugins/media-keys/touchpad-disabled-48.png 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 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + height="300" + id="svg11300" + inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png" + inkscape:export-xdpi="90.000000" + inkscape:export-ydpi="90.000000" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + inkscape:version="0.46+devel" + sodipodi:docname="hicolor_status_scalable_touchpad-disabled.svg" + sodipodi:version="0.32" + style="display:inline;enable-background:new" + version="1.0" + width="400"> + <title + id="title3835">Touchpad</title> + <metadata + id="metadata154"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title>Touchpad</dc:title> + <dc:creator> + <cc:Agent> + <dc:title>Lapo Calamandrei</dc:title> + </cc:Agent> + </dc:creator> + <dc:contributor> + <cc:Agent> + <dc:title /> + </cc:Agent> + </dc:contributor> + <dc:source /> + <cc:license + rdf:resource="" /> + <dc:subject> + <rdf:Bag /> + </dc:subject> + </cc:Work> + </rdf:RDF> + </metadata> + <sodipodi:namedview + bordercolor="#666666" + borderopacity="0.25490196" + fill="#f57900" + gridtolerance="12" + guidetolerance="13" + height="300px" + id="base" + inkscape:current-layer="layer2" + inkscape:cx="433.90068" + inkscape:cy="165.06237" + inkscape:document-units="px" + inkscape:grid-bbox="true" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:showpageshadow="false" + inkscape:snap-bbox="true" + inkscape:snap-nodes="true" + inkscape:window-height="1177" + inkscape:window-width="1920" + inkscape:window-x="1440" + inkscape:window-y="0" + inkscape:zoom="1.4142136" + objecttolerance="7" + pagecolor="#ffffff" + showgrid="false" + stroke="#ef2929" + width="400px" + showguides="true" + inkscape:guide-bbox="true" + showborder="true" + inkscape:window-maximized="1"> + <inkscape:grid + enabled="true" + id="grid5883" + spacingx="0.5px" + spacingy="0.5px" + type="xygrid" + visible="true" + empspacing="2" + snapvisiblegridlinesonly="true" /> + <sodipodi:guide + orientation="1,0" + position="313.98438,106.53125" + id="guide4872" /> + <sodipodi:guide + orientation="0,1" + position="312.32813,105.01563" + id="guide4874" /> + <sodipodi:guide + orientation="0,1" + position="312.90625,147" + id="guide4876" /> + <sodipodi:guide + orientation="1,0" + position="313,161.6875" + id="guide4878" /> + <sodipodi:guide + orientation="0,1" + position="341.64306,213.01592" + id="guide4880" /> + </sodipodi:namedview> + <defs + id="defs3"> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 150 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="400 : 150 : 1" + inkscape:persp3d-origin="200 : 100 : 1" + id="perspective147" /> + <linearGradient + inkscape:collect="always" + id="linearGradient2972"> + <stop + style="stop-color:#babdb6;stop-opacity:1" + offset="0" + id="stop2974" /> + <stop + style="stop-color:#555753;stop-opacity:1" + offset="1" + id="stop2976" /> + </linearGradient> + <linearGradient + id="linearGradient3100"> + <stop + id="stop3102" + offset="0" + style="stop-color:#babdb6;stop-opacity:1" /> + <stop + style="stop-color:#eeeeec;stop-opacity:1" + offset="0.25" + id="stop3104" /> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="0.5" + id="stop3106" /> + <stop + id="stop3108" + offset="0.75" + style="stop-color:#ffffff;stop-opacity:1" /> + <stop + id="stop3110" + offset="1" + style="stop-color:#babdb6;stop-opacity:1" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient3743"> + <stop + style="stop-color:#000000;stop-opacity:0.2" + offset="0" + id="stop3745" /> + <stop + style="stop-color:#ffffff;stop-opacity:1" + offset="1" + id="stop3747" /> + </linearGradient> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3760-7" + id="radialGradient3766-2" + cx="311" + cy="225.23932" + fx="311" + fy="225.23932" + r="8" + gradientTransform="matrix(1.4590081,0,0,1.0942561,-142.75153,-21.969492)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + id="linearGradient3760-7"> + <stop + style="stop-color:#eeeeec;stop-opacity:1" + offset="0" + id="stop3762-0" /> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="1" + id="stop3764-5" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient3752-2"> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="0" + id="stop3754-2" /> + <stop + style="stop-color:#babdb6;stop-opacity:1" + offset="1" + id="stop3756-8" /> + </linearGradient> + <linearGradient + y2="238.1875" + x2="324.875" + y1="231.5" + x1="304.8125" + gradientUnits="userSpaceOnUse" + id="linearGradient3794" + xlink:href="#linearGradient3752-2" + inkscape:collect="always" + gradientTransform="translate(0,-1)" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3760-7-6" + id="radialGradient3766-2-5" + cx="312.09396" + cy="224.27068" + fx="312.09396" + fy="224.27068" + r="8" + gradientTransform="matrix(2.0157047,0,0,1.5117786,-315.08929,-153.04762)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + id="linearGradient3760-7-6"> + <stop + style="stop-color:#eeeeec;stop-opacity:1" + offset="0" + id="stop3762-0-6" /> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="1" + id="stop3764-5-1" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient3752-2-3"> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="0" + id="stop3754-2-2" /> + <stop + style="stop-color:#babdb6;stop-opacity:1" + offset="1" + id="stop3756-8-6" /> + </linearGradient> + <linearGradient + y2="238.1875" + x2="324.875" + y1="231.5" + x1="304.8125" + gradientUnits="userSpaceOnUse" + id="linearGradient2894" + xlink:href="#linearGradient3752-2-3" + inkscape:collect="always" + gradientTransform="translate(1,-38)" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3743" + id="linearGradient3749" + x1="304" + y1="177" + x2="304" + y2="195" + gradientUnits="userSpaceOnUse" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3760-7-6-4" + id="radialGradient3766-2-5-1" + cx="312.09396" + cy="224.27068" + fx="312.09396" + fy="224.27068" + r="8" + gradientTransform="matrix(3.7131449,0,0,3.563472,-838.85008,-725.00376)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + id="linearGradient3760-7-6-4"> + <stop + style="stop-color:#eeeeec;stop-opacity:1" + offset="0" + id="stop3762-0-6-6" /> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="1" + id="stop3764-5-1-4" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient3743-4"> + <stop + style="stop-color:#000000;stop-opacity:0.2" + offset="0" + id="stop3745-6" /> + <stop + style="stop-color:#ffffff;stop-opacity:1" + offset="1" + id="stop3747-2" /> + </linearGradient> + <linearGradient + y2="195" + x2="304" + y1="177" + x1="304" + gradientUnits="userSpaceOnUse" + id="linearGradient2910" + xlink:href="#linearGradient3743-4" + inkscape:collect="always" + gradientTransform="matrix(1.9473685,0,0,1.9444446,-291.47369,-291.58337)" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3100" + id="linearGradient3092" + x1="302" + y1="82.375" + x2="338" + y2="92.75" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3100-5" + id="linearGradient3092-9" + x1="305.89941" + y1="83.784264" + x2="334.10059" + y2="91.340736" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-2,66)" /> + <linearGradient + id="linearGradient3100-5"> + <stop + id="stop3102-6" + offset="0" + style="stop-color:#babdb6;stop-opacity:1" /> + <stop + style="stop-color:#eeeeec;stop-opacity:1" + offset="0.25" + id="stop3104-13" /> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="0.5" + id="stop3106-5" /> + <stop + id="stop3108-50" + offset="0.75" + style="stop-color:#ffffff;stop-opacity:1" /> + <stop + id="stop3110-4" + offset="1" + style="stop-color:#babdb6;stop-opacity:1" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient3743-4-4"> + <stop + style="stop-color:#000000;stop-opacity:0.2" + offset="0" + id="stop3745-6-8" /> + <stop + style="stop-color:#ffffff;stop-opacity:1" + offset="1" + id="stop3747-2-3" /> + </linearGradient> + <linearGradient + y2="195" + x2="304" + y1="180.95102" + x1="304" + gradientTransform="matrix(1.8448754,0,0,1.8333335,-257.26455,-204.75003)" + gradientUnits="userSpaceOnUse" + id="linearGradient4350" + xlink:href="#linearGradient3743-4-4" + inkscape:collect="always" /> + <linearGradient + inkscape:collect="always" + id="linearGradient3760-7-6-4-66-6"> + <stop + style="stop-color:#eeeeec;stop-opacity:1" + offset="0" + id="stop3762-0-6-6-61-7" /> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="1" + id="stop3764-5-1-4-0-6" /> + </linearGradient> + <radialGradient + r="8" + fy="222.91086" + fx="312.22864" + cy="222.91086" + cx="312.22864" + gradientTransform="matrix(2.8880002,0,0,2.9155676,-583.21633,-511.91208)" + gradientUnits="userSpaceOnUse" + id="radialGradient4444" + xlink:href="#linearGradient3760-7-6-4-66-6" + inkscape:collect="always" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2972" + id="linearGradient2978" + x1="315.81155" + y1="82.20932" + x2="315.81155" + y2="89.25135" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2972" + id="linearGradient3756" + x1="318.5" + y1="147.03621" + x2="318.5" + y2="155.96379" + gradientUnits="userSpaceOnUse" /> + <inkscape:perspective + id="perspective3111" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + id="perspective3912" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + id="perspective4331" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + id="perspective4799" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + </defs> + <g + id="layer1" + inkscape:groupmode="layer" + inkscape:label="artwork" + style="display:inline"> + <g + inkscape:groupmode="layer" + id="layer5" + inkscape:label="disabled" + style="display:none" + sodipodi:insensitive="true"> + <rect + height="256" + id="rect6282" + inkscape:label="256x256" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="256" + x="16" + y="28" /> + </g> + <g + id="layer6" + inkscape:groupmode="layer" + inkscape:label="baseplate" + style="display:none"> + <rect + height="48" + id="rect6284" + inkscape:label="48x48" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="48" + x="296" + y="50" /> + <rect + height="32" + id="rect6592" + inkscape:label="32x32" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="32" + x="303" + y="126" /> + <rect + height="22" + id="rect6749" + inkscape:label="22x22" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="22" + x="303" + y="177" /> + <rect + height="16" + id="rect6833" + inkscape:label="16x16" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="16" + x="303" + y="219" /> + <rect + height="24" + id="rect8104" + inkscape:label="24x24" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="24" + x="302" + y="176" /> + <text + id="context" + inkscape:label="context" + style="font-size:18.30070686px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:Bitstream Vera Sans" + x="20.970737" + xml:space="preserve" + y="21.513618"><tspan + id="tspan2716" + sodipodi:role="line" + x="20.970737" + y="21.513618">devices</tspan></text> + <text + id="icon-name" + inkscape:label="icon-name" + sodipodi:linespacing="125%" + style="font-size:18.30070686px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:Droid Sans;-inkscape-font-specification:Droid Sans Bold" + x="141.97073" + xml:space="preserve" + y="21.513618"><tspan + id="tspan3023" + sodipodi:role="line" + x="141.97073" + y="21.513618">input-touchpad</tspan></text> + </g> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="small sizes" + style="display:inline"> + <path + style="color:#000000;fill:url(#linearGradient3794);fill-opacity:1;fill-rule:nonzero;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="m 303.5,227.5 0,4 c 0,1.108 0.892,2 2,2 l 11,0 c 1.108,0 2,-0.892 2,-2 l 0,-4 c 0,1.108 -0.892,2 -2,2 l -11,0 c -1.108,0 -2,-0.892 -2,-2 z" + id="rect2846-2-3" + sodipodi:nodetypes="ccccccccc" /> + <rect + style="color:#000000;fill:url(#radialGradient3766-2);fill-opacity:1;fill-rule:nonzero;stroke:#babdb6;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect2846" + width="15" + height="10" + x="303.5" + y="219.5" + rx="2" + ry="2" /> + <rect + style="opacity:0.3;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3694" + width="13" + height="12" + x="304.5" + y="220.5" + rx="1" + ry="1" /> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeec;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" + d="m 304,229.5 0,1 c 0,0.0541 0.002,0.1029 0,0.15625 0.45244,0.21377 0.96717,0.34375 1.5,0.34375 l 11,0 c 0.53283,0 1.04756,-0.12998 1.5,-0.34375 L 318,229.5 c -0.41577,0.30853 -0.93558,0.5 -1.5,0.5 l -11,0 c -0.56442,0 -1.08423,-0.19147 -1.5,-0.5 z" + id="rect2846-2" + sodipodi:nodetypes="cccccccccc" /> + <rect + style="color:#000000;fill:#d3d7cf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3728" + width="1" + height="3" + x="310" + y="230" + rx="0" + ry="0" /> + <rect + style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3728-4" + width="1" + height="3" + x="311" + y="230" + rx="0" + ry="0" /> + <rect + style="opacity:0.3;color:#000000;fill:none;stroke:url(#linearGradient3749);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect2846-28-6" + width="19" + height="18" + x="304.5" + y="178.5" + rx="2" + ry="2" /> + <path + style="color:#000000;fill:url(#linearGradient2894);fill-opacity:1;fill-rule:nonzero;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="m 304.5,190.5 0,4 c 0,1.108 0.892,2 2,2 l 15,0 c 1.108,0 2,-0.892 2,-2 l 0,-4 c 0,1.108 -0.892,2 -2,2 l -15,0 c -1.108,0 -2,-0.892 -2,-2 z" + id="rect2846-2-3-0" + sodipodi:nodetypes="ccccccccc" /> + <rect + style="color:#000000;fill:url(#radialGradient3766-2-5);fill-opacity:1;fill-rule:nonzero;stroke:#babdb6;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect2846-28" + width="18.999943" + height="14.000024" + x="304.5" + y="178.5" + rx="2" + ry="2" /> + <rect + style="opacity:0.3;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3694-0" + width="17.000095" + height="16.000011" + x="305.5" + y="179.5" + rx="1" + ry="1" /> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeec;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" + d="m 305,192.5 0,1 c 0,0.0541 0.002,0.1029 0,0.15625 0.45244,0.21377 0.96717,0.34375 1.5,0.34375 l 15,0 c 0.53283,0 1.04756,-0.12998 1.5,-0.34375 L 323,192.5 c -0.41577,0.30853 -0.93558,0.5 -1.5,0.5 l -15,0 c -0.56442,0 -1.08423,-0.19147 -1.5,-0.5 z" + id="rect2846-2-1" + sodipodi:nodetypes="cccccccccc" /> + <rect + style="color:#000000;fill:#d3d7cf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3728-5" + width="1" + height="3" + x="313" + y="193" + rx="0" + ry="0" /> + <rect + style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3728-4-5" + width="1" + height="3" + x="314" + y="193" + rx="0" + ry="0" /> + <rect + style="opacity:0.3;color:#000000;fill:none;stroke:url(#linearGradient2910);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect2846-28-6-4" + width="38" + height="35" + x="301.5" + y="55.5" + rx="4" + ry="4" /> + <rect + style="color:#000000;fill:url(#radialGradient3766-2-5-1);fill-opacity:1;fill-rule:nonzero;stroke:#babdb6;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect2846-28-66" + width="35.999939" + height="33.000004" + x="302.50006" + y="56.499996" + rx="3.0000038" + ry="3.0000038" /> + <rect + ry="2" + rx="2" + y="57.5" + x="303.5" + height="25" + width="34" + id="rect3694-0-0" + style="opacity:0.3;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + <g + id="g4205"> + <path + id="rect3694-0-0-9" + d="m 303,84.5 0,2 c 0,1.367703 1.1323,2.5 2.5,2.5 l 14.5,0 0,-2 -14.5,0 c -0.0657,0 -0.1232,-0.02642 -0.1875,-0.03125 C 304.01204,86.871142 303,85.827989 303,84.5 z" + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.1;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" /> + <path + id="rect3694-0-0-9-8" + d="m 338,84.5 0,2 c 0,1.367703 -1.1323,2.5 -2.5,2.5 l -14.5,0 0,-2 14.5,0 c 0.0657,0 0.1232,-0.02642 0.1875,-0.03125 C 336.98796,86.871142 338,85.827989 338,84.5 z" + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.1;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" /> + </g> + <g + id="g2958" + style="fill-opacity:1;stroke:url(#linearGradient2978)"> + <path + sodipodi:nodetypes="ccccccccc" + id="rect2846-28-66-1" + d="m 302.5,80.5 0,6 c 0,1.662002 1.338,3 3,3 l 30,0 c 1.662,0 3,-1.337998 3,-3 l 0,-6 c 0,1.662002 -1.338,3 -3,3 l -30,0 c -1.662,0 -3,-1.337998 -3,-3 z" + style="color:#000000;fill:url(#linearGradient3092);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient2978);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + <path + id="path3112" + d="m 320.5,83.5 0,6" + style="fill:none;stroke:url(#linearGradient2978);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" /> + </g> + <path + style="opacity:0.5;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="m 303.5,83.875 0,2.625 c 0,1.12494 0.87506,2 2,2 l 14,0 0,-4 -14,0 c -0.74347,0 -1.40165,-0.267405 -2,-0.625 z" + id="path3161-2" + sodipodi:nodetypes="ccccccc" /> + <path + style="opacity:0.5;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="m 337.5,83.875 0,2.625 c 0,1.12494 -0.87506,2 -2,2 l -14,0 0,-4 14,0 c 0.74347,0 1.40165,-0.267405 2,-0.625 z" + id="path3161-2-0" + sodipodi:nodetypes="ccccccc" /> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.4;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" + d="m 303,82.65625 0,1.3125 C 303.8401,84.608417 304.86264,85 306,85 l 14,0 0,-1 -14,0 c -1.20201,0 -2.2695,-0.516326 -3,-1.34375 z" + id="rect2846-28-66-0" /> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.4;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" + d="m 338,82.65625 0,1.3125 C 337.1599,84.608417 336.13736,85 335,85 l -14,0 0,-1 14,0 c 1.20201,0 2.2695,-0.516326 3,-1.34375 z" + id="rect2846-28-66-0-6" /> + <path + style="opacity:0.1;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" + d="m 309.49911,81.5 22.00265,0" + id="path4233" /> + <path + style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" + d="m 336.5,76.504425 0,-13.00885" + id="path4235" /> + <rect + style="opacity:1;color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237" + width="0.99953973" + height="0.99999803" + x="307.00046" + y="81" /> + <rect + style="opacity:1;color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237-6" + width="0.99953973" + height="0.99999803" + x="333.00046" + y="81" /> + <rect + style="opacity:1;color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237-6-8" + width="0.99953973" + height="0.99999803" + x="336.00046" + y="78" /> + <rect + style="opacity:1;color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237-6-8-5" + width="0.99953973" + height="0.99999803" + x="336.00046" + y="61" /> + <rect + style="opacity:0.3;color:#000000;fill:none;stroke:url(#linearGradient4350);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect2846-28-6-4-0" + width="28" + height="27" + x="304.5" + y="128.5" + rx="3" + ry="3" /> + <rect + style="color:#000000;fill:url(#radialGradient4444);fill-opacity:1;fill-rule:nonzero;stroke:#babdb6;stroke-width:0.99999994000000003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect2846-28-66-3-9" + width="28" + height="26" + x="304.5" + y="128.5" + rx="3" + ry="3" /> + <rect + ry="2" + rx="2" + y="129.5" + x="305.5" + height="20" + width="26" + id="rect3694-0-0-2" + style="opacity:0.3;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + <g + id="g3752" + style="stroke:url(#linearGradient3756)"> + <path + sodipodi:nodetypes="ccccccccc" + id="rect2846-28-66-1-2" + d="m 304.5,147.5 0,5 c 0,1.662 1.338,3 3,3 l 22,0 c 1.662,0 3,-1.338 3,-3 l 0,-5 c 0,1.662 -1.338,3 -3,3 l -22,0 c -1.662,0 -3,-1.338 -3,-3 z" + style="color:#000000;fill:url(#linearGradient3092-9);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient3756);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + <path + sodipodi:nodetypes="cc" + id="path3112-3" + d="m 318.5,150.5 0,5" + style="fill:none;stroke:url(#linearGradient3756);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> + </g> + <g + style="display:inline;enable-background:new" + id="g4205-5" + transform="translate(-2,66)"> + <path + id="rect3694-0-0-9-83" + d="m 307,84.5 0,2 c 0,1.367703 1.1323,2.5 2.5,2.5 l 10.5,0 0,-2 -10.5,0 c -0.0657,0 -0.1232,-0.02642 -0.1875,-0.03125 C 308.01204,86.871142 307,85.827989 307,84.5 z" + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.1;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" + sodipodi:nodetypes="ccccccsc" /> + <path + id="rect3694-0-0-9-8-9" + d="m 334,84.5 0,2 c 0,1.367703 -1.1323,2.5 -2.5,2.5 l -10.5,0 0,-2 10.5,0 c 0.0657,0 0.1232,-0.02642 0.1875,-0.03125 C 332.98796,86.871142 334,85.827989 334,84.5 z" + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.1;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" + sodipodi:nodetypes="ccccccsc" /> + </g> + <path + style="opacity:0.6;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="m 305.5,150.875 0,1.625 c 0,1.12494 0.87506,2 2,2 l 10,0 0,-3 -10,0 c -0.74347,0 -1.40165,-0.2674 -2,-0.625 z" + id="path3161-2-4" + sodipodi:nodetypes="ccccccc" /> + <path + style="opacity:0.6;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="m 331.5,150.875 0,1.625 c 0,1.12494 -0.87506,2 -2,2 l -10,0 0,-3 10,0 c 0.74347,0 1.40165,-0.2674 2,-0.625 z" + id="path3161-2-0-7" + sodipodi:nodetypes="ccccccc" /> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.4;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" + d="m 305,149.65625 0,1.3125 c 0.8401,0.63967 1.86264,1.03125 3,1.03125 l 10,0 0,-1 -10,0 c -1.20201,0 -2.2695,-0.51633 -3,-1.34375 z" + id="rect2846-28-66-0-7" + sodipodi:nodetypes="ccccccc" /> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.4;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" + d="m 332,149.65625 0,1.3125 C 331.1599,151.60842 330.13736,152 329,152 l -10,0 0,-1 10,0 c 1.20201,0 2.2695,-0.51633 3,-1.34375 z" + id="rect2846-28-66-0-6-4" + sodipodi:nodetypes="ccccccc" /> + <path + style="opacity:0.1;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" + d="m 310.49911,148.5 15.00265,0" + id="path4233-4" + sodipodi:nodetypes="cc" /> + <path + style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" + d="m 330.5,143.50442 0,-9.00884" + id="path4235-3" + sodipodi:nodetypes="cc" /> + <rect + style="opacity:1;color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237-5" + width="0.99953973" + height="0.99999803" + x="308.00046" + y="148" /> + <rect + style="opacity:1;color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237-6-80" + width="0.99953973" + height="0.99999803" + x="327.00046" + y="148" /> + <rect + style="opacity:1;color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237-6-8-3" + width="0.99953973" + height="0.99999803" + x="330.00046" + y="145" /> + <rect + style="opacity:1;color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237-6-8-5-0" + width="0.99953973" + height="0.99999803" + x="330.00046" + y="132" /> + <g + id="g6998" + transform="translate(297.68228,160.06933)"> + <rect + style="fill:#ef2929;fill-opacity:1;stroke:#a40000;stroke-width:1.00000012;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" + id="rect5861" + width="7.9959006" + height="7.9958639" + x="12.802565" + y="26.419176" + rx="1.5753298" + ry="1.5876297" /> + <g + id="g6991"> + <rect + y="27.918909" + x="14.302099" + height="2" + width="2" + id="rect6981" + style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" /> + <rect + y="30.918909" + x="14.302099" + height="2" + width="2" + id="rect6983" + style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" /> + <rect + y="28.918909" + x="15.302099" + height="3.0000005" + width="2.9999998" + id="rect6985" + style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" /> + <rect + y="30.918909" + x="17.302099" + height="2" + width="2" + id="rect6987" + style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" /> + <rect + y="27.918909" + x="17.302099" + height="2" + width="2" + id="rect6989" + style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" /> + </g> + </g> + <g + id="g7188" + transform="translate(300.694,231.07228)"> + <rect + ry="1.1537831" + rx="1.0881115" + y="-6.0811005" + x="7.3020992" + height="7" + width="7" + id="rect7176" + style="fill:#ef2929;fill-opacity:1;fill-rule:evenodd;stroke:none" /> + <rect + ry="0" + rx="0" + y="-5.0811005" + x="8.3020992" + height="2" + width="2" + id="rect7178" + style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" /> + <rect + ry="0" + rx="0" + y="-5.0811005" + x="11.302099" + height="2" + width="2" + id="rect7180" + style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" /> + <rect + ry="0" + rx="0" + y="-2.0811005" + x="11.302099" + height="2" + width="2" + id="rect7182" + style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" /> + <rect + ry="0" + rx="0" + y="-2.0811005" + x="8.3020992" + height="2" + width="2" + id="rect7184" + style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" /> + <rect + ry="0" + rx="0" + y="-4.0811005" + x="9.3020992" + height="3.0000005" + width="3.0000002" + id="rect7186" + style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none" /> + </g> + <g + transform="matrix(0.9980467,0,0,0.9980473,271.08457,122.06151)" + id="g7081"> + <rect + style="fill:#ef2929;fill-opacity:0.98473283;fill-rule:evenodd;stroke:#a40000;stroke-width:1.0019567;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:10.43299961;stroke-opacity:1;stroke-dasharray:none" + id="rect7069" + width="10.000005" + height="10" + x="42.5" + y="21.5" + rx="1.7585585" + ry="1.7585585" /> + <g + id="g7075" + transform="matrix(0.7692308,0,0,0.7692308,2.5,6.1153846)"> + <path + id="path7071" + d="m 56,24 5,5" + style="fill:none;stroke:#ffffff;stroke-width:1.69330692;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <path + id="path7073" + d="m 56,29 5,-5" + style="fill:none;stroke:#ffffff;stroke-width:1.69330692;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + </g> + <rect + style="opacity:0.3;fill:none;stroke:#ffffff;stroke-width:1.00195682;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:10.43299961;stroke-opacity:1;stroke-dasharray:none" + id="rect7079" + width="8.0156603" + height="8.0156527" + x="43.492176" + y="22.492174" + rx="0.78614295" + ry="0.78614295" /> + </g> + <g + id="layer4-3" + inkscape:label="Muted" + style="display:inline" + transform="translate(284.98438,57.984079)"> + <g + id="g4694" + transform="translate(-2,0)"> + <rect + ry="1.4868355" + rx="1.4868355" + y="16.498245" + x="31.498245" + height="12.00351" + width="12.00351" + id="rect2021" + style="fill:#ef2929;fill-opacity:1;stroke:#cc0000;stroke-width:0.9964897;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:1.20000057;display:inline" /> + <rect + ry="0.4861359" + rx="0.4861359" + y="17.500002" + x="32.5" + height="9.9999962" + width="9.9999962" + id="rect3795" + style="opacity:0.3;fill:none;stroke:#ffffff;stroke-width:0.99999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:1.20000057;display:inline" /> + <path + sodipodi:nodetypes="cc" + id="path4682" + d="m 35,20 5,5" + style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <path + sodipodi:nodetypes="cc" + id="path4684" + d="m 40,20 -5,5" + style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline" /> + </g> + </g> + </g> + <g + inkscape:groupmode="layer" + id="layer4" + inkscape:label="hires" + style="display:inline" /> + <g + id="g256" + style="display:inline;enable-background:new" + transform="translate(20,30)" /> + <g + id="g4021" + style="display:inline;enable-background:new" + transform="translate(-577.97771,370.7754)" /> + <g + transform="translate(-457.73144,-1.374928)" + id="g10306" + style="enable-background:new"> + <g + id="layer3" + inkscape:label="plate" + style="display:none"> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect6282-8" + width="256" + height="256" + x="20" + y="20" + inkscape:label="256x256" /> + <rect + inkscape:label="48x48" + y="39.99633" + x="296.0625" + height="48" + width="48" + id="rect6284-8" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect6592-5" + width="32" + height="32" + x="303" + y="115.99633" + inkscape:label="32x32" /> + <rect + inkscape:label="22x22" + y="167.05884" + x="303" + height="22" + width="22" + id="rect6749-0" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect6833-9" + width="16" + height="16" + x="303" + y="209" + inkscape:label="16x16" /> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect5028" + width="24" + height="24" + x="301.95709" + y="165.95343" + inkscape:label="24x24" /> + </g> + <g + id="layer1-6" + inkscape:label="artwork" + style="display:inline"> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:none;overflow:visible;enable-background:accumulate" + id="256x256" + width="256" + height="256" + x="23.5" + y="171.59863" + inkscape:label="256x256" /> + <rect + y="171.59863" + x="-38.5" + height="48" + width="48" + id="48x48" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:none;overflow:visible;enable-background:accumulate" + inkscape:label="48x48" /> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:none;overflow:visible;enable-background:accumulate" + id="24x24" + width="24" + height="24" + x="-123.5" + y="171.59863" + inkscape:label="24x24" /> + <rect + y="171.59863" + x="-155.5" + height="16" + width="16" + id="16x16" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:none;overflow:visible;enable-background:accumulate" + inkscape:label="16x16" /> + <rect + inkscape:label="32x32" + y="171.59863" + x="-87.5" + height="32" + width="32" + id="32x32" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:none;overflow:visible;enable-background:accumulate" /> + </g> + </g> + <g + id="g4445" + style="display:inline;enable-background:new" + transform="translate(-393,-62.246031)" /> + <g + id="g5542" + style="display:inline;enable-background:new" + transform="translate(-364.39697,166.26869)" /> + </g> +</svg> 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 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + height="38" + id="svg11300" + inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png" + inkscape:export-xdpi="90.000000" + inkscape:export-ydpi="90.000000" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + inkscape:version="0.47 r22583" + sodipodi:docname="touchpad-disabled.svg" + sodipodi:version="0.32" + style="display:inline;enable-background:new" + version="1.0" + width="41"> + <title + id="title3835">Touchpad</title> + <metadata + id="metadata154"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title>Touchpad</dc:title> + <dc:creator> + <cc:Agent> + <dc:title>Lapo Calamandrei</dc:title> + </cc:Agent> + </dc:creator> + <dc:contributor> + <cc:Agent> + <dc:title /> + </cc:Agent> + </dc:contributor> + <dc:source /> + <cc:license + rdf:resource="" /> + <dc:subject> + <rdf:Bag /> + </dc:subject> + </cc:Work> + </rdf:RDF> + </metadata> + <sodipodi:namedview + bordercolor="#666666" + borderopacity="0.25490196" + fill="#f57900" + gridtolerance="12" + guidetolerance="13" + height="300px" + id="base" + inkscape:current-layer="layer2" + inkscape:cx="133.90068" + inkscape:cy="-44.351844" + inkscape:document-units="px" + inkscape:grid-bbox="true" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:showpageshadow="false" + inkscape:snap-bbox="true" + inkscape:snap-nodes="true" + inkscape:window-height="975" + inkscape:window-width="1680" + inkscape:window-x="0" + inkscape:window-y="25" + inkscape:zoom="1.4142136" + objecttolerance="7" + pagecolor="#ffffff" + showgrid="false" + stroke="#ef2929" + width="400px" + showguides="true" + inkscape:guide-bbox="true" + showborder="true" + inkscape:window-maximized="1"> + <inkscape:grid + enabled="true" + id="grid5883" + spacingx="0.5px" + spacingy="0.5px" + type="xygrid" + visible="true" + empspacing="2" + snapvisiblegridlinesonly="true" /> + <sodipodi:guide + orientation="1,0" + position="13.98438,-101.46875" + id="guide4872" /> + <sodipodi:guide + orientation="0,1" + position="12.32813,-102.98437" + id="guide4874" /> + <sodipodi:guide + orientation="0,1" + position="12.90625,-61" + id="guide4876" /> + <sodipodi:guide + orientation="1,0" + position="13,-46.3125" + id="guide4878" /> + <sodipodi:guide + orientation="0,1" + position="41.64306,5.01592" + id="guide4880" /> + </sodipodi:namedview> + <defs + id="defs3"> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 150 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="400 : 150 : 1" + inkscape:persp3d-origin="200 : 100 : 1" + id="perspective147" /> + <linearGradient + inkscape:collect="always" + id="linearGradient2972"> + <stop + style="stop-color:#babdb6;stop-opacity:1" + offset="0" + id="stop2974" /> + <stop + style="stop-color:#555753;stop-opacity:1" + offset="1" + id="stop2976" /> + </linearGradient> + <linearGradient + id="linearGradient3100"> + <stop + id="stop3102" + offset="0" + style="stop-color:#babdb6;stop-opacity:1" /> + <stop + style="stop-color:#eeeeec;stop-opacity:1" + offset="0.25" + id="stop3104" /> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="0.5" + id="stop3106" /> + <stop + id="stop3108" + offset="0.75" + style="stop-color:#ffffff;stop-opacity:1" /> + <stop + id="stop3110" + offset="1" + style="stop-color:#babdb6;stop-opacity:1" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient3743"> + <stop + style="stop-color:#000000;stop-opacity:0.2" + offset="0" + id="stop3745" /> + <stop + style="stop-color:#ffffff;stop-opacity:1" + offset="1" + id="stop3747" /> + </linearGradient> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3760-7" + id="radialGradient3766-2" + cx="311" + cy="225.23932" + fx="311" + fy="225.23932" + r="8" + gradientTransform="matrix(1.4590081,0,0,1.0942561,-142.75153,-21.969492)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + id="linearGradient3760-7"> + <stop + style="stop-color:#eeeeec;stop-opacity:1" + offset="0" + id="stop3762-0" /> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="1" + id="stop3764-5" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient3752-2"> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="0" + id="stop3754-2" /> + <stop + style="stop-color:#babdb6;stop-opacity:1" + offset="1" + id="stop3756-8" /> + </linearGradient> + <linearGradient + y2="238.1875" + x2="324.875" + y1="231.5" + x1="304.8125" + gradientUnits="userSpaceOnUse" + id="linearGradient3794" + xlink:href="#linearGradient3752-2" + inkscape:collect="always" + gradientTransform="translate(0,-1)" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3760-7-6" + id="radialGradient3766-2-5" + cx="312.09396" + cy="224.27068" + fx="312.09396" + fy="224.27068" + r="8" + gradientTransform="matrix(2.0157047,0,0,1.5117786,-315.08929,-153.04762)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + id="linearGradient3760-7-6"> + <stop + style="stop-color:#eeeeec;stop-opacity:1" + offset="0" + id="stop3762-0-6" /> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="1" + id="stop3764-5-1" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient3752-2-3"> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="0" + id="stop3754-2-2" /> + <stop + style="stop-color:#babdb6;stop-opacity:1" + offset="1" + id="stop3756-8-6" /> + </linearGradient> + <linearGradient + y2="238.1875" + x2="324.875" + y1="231.5" + x1="304.8125" + gradientUnits="userSpaceOnUse" + id="linearGradient2894" + xlink:href="#linearGradient3752-2-3" + inkscape:collect="always" + gradientTransform="translate(1,-38)" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3743" + id="linearGradient3749" + x1="304" + y1="177" + x2="304" + y2="195" + gradientUnits="userSpaceOnUse" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3760-7-6-4" + id="radialGradient3766-2-5-1" + cx="312.09396" + cy="224.27068" + fx="312.09396" + fy="224.27068" + r="8" + gradientTransform="matrix(3.7131449,0,0,3.563472,-838.85008,-725.00376)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + id="linearGradient3760-7-6-4"> + <stop + style="stop-color:#eeeeec;stop-opacity:1" + offset="0" + id="stop3762-0-6-6" /> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="1" + id="stop3764-5-1-4" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient3743-4"> + <stop + style="stop-color:#000000;stop-opacity:0.2" + offset="0" + id="stop3745-6" /> + <stop + style="stop-color:#ffffff;stop-opacity:1" + offset="1" + id="stop3747-2" /> + </linearGradient> + <linearGradient + y2="195" + x2="304" + y1="177" + x1="304" + gradientUnits="userSpaceOnUse" + id="linearGradient2910" + xlink:href="#linearGradient3743-4" + inkscape:collect="always" + gradientTransform="matrix(1.9473685,0,0,1.9444446,-291.47369,-291.58337)" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3100" + id="linearGradient3092" + x1="302" + y1="82.375" + x2="338" + y2="92.75" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3100-5" + id="linearGradient3092-9" + x1="305.89941" + y1="83.784264" + x2="334.10059" + y2="91.340736" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-2,66)" /> + <linearGradient + id="linearGradient3100-5"> + <stop + id="stop3102-6" + offset="0" + style="stop-color:#babdb6;stop-opacity:1" /> + <stop + style="stop-color:#eeeeec;stop-opacity:1" + offset="0.25" + id="stop3104-13" /> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="0.5" + id="stop3106-5" /> + <stop + id="stop3108-50" + offset="0.75" + style="stop-color:#ffffff;stop-opacity:1" /> + <stop + id="stop3110-4" + offset="1" + style="stop-color:#babdb6;stop-opacity:1" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient3743-4-4"> + <stop + style="stop-color:#000000;stop-opacity:0.2" + offset="0" + id="stop3745-6-8" /> + <stop + style="stop-color:#ffffff;stop-opacity:1" + offset="1" + id="stop3747-2-3" /> + </linearGradient> + <linearGradient + y2="195" + x2="304" + y1="180.95102" + x1="304" + gradientTransform="matrix(1.8448754,0,0,1.8333335,-257.26455,-204.75003)" + gradientUnits="userSpaceOnUse" + id="linearGradient4350" + xlink:href="#linearGradient3743-4-4" + inkscape:collect="always" /> + <linearGradient + inkscape:collect="always" + id="linearGradient3760-7-6-4-66-6"> + <stop + style="stop-color:#eeeeec;stop-opacity:1" + offset="0" + id="stop3762-0-6-6-61-7" /> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="1" + id="stop3764-5-1-4-0-6" /> + </linearGradient> + <radialGradient + r="8" + fy="222.91086" + fx="312.22864" + cy="222.91086" + cx="312.22864" + gradientTransform="matrix(2.8880002,0,0,2.9155676,-583.21633,-511.91208)" + gradientUnits="userSpaceOnUse" + id="radialGradient4444" + xlink:href="#linearGradient3760-7-6-4-66-6" + inkscape:collect="always" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2972" + id="linearGradient2978" + x1="315.81155" + y1="82.20932" + x2="315.81155" + y2="89.25135" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2972" + id="linearGradient3756" + x1="318.5" + y1="147.03621" + x2="318.5" + y2="155.96379" + gradientUnits="userSpaceOnUse" /> + <inkscape:perspective + id="perspective3111" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + id="perspective3912" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + id="perspective4331" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + id="perspective4799" + inkscape:persp3d-origin="0.5 : 0.33333333 : 1" + inkscape:vp_z="1 : 0.5 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 0.5 : 1" + sodipodi:type="inkscape:persp3d" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2972" + id="linearGradient2988" + gradientUnits="userSpaceOnUse" + x1="315.81155" + y1="82.20932" + x2="315.81155" + y2="89.25135" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2972" + id="linearGradient2990" + gradientUnits="userSpaceOnUse" + x1="315.81155" + y1="82.20932" + x2="315.81155" + y2="89.25135" /> + </defs> + <g + id="layer1" + inkscape:groupmode="layer" + inkscape:label="artwork" + style="display:inline" + transform="translate(-300,-54)"> + <g + inkscape:groupmode="layer" + id="layer5" + inkscape:label="disabled" + style="display:none" + sodipodi:insensitive="true"> + <rect + height="256" + id="rect6282" + inkscape:label="256x256" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="256" + x="16" + y="28" /> + </g> + <g + id="layer6" + inkscape:groupmode="layer" + inkscape:label="baseplate" + style="display:none"> + <rect + height="48" + id="rect6284" + inkscape:label="48x48" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="48" + x="296" + y="50" /> + <rect + height="32" + id="rect6592" + inkscape:label="32x32" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="32" + x="303" + y="126" /> + <rect + height="22" + id="rect6749" + inkscape:label="22x22" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="22" + x="303" + y="177" /> + <rect + height="16" + id="rect6833" + inkscape:label="16x16" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="16" + x="303" + y="219" /> + <rect + height="24" + id="rect8104" + inkscape:label="24x24" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="24" + x="302" + y="176" /> + <text + id="context" + inkscape:label="context" + style="font-size:18.30070686px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:Bitstream Vera Sans" + x="20.970737" + xml:space="preserve" + y="21.513618"><tspan + id="tspan2716" + sodipodi:role="line" + x="20.970737" + y="21.513618">devices</tspan></text> + <text + id="icon-name" + inkscape:label="icon-name" + sodipodi:linespacing="125%" + style="font-size:18.30070686px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:Droid Sans;-inkscape-font-specification:Droid Sans Bold" + x="141.97073" + xml:space="preserve" + y="21.513618"><tspan + id="tspan3023" + sodipodi:role="line" + x="141.97073" + y="21.513618">input-touchpad</tspan></text> + </g> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="small sizes" + style="display:inline"> + <rect + style="opacity:0.3;color:#000000;fill:none;stroke:url(#linearGradient2910);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect2846-28-6-4" + width="38" + height="35" + x="301.5" + y="55.5" + rx="4" + ry="4" /> + <rect + style="color:#000000;fill:url(#radialGradient3766-2-5-1);fill-opacity:1;fill-rule:nonzero;stroke:#babdb6;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect2846-28-66" + width="35.999939" + height="33.000004" + x="302.50006" + y="56.499996" + rx="3.0000038" + ry="3.0000038" /> + <rect + ry="2" + rx="2" + y="57.5" + x="303.5" + height="25" + width="34" + id="rect3694-0-0" + style="opacity:0.3;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + <g + id="g4205"> + <path + id="rect3694-0-0-9" + d="m 303,84.5 0,2 c 0,1.367703 1.1323,2.5 2.5,2.5 l 14.5,0 0,-2 -14.5,0 c -0.0657,0 -0.1232,-0.02642 -0.1875,-0.03125 C 304.01204,86.871142 303,85.827989 303,84.5 z" + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.1;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" /> + <path + id="rect3694-0-0-9-8" + d="m 338,84.5 0,2 c 0,1.367703 -1.1323,2.5 -2.5,2.5 l -14.5,0 0,-2 14.5,0 c 0.0657,0 0.1232,-0.02642 0.1875,-0.03125 C 336.98796,86.871142 338,85.827989 338,84.5 z" + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.1;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" /> + </g> + <g + id="g2958" + style="fill-opacity:1;stroke:url(#linearGradient2978)"> + <path + sodipodi:nodetypes="ccccccccc" + id="rect2846-28-66-1" + d="m 302.5,80.5 0,6 c 0,1.662002 1.338,3 3,3 l 30,0 c 1.662,0 3,-1.337998 3,-3 l 0,-6 c 0,1.662002 -1.338,3 -3,3 l -30,0 c -1.662,0 -3,-1.337998 -3,-3 z" + style="color:#000000;fill:url(#linearGradient3092);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient2988);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + <path + id="path3112" + d="m 320.5,83.5 0,6" + style="fill:none;stroke:url(#linearGradient2990);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + </g> + <path + style="opacity:0.5;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="m 303.5,83.875 0,2.625 c 0,1.12494 0.87506,2 2,2 l 14,0 0,-4 -14,0 c -0.74347,0 -1.40165,-0.267405 -2,-0.625 z" + id="path3161-2" + sodipodi:nodetypes="ccccccc" /> + <path + style="opacity:0.5;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="m 337.5,83.875 0,2.625 c 0,1.12494 -0.87506,2 -2,2 l -14,0 0,-4 14,0 c 0.74347,0 1.40165,-0.267405 2,-0.625 z" + id="path3161-2-0" + sodipodi:nodetypes="ccccccc" /> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.4;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" + d="m 303,82.65625 0,1.3125 C 303.8401,84.608417 304.86264,85 306,85 l 14,0 0,-1 -14,0 c -1.20201,0 -2.2695,-0.516326 -3,-1.34375 z" + id="rect2846-28-66-0" /> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.4;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" + d="m 338,82.65625 0,1.3125 C 337.1599,84.608417 336.13736,85 335,85 l -14,0 0,-1 14,0 c 1.20201,0 2.2695,-0.516326 3,-1.34375 z" + id="rect2846-28-66-0-6" /> + <path + style="opacity:0.1;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" + d="m 309.49911,81.5 22.00265,0" + id="path4233" /> + <path + style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" + d="m 336.5,76.504425 0,-13.00885" + id="path4235" /> + <rect + style="color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237" + width="0.99953973" + height="0.99999803" + x="307.00046" + y="81" /> + <rect + style="color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237-6" + width="0.99953973" + height="0.99999803" + x="333.00046" + y="81" /> + <rect + style="color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237-6-8" + width="0.99953973" + height="0.99999803" + x="336.00046" + y="78" /> + <rect + style="color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237-6-8-5" + width="0.99953973" + height="0.99999803" + x="336.00046" + y="61" /> + <g + id="layer4-3" + inkscape:label="Muted" + style="display:inline" + transform="translate(284.98438,57.984079)"> + <g + id="g4694" + transform="translate(-2,0)"> + <rect + ry="1.4868355" + rx="1.4868355" + y="16.498245" + x="31.498245" + height="12.00351" + width="12.00351" + id="rect2021" + style="fill:#ef2929;fill-opacity:1;stroke:#cc0000;stroke-width:0.9964897;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:1.20000057;display:inline" /> + <rect + ry="0.4861359" + rx="0.4861359" + y="17.500002" + x="32.5" + height="9.9999962" + width="9.9999962" + id="rect3795" + style="opacity:0.3;fill:none;stroke:#ffffff;stroke-width:0.99999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:1.20000057;display:inline" /> + <path + sodipodi:nodetypes="cc" + id="path4682" + d="m 35,20 5,5" + style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> + <path + sodipodi:nodetypes="cc" + id="path4684" + d="m 40,20 -5,5" + style="fill:none;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline" /> + </g> + </g> + </g> + <g + inkscape:groupmode="layer" + id="layer4" + inkscape:label="hires" + style="display:inline" /> + <g + id="g256" + style="display:inline;enable-background:new" + transform="translate(20,30)" /> + <g + id="g4021" + style="display:inline;enable-background:new" + transform="translate(-577.97771,370.7754)" /> + <g + transform="translate(-457.73144,-1.374928)" + id="g10306" + style="enable-background:new"> + <g + id="layer3" + inkscape:label="plate" + style="display:none"> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect6282-8" + width="256" + height="256" + x="20" + y="20" + inkscape:label="256x256" /> + <rect + inkscape:label="48x48" + y="39.99633" + x="296.0625" + height="48" + width="48" + id="rect6284-8" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect6592-5" + width="32" + height="32" + x="303" + y="115.99633" + inkscape:label="32x32" /> + <rect + inkscape:label="22x22" + y="167.05884" + x="303" + height="22" + width="22" + id="rect6749-0" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect6833-9" + width="16" + height="16" + x="303" + y="209" + inkscape:label="16x16" /> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect5028" + width="24" + height="24" + x="301.95709" + y="165.95343" + inkscape:label="24x24" /> + </g> + <g + id="layer1-6" + inkscape:label="artwork" + style="display:inline"> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:none;overflow:visible;enable-background:accumulate" + id="256x256" + width="256" + height="256" + x="23.5" + y="171.59863" + inkscape:label="256x256" /> + <rect + y="171.59863" + x="-38.5" + height="48" + width="48" + id="48x48" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:none;overflow:visible;enable-background:accumulate" + inkscape:label="48x48" /> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:none;overflow:visible;enable-background:accumulate" + id="24x24" + width="24" + height="24" + x="-123.5" + y="171.59863" + inkscape:label="24x24" /> + <rect + y="171.59863" + x="-155.5" + height="16" + width="16" + id="16x16" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:none;overflow:visible;enable-background:accumulate" + inkscape:label="16x16" /> + <rect + inkscape:label="32x32" + y="171.59863" + x="-87.5" + height="32" + width="32" + id="32x32" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:none;overflow:visible;enable-background:accumulate" /> + </g> + </g> + <g + id="g4445" + style="display:inline;enable-background:new" + transform="translate(-393,-62.246031)" /> + <g + id="g5542" + style="display:inline;enable-background:new" + transform="translate(-364.39697,166.26869)" /> + </g> +</svg> diff --git a/plugins/media-keys/touchpad-enabled-16.png b/plugins/media-keys/touchpad-enabled-16.png Binary files differnew file mode 100644 index 0000000..58fc1d4 --- /dev/null +++ b/plugins/media-keys/touchpad-enabled-16.png diff --git a/plugins/media-keys/touchpad-enabled-22.png b/plugins/media-keys/touchpad-enabled-22.png Binary files differnew file mode 100644 index 0000000..ae23118 --- /dev/null +++ b/plugins/media-keys/touchpad-enabled-22.png diff --git a/plugins/media-keys/touchpad-enabled-24.png b/plugins/media-keys/touchpad-enabled-24.png Binary files differnew file mode 100644 index 0000000..b8617e9 --- /dev/null +++ b/plugins/media-keys/touchpad-enabled-24.png diff --git a/plugins/media-keys/touchpad-enabled-32.png b/plugins/media-keys/touchpad-enabled-32.png Binary files differnew file mode 100644 index 0000000..7bbfa48 --- /dev/null +++ b/plugins/media-keys/touchpad-enabled-32.png diff --git a/plugins/media-keys/touchpad-enabled-48.png b/plugins/media-keys/touchpad-enabled-48.png Binary files differnew file mode 100644 index 0000000..ebad680 --- /dev/null +++ b/plugins/media-keys/touchpad-enabled-48.png 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 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + height="300" + id="svg11300" + inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png" + inkscape:export-xdpi="90.000000" + inkscape:export-ydpi="90.000000" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + inkscape:version="0.47pre4 r22446" + sodipodi:docname="input-touchpad.svg" + sodipodi:version="0.32" + style="display:inline;enable-background:new" + version="1.0" + width="400"> + <title + id="title3835">Touchpad</title> + <metadata + id="metadata154"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title>Touchpad</dc:title> + <dc:creator> + <cc:Agent> + <dc:title>Lapo Calamandrei</dc:title> + </cc:Agent> + </dc:creator> + <dc:contributor> + <cc:Agent> + <dc:title /> + </cc:Agent> + </dc:contributor> + <dc:source /> + <cc:license + rdf:resource="" /> + <dc:subject> + <rdf:Bag /> + </dc:subject> + </cc:Work> + </rdf:RDF> + </metadata> + <sodipodi:namedview + bordercolor="#666666" + borderopacity="0.25490196" + fill="#f57900" + gridtolerance="12" + guidetolerance="13" + height="300px" + id="base" + inkscape:current-layer="layer2" + inkscape:cx="329.26576" + inkscape:cy="97.934968" + inkscape:document-units="px" + inkscape:grid-bbox="true" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:showpageshadow="false" + inkscape:snap-bbox="true" + inkscape:snap-nodes="true" + inkscape:window-height="935" + inkscape:window-width="968" + inkscape:window-x="213" + inkscape:window-y="37" + inkscape:zoom="1" + objecttolerance="7" + pagecolor="#ffffff" + showgrid="false" + stroke="#ef2929" + width="400px" + showguides="true" + inkscape:guide-bbox="true" + showborder="true" + inkscape:window-maximized="0"> + <inkscape:grid + enabled="true" + id="grid5883" + spacingx="0.5px" + spacingy="0.5px" + type="xygrid" + visible="true" + empspacing="2" + snapvisiblegridlinesonly="true" /> + </sodipodi:namedview> + <defs + id="defs3"> + <linearGradient + inkscape:collect="always" + id="linearGradient2972"> + <stop + style="stop-color:#babdb6;stop-opacity:1" + offset="0" + id="stop2974" /> + <stop + style="stop-color:#555753;stop-opacity:1" + offset="1" + id="stop2976" /> + </linearGradient> + <linearGradient + id="linearGradient3100"> + <stop + id="stop3102" + offset="0" + style="stop-color:#babdb6;stop-opacity:1" /> + <stop + style="stop-color:#eeeeec;stop-opacity:1" + offset="0.25" + id="stop3104" /> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="0.5" + id="stop3106" /> + <stop + id="stop3108" + offset="0.75" + style="stop-color:#ffffff;stop-opacity:1" /> + <stop + id="stop3110" + offset="1" + style="stop-color:#babdb6;stop-opacity:1" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient3743"> + <stop + style="stop-color:#000000;stop-opacity:0.2" + offset="0" + id="stop3745" /> + <stop + style="stop-color:#ffffff;stop-opacity:1" + offset="1" + id="stop3747" /> + </linearGradient> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3760-7" + id="radialGradient3766-2" + cx="311" + cy="225.23932" + fx="311" + fy="225.23932" + r="8" + gradientTransform="matrix(1.4590081,0,0,1.0942561,-142.75153,-21.969492)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + id="linearGradient3760-7"> + <stop + style="stop-color:#eeeeec;stop-opacity:1" + offset="0" + id="stop3762-0" /> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="1" + id="stop3764-5" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient3752-2"> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="0" + id="stop3754-2" /> + <stop + style="stop-color:#babdb6;stop-opacity:1" + offset="1" + id="stop3756-8" /> + </linearGradient> + <linearGradient + y2="238.1875" + x2="324.875" + y1="231.5" + x1="304.8125" + gradientUnits="userSpaceOnUse" + id="linearGradient3794" + xlink:href="#linearGradient3752-2" + inkscape:collect="always" + gradientTransform="translate(0,-1)" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3760-7-6" + id="radialGradient3766-2-5" + cx="312.09396" + cy="224.27068" + fx="312.09396" + fy="224.27068" + r="8" + gradientTransform="matrix(2.0157047,0,0,1.5117786,-315.08929,-153.04762)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + id="linearGradient3760-7-6"> + <stop + style="stop-color:#eeeeec;stop-opacity:1" + offset="0" + id="stop3762-0-6" /> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="1" + id="stop3764-5-1" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient3752-2-3"> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="0" + id="stop3754-2-2" /> + <stop + style="stop-color:#babdb6;stop-opacity:1" + offset="1" + id="stop3756-8-6" /> + </linearGradient> + <linearGradient + y2="238.1875" + x2="324.875" + y1="231.5" + x1="304.8125" + gradientUnits="userSpaceOnUse" + id="linearGradient2894" + xlink:href="#linearGradient3752-2-3" + inkscape:collect="always" + gradientTransform="translate(1,-38)" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3743" + id="linearGradient3749" + x1="304" + y1="177" + x2="304" + y2="195" + gradientUnits="userSpaceOnUse" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3760-7-6-4" + id="radialGradient3766-2-5-1" + cx="312.09396" + cy="224.27068" + fx="312.09396" + fy="224.27068" + r="8" + gradientTransform="matrix(3.7131449,0,0,3.563472,-838.85008,-725.00376)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + id="linearGradient3760-7-6-4"> + <stop + style="stop-color:#eeeeec;stop-opacity:1" + offset="0" + id="stop3762-0-6-6" /> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="1" + id="stop3764-5-1-4" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient3743-4"> + <stop + style="stop-color:#000000;stop-opacity:0.2" + offset="0" + id="stop3745-6" /> + <stop + style="stop-color:#ffffff;stop-opacity:1" + offset="1" + id="stop3747-2" /> + </linearGradient> + <linearGradient + y2="195" + x2="304" + y1="177" + x1="304" + gradientUnits="userSpaceOnUse" + id="linearGradient2910" + xlink:href="#linearGradient3743-4" + inkscape:collect="always" + gradientTransform="matrix(1.9473685,0,0,1.9444446,-291.47369,-291.58337)" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3100" + id="linearGradient3092" + x1="302" + y1="82.375" + x2="338" + y2="92.75" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3100-5" + id="linearGradient3092-9" + x1="305.89941" + y1="83.784264" + x2="334.10059" + y2="91.340736" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-2,66)" /> + <linearGradient + id="linearGradient3100-5"> + <stop + id="stop3102-6" + offset="0" + style="stop-color:#babdb6;stop-opacity:1" /> + <stop + style="stop-color:#eeeeec;stop-opacity:1" + offset="0.25" + id="stop3104-13" /> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="0.5" + id="stop3106-5" /> + <stop + id="stop3108-50" + offset="0.75" + style="stop-color:#ffffff;stop-opacity:1" /> + <stop + id="stop3110-4" + offset="1" + style="stop-color:#babdb6;stop-opacity:1" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient3743-4-4"> + <stop + style="stop-color:#000000;stop-opacity:0.2" + offset="0" + id="stop3745-6-8" /> + <stop + style="stop-color:#ffffff;stop-opacity:1" + offset="1" + id="stop3747-2-3" /> + </linearGradient> + <linearGradient + y2="195" + x2="304" + y1="180.95102" + x1="304" + gradientTransform="matrix(1.8448754,0,0,1.8333335,-257.26455,-204.75003)" + gradientUnits="userSpaceOnUse" + id="linearGradient4350" + xlink:href="#linearGradient3743-4-4" + inkscape:collect="always" /> + <linearGradient + inkscape:collect="always" + id="linearGradient3760-7-6-4-66-6"> + <stop + style="stop-color:#eeeeec;stop-opacity:1" + offset="0" + id="stop3762-0-6-6-61-7" /> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="1" + id="stop3764-5-1-4-0-6" /> + </linearGradient> + <radialGradient + r="8" + fy="222.91086" + fx="312.22864" + cy="222.91086" + cx="312.22864" + gradientTransform="matrix(2.8880002,0,0,2.9155676,-583.21633,-511.91208)" + gradientUnits="userSpaceOnUse" + id="radialGradient4444" + xlink:href="#linearGradient3760-7-6-4-66-6" + inkscape:collect="always" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2972" + id="linearGradient2978" + x1="315.81155" + y1="82.20932" + x2="315.81155" + y2="89.25135" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2972" + id="linearGradient3756" + x1="318.5" + y1="147.03621" + x2="318.5" + y2="155.96379" + gradientUnits="userSpaceOnUse" /> + </defs> + <g + id="layer1" + inkscape:groupmode="layer" + inkscape:label="artwork" + style="display:inline"> + <g + inkscape:groupmode="layer" + id="layer5" + inkscape:label="disabled" + style="display:none" + sodipodi:insensitive="true"> + <rect + height="256" + id="rect6282" + inkscape:label="256x256" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="256" + x="16" + y="28" /> + </g> + <g + id="layer6" + inkscape:groupmode="layer" + inkscape:label="baseplate" + style="display:none"> + <rect + height="48" + id="rect6284" + inkscape:label="48x48" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="48" + x="296" + y="50" /> + <rect + height="32" + id="rect6592" + inkscape:label="32x32" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="32" + x="303" + y="126" /> + <rect + height="22" + id="rect6749" + inkscape:label="22x22" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="22" + x="303" + y="177" /> + <rect + height="16" + id="rect6833" + inkscape:label="16x16" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="16" + x="303" + y="219" /> + <rect + height="24" + id="rect8104" + inkscape:label="24x24" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="24" + x="302" + y="176" /> + <text + id="context" + inkscape:label="context" + style="font-size:18.30070686px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:Bitstream Vera Sans" + x="20.970737" + xml:space="preserve" + y="21.513618"><tspan + id="tspan2716" + sodipodi:role="line" + x="20.970737" + y="21.513618">devices</tspan></text> + <text + id="icon-name" + inkscape:label="icon-name" + sodipodi:linespacing="125%" + style="font-size:18.30070686px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:Droid Sans;-inkscape-font-specification:Droid Sans Bold" + x="141.97073" + xml:space="preserve" + y="21.513618"><tspan + id="tspan3023" + sodipodi:role="line" + x="141.97073" + y="21.513618">input-touchpad</tspan></text> + </g> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="small sizes" + style="display:inline"> + <path + style="color:#000000;fill:url(#linearGradient3794);fill-opacity:1;fill-rule:nonzero;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="m 303.5,227.5 0,4 c 0,1.108 0.892,2 2,2 l 11,0 c 1.108,0 2,-0.892 2,-2 l 0,-4 c 0,1.108 -0.892,2 -2,2 l -11,0 c -1.108,0 -2,-0.892 -2,-2 z" + id="rect2846-2-3" + sodipodi:nodetypes="ccccccccc" /> + <rect + style="color:#000000;fill:url(#radialGradient3766-2);fill-opacity:1;fill-rule:nonzero;stroke:#babdb6;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect2846" + width="15" + height="10" + x="303.5" + y="219.5" + rx="2" + ry="2" /> + <rect + style="opacity:0.3;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3694" + width="13" + height="12" + x="304.5" + y="220.5" + rx="1" + ry="1" /> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeec;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" + d="m 304,229.5 0,1 c 0,0.0541 0.002,0.1029 0,0.15625 0.45244,0.21377 0.96717,0.34375 1.5,0.34375 l 11,0 c 0.53283,0 1.04756,-0.12998 1.5,-0.34375 L 318,229.5 c -0.41577,0.30853 -0.93558,0.5 -1.5,0.5 l -11,0 c -0.56442,0 -1.08423,-0.19147 -1.5,-0.5 z" + id="rect2846-2" + sodipodi:nodetypes="cccccccccc" /> + <rect + style="color:#000000;fill:#d3d7cf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3728" + width="1" + height="3" + x="310" + y="230" + rx="0" + ry="0" /> + <rect + style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3728-4" + width="1" + height="3" + x="311" + y="230" + rx="0" + ry="0" /> + <rect + style="opacity:0.3;color:#000000;fill:none;stroke:url(#linearGradient3749);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect2846-28-6" + width="19" + height="18" + x="304.5" + y="178.5" + rx="2" + ry="2" /> + <path + style="color:#000000;fill:url(#linearGradient2894);fill-opacity:1;fill-rule:nonzero;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="m 304.5,190.5 0,4 c 0,1.108 0.892,2 2,2 l 15,0 c 1.108,0 2,-0.892 2,-2 l 0,-4 c 0,1.108 -0.892,2 -2,2 l -15,0 c -1.108,0 -2,-0.892 -2,-2 z" + id="rect2846-2-3-0" + sodipodi:nodetypes="ccccccccc" /> + <rect + style="color:#000000;fill:url(#radialGradient3766-2-5);fill-opacity:1;fill-rule:nonzero;stroke:#babdb6;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect2846-28" + width="18.999943" + height="14.000024" + x="304.5" + y="178.5" + rx="2" + ry="2" /> + <rect + style="opacity:0.3;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3694-0" + width="17.000095" + height="16.000011" + x="305.5" + y="179.5" + rx="1" + ry="1" /> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;color:#000000;fill:#eeeeec;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" + d="m 305,192.5 0,1 c 0,0.0541 0.002,0.1029 0,0.15625 0.45244,0.21377 0.96717,0.34375 1.5,0.34375 l 15,0 c 0.53283,0 1.04756,-0.12998 1.5,-0.34375 L 323,192.5 c -0.41577,0.30853 -0.93558,0.5 -1.5,0.5 l -15,0 c -0.56442,0 -1.08423,-0.19147 -1.5,-0.5 z" + id="rect2846-2-1" + sodipodi:nodetypes="cccccccccc" /> + <rect + style="color:#000000;fill:#d3d7cf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3728-5" + width="1" + height="3" + x="313" + y="193" + rx="0" + ry="0" /> + <rect + style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3728-4-5" + width="1" + height="3" + x="314" + y="193" + rx="0" + ry="0" /> + <rect + style="opacity:0.3;color:#000000;fill:none;stroke:url(#linearGradient2910);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect2846-28-6-4" + width="38" + height="35" + x="301.5" + y="55.5" + rx="4" + ry="4" /> + <rect + style="color:#000000;fill:url(#radialGradient3766-2-5-1);fill-opacity:1;fill-rule:nonzero;stroke:#babdb6;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect2846-28-66" + width="35.999939" + height="33.000004" + x="302.50006" + y="56.499996" + rx="3.0000038" + ry="3.0000038" /> + <rect + ry="2" + rx="2" + y="57.5" + x="303.5" + height="25" + width="34" + id="rect3694-0-0" + style="opacity:0.3;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + <g + id="g4205"> + <path + id="rect3694-0-0-9" + d="m 303,84.5 0,2 c 0,1.367703 1.1323,2.5 2.5,2.5 l 14.5,0 0,-2 -14.5,0 c -0.0657,0 -0.1232,-0.02642 -0.1875,-0.03125 C 304.01204,86.871142 303,85.827989 303,84.5 z" + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.1;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" /> + <path + id="rect3694-0-0-9-8" + d="m 338,84.5 0,2 c 0,1.367703 -1.1323,2.5 -2.5,2.5 l -14.5,0 0,-2 14.5,0 c 0.0657,0 0.1232,-0.02642 0.1875,-0.03125 C 336.98796,86.871142 338,85.827989 338,84.5 z" + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.1;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" /> + </g> + <g + id="g2958" + style="fill-opacity:1;stroke:url(#linearGradient2978)"> + <path + sodipodi:nodetypes="ccccccccc" + id="rect2846-28-66-1" + d="m 302.5,80.5 0,6 c 0,1.662002 1.338,3 3,3 l 30,0 c 1.662,0 3,-1.337998 3,-3 l 0,-6 c 0,1.662002 -1.338,3 -3,3 l -30,0 c -1.662,0 -3,-1.337998 -3,-3 z" + style="color:#000000;fill:url(#linearGradient3092);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient2978);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + <path + id="path3112" + d="m 320.5,83.5 0,6" + style="fill:none;stroke:url(#linearGradient2978);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" /> + </g> + <path + style="opacity:0.5;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="m 303.5,83.875 0,2.625 c 0,1.12494 0.87506,2 2,2 l 14,0 0,-4 -14,0 c -0.74347,0 -1.40165,-0.267405 -2,-0.625 z" + id="path3161-2" + sodipodi:nodetypes="ccccccc" /> + <path + style="opacity:0.5;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="m 337.5,83.875 0,2.625 c 0,1.12494 -0.87506,2 -2,2 l -14,0 0,-4 14,0 c 0.74347,0 1.40165,-0.267405 2,-0.625 z" + id="path3161-2-0" + sodipodi:nodetypes="ccccccc" /> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.4;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" + d="m 303,82.65625 0,1.3125 C 303.8401,84.608417 304.86264,85 306,85 l 14,0 0,-1 -14,0 c -1.20201,0 -2.2695,-0.516326 -3,-1.34375 z" + id="rect2846-28-66-0" /> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.4;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" + d="m 338,82.65625 0,1.3125 C 337.1599,84.608417 336.13736,85 335,85 l -14,0 0,-1 14,0 c 1.20201,0 2.2695,-0.516326 3,-1.34375 z" + id="rect2846-28-66-0-6" /> + <path + style="opacity:0.1;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" + d="m 309.49911,81.5 22.00265,0" + id="path4233" /> + <path + style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" + d="m 336.5,76.504425 0,-13.00885" + id="path4235" /> + <rect + style="opacity:1;color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237" + width="0.99953973" + height="0.99999803" + x="307.00046" + y="81" /> + <rect + style="opacity:1;color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237-6" + width="0.99953973" + height="0.99999803" + x="333.00046" + y="81" /> + <rect + style="opacity:1;color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237-6-8" + width="0.99953973" + height="0.99999803" + x="336.00046" + y="78" /> + <rect + style="opacity:1;color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237-6-8-5" + width="0.99953973" + height="0.99999803" + x="336.00046" + y="61" /> + <rect + style="opacity:0.3;color:#000000;fill:none;stroke:url(#linearGradient4350);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect2846-28-6-4-0" + width="28" + height="27" + x="304.5" + y="128.5" + rx="3" + ry="3" /> + <rect + style="color:#000000;fill:url(#radialGradient4444);fill-opacity:1;fill-rule:nonzero;stroke:#babdb6;stroke-width:0.99999994000000003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect2846-28-66-3-9" + width="28" + height="26" + x="304.5" + y="128.5" + rx="3" + ry="3" /> + <rect + ry="2" + rx="2" + y="129.5" + x="305.5" + height="20" + width="26" + id="rect3694-0-0-2" + style="opacity:0.3;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + <g + id="g3752" + style="stroke:url(#linearGradient3756)"> + <path + sodipodi:nodetypes="ccccccccc" + id="rect2846-28-66-1-2" + d="m 304.5,147.5 0,5 c 0,1.662 1.338,3 3,3 l 22,0 c 1.662,0 3,-1.338 3,-3 l 0,-5 c 0,1.662 -1.338,3 -3,3 l -22,0 c -1.662,0 -3,-1.338 -3,-3 z" + style="color:#000000;fill:url(#linearGradient3092-9);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient3756);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + <path + sodipodi:nodetypes="cc" + id="path3112-3" + d="m 318.5,150.5 0,5" + style="fill:none;stroke:url(#linearGradient3756);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" /> + </g> + <g + style="display:inline;enable-background:new" + id="g4205-5" + transform="translate(-2,66)"> + <path + id="rect3694-0-0-9-83" + d="m 307,84.5 0,2 c 0,1.367703 1.1323,2.5 2.5,2.5 l 10.5,0 0,-2 -10.5,0 c -0.0657,0 -0.1232,-0.02642 -0.1875,-0.03125 C 308.01204,86.871142 307,85.827989 307,84.5 z" + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.1;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" + sodipodi:nodetypes="ccccccsc" /> + <path + id="rect3694-0-0-9-8-9" + d="m 334,84.5 0,2 c 0,1.367703 -1.1323,2.5 -2.5,2.5 l -10.5,0 0,-2 10.5,0 c 0.0657,0 0.1232,-0.02642 0.1875,-0.03125 C 332.98796,86.871142 334,85.827989 334,84.5 z" + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.1;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" + sodipodi:nodetypes="ccccccsc" /> + </g> + <path + style="opacity:0.6;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="m 305.5,150.875 0,1.625 c 0,1.12494 0.87506,2 2,2 l 10,0 0,-3 -10,0 c -0.74347,0 -1.40165,-0.2674 -2,-0.625 z" + id="path3161-2-4" + sodipodi:nodetypes="ccccccc" /> + <path + style="opacity:0.6;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="m 331.5,150.875 0,1.625 c 0,1.12494 -0.87506,2 -2,2 l -10,0 0,-3 10,0 c 0.74347,0 1.40165,-0.2674 2,-0.625 z" + id="path3161-2-0-7" + sodipodi:nodetypes="ccccccc" /> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.4;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" + d="m 305,149.65625 0,1.3125 c 0.8401,0.63967 1.86264,1.03125 3,1.03125 l 10,0 0,-1 -10,0 c -1.20201,0 -2.2695,-0.51633 -3,-1.34375 z" + id="rect2846-28-66-0-7" + sodipodi:nodetypes="ccccccc" /> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.4;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" + d="m 332,149.65625 0,1.3125 C 331.1599,151.60842 330.13736,152 329,152 l -10,0 0,-1 10,0 c 1.20201,0 2.2695,-0.51633 3,-1.34375 z" + id="rect2846-28-66-0-6-4" + sodipodi:nodetypes="ccccccc" /> + <path + style="opacity:0.1;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" + d="m 310.49911,148.5 15.00265,0" + id="path4233-4" + sodipodi:nodetypes="cc" /> + <path + style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;display:inline;enable-background:new" + d="m 330.5,143.50442 0,-9.00884" + id="path4235-3" + sodipodi:nodetypes="cc" /> + <rect + style="opacity:1;color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237-5" + width="0.99953973" + height="0.99999803" + x="308.00046" + y="148" /> + <rect + style="opacity:1;color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237-6-80" + width="0.99953973" + height="0.99999803" + x="327.00046" + y="148" /> + <rect + style="opacity:1;color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237-6-8-3" + width="0.99953973" + height="0.99999803" + x="330.00046" + y="145" /> + <rect + style="opacity:1;color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237-6-8-5-0" + width="0.99953973" + height="0.99999803" + x="330.00046" + y="132" /> + </g> + <g + inkscape:groupmode="layer" + id="layer4" + inkscape:label="hires" + style="display:inline" /> + <g + id="g256" + style="display:inline;enable-background:new" + transform="translate(20,30)" /> + <g + id="g4021" + style="display:inline;enable-background:new" + transform="translate(-577.97771,370.7754)" /> + <g + transform="translate(-457.73144,-1.374928)" + id="g10306" + style="enable-background:new"> + <g + id="layer3" + inkscape:label="plate" + style="display:none"> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect6282-8" + width="256" + height="256" + x="20" + y="20" + inkscape:label="256x256" /> + <rect + inkscape:label="48x48" + y="39.99633" + x="296.0625" + height="48" + width="48" + id="rect6284-8" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect6592-5" + width="32" + height="32" + x="303" + y="115.99633" + inkscape:label="32x32" /> + <rect + inkscape:label="22x22" + y="167.05884" + x="303" + height="22" + width="22" + id="rect6749-0" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect6833-9" + width="16" + height="16" + x="303" + y="209" + inkscape:label="16x16" /> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect5028" + width="24" + height="24" + x="301.95709" + y="165.95343" + inkscape:label="24x24" /> + </g> + <g + id="layer1-6" + inkscape:label="artwork" + style="display:inline"> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:none;overflow:visible;enable-background:accumulate" + id="256x256" + width="256" + height="256" + x="23.5" + y="171.59863" + inkscape:label="256x256" /> + <rect + y="171.59863" + x="-38.5" + height="48" + width="48" + id="48x48" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:none;overflow:visible;enable-background:accumulate" + inkscape:label="48x48" /> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:none;overflow:visible;enable-background:accumulate" + id="24x24" + width="24" + height="24" + x="-123.5" + y="171.59863" + inkscape:label="24x24" /> + <rect + y="171.59863" + x="-155.5" + height="16" + width="16" + id="16x16" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:none;overflow:visible;enable-background:accumulate" + inkscape:label="16x16" /> + <rect + inkscape:label="32x32" + y="171.59863" + x="-87.5" + height="32" + width="32" + id="32x32" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:none;overflow:visible;enable-background:accumulate" /> + </g> + </g> + <g + id="g4445" + style="display:inline;enable-background:new" + transform="translate(-393,-62.246031)" /> + <g + id="g5542" + style="display:inline;enable-background:new" + transform="translate(-364.39697,166.26869)" /> + </g> +</svg> 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 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + height="38" + id="svg11300" + inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png" + inkscape:export-xdpi="90.000000" + inkscape:export-ydpi="90.000000" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + inkscape:version="0.47 r22583" + sodipodi:docname="touchpad-enabled.svg" + sodipodi:version="0.32" + style="display:inline;enable-background:new" + version="1.0" + width="41"> + <title + id="title3835">Touchpad</title> + <metadata + id="metadata154"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title>Touchpad</dc:title> + <dc:creator> + <cc:Agent> + <dc:title>Lapo Calamandrei</dc:title> + </cc:Agent> + </dc:creator> + <dc:contributor> + <cc:Agent> + <dc:title /> + </cc:Agent> + </dc:contributor> + <dc:source /> + <cc:license + rdf:resource="" /> + <dc:subject> + <rdf:Bag /> + </dc:subject> + </cc:Work> + </rdf:RDF> + </metadata> + <sodipodi:namedview + bordercolor="#666666" + borderopacity="0.25490196" + fill="#f57900" + gridtolerance="12" + guidetolerance="13" + height="300px" + id="base" + inkscape:current-layer="layer2" + inkscape:cx="29.26576" + inkscape:cy="-112.06503" + inkscape:document-units="px" + inkscape:grid-bbox="true" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:showpageshadow="false" + inkscape:snap-bbox="true" + inkscape:snap-nodes="true" + inkscape:window-height="935" + inkscape:window-width="968" + inkscape:window-x="213" + inkscape:window-y="37" + inkscape:zoom="1" + objecttolerance="7" + pagecolor="#ffffff" + showgrid="false" + stroke="#ef2929" + width="400px" + showguides="true" + inkscape:guide-bbox="true" + showborder="true" + inkscape:window-maximized="0"> + <inkscape:grid + enabled="true" + id="grid5883" + spacingx="0.5px" + spacingy="0.5px" + type="xygrid" + visible="true" + empspacing="2" + snapvisiblegridlinesonly="true" /> + </sodipodi:namedview> + <defs + id="defs3"> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 150 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="400 : 150 : 1" + inkscape:persp3d-origin="200 : 100 : 1" + id="perspective147" /> + <linearGradient + inkscape:collect="always" + id="linearGradient2972"> + <stop + style="stop-color:#babdb6;stop-opacity:1" + offset="0" + id="stop2974" /> + <stop + style="stop-color:#555753;stop-opacity:1" + offset="1" + id="stop2976" /> + </linearGradient> + <linearGradient + id="linearGradient3100"> + <stop + id="stop3102" + offset="0" + style="stop-color:#babdb6;stop-opacity:1" /> + <stop + style="stop-color:#eeeeec;stop-opacity:1" + offset="0.25" + id="stop3104" /> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="0.5" + id="stop3106" /> + <stop + id="stop3108" + offset="0.75" + style="stop-color:#ffffff;stop-opacity:1" /> + <stop + id="stop3110" + offset="1" + style="stop-color:#babdb6;stop-opacity:1" /> + </linearGradient> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient3760-7-6-4" + id="radialGradient3766-2-5-1" + cx="312.09396" + cy="224.27068" + fx="312.09396" + fy="224.27068" + r="8" + gradientTransform="matrix(3.7131449,0,0,3.563472,-838.85008,-725.00376)" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + id="linearGradient3760-7-6-4"> + <stop + style="stop-color:#eeeeec;stop-opacity:1" + offset="0" + id="stop3762-0-6-6" /> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="1" + id="stop3764-5-1-4" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient3743-4"> + <stop + style="stop-color:#000000;stop-opacity:0.2" + offset="0" + id="stop3745-6" /> + <stop + style="stop-color:#ffffff;stop-opacity:1" + offset="1" + id="stop3747-2" /> + </linearGradient> + <linearGradient + y2="195" + x2="304" + y1="177" + x1="304" + gradientUnits="userSpaceOnUse" + id="linearGradient2910" + xlink:href="#linearGradient3743-4" + inkscape:collect="always" + gradientTransform="matrix(1.9473685,0,0,1.9444446,-291.47369,-291.58337)" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3100" + id="linearGradient3092" + x1="302" + y1="82.375" + x2="338" + y2="92.75" + gradientUnits="userSpaceOnUse" /> + <linearGradient + id="linearGradient3100-5"> + <stop + id="stop3102-6" + offset="0" + style="stop-color:#babdb6;stop-opacity:1" /> + <stop + style="stop-color:#eeeeec;stop-opacity:1" + offset="0.25" + id="stop3104-13" /> + <stop + style="stop-color:#d3d7cf;stop-opacity:1" + offset="0.5" + id="stop3106-5" /> + <stop + id="stop3108-50" + offset="0.75" + style="stop-color:#ffffff;stop-opacity:1" /> + <stop + id="stop3110-4" + offset="1" + style="stop-color:#babdb6;stop-opacity:1" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2972" + id="linearGradient2978" + x1="315.81155" + y1="82.20932" + x2="315.81155" + y2="89.25135" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2972" + id="linearGradient3756" + x1="318.5" + y1="147.03621" + x2="318.5" + y2="155.96379" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2972" + id="linearGradient2953" + gradientUnits="userSpaceOnUse" + x1="315.81155" + y1="82.20932" + x2="315.81155" + y2="89.25135" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2972" + id="linearGradient2955" + gradientUnits="userSpaceOnUse" + x1="315.81155" + y1="82.20932" + x2="315.81155" + y2="89.25135" /> + </defs> + <g + id="layer1" + inkscape:groupmode="layer" + inkscape:label="artwork" + style="display:inline" + transform="translate(-300,-54)"> + <g + inkscape:groupmode="layer" + id="layer5" + inkscape:label="disabled" + style="display:none" + sodipodi:insensitive="true"> + <rect + height="256" + id="rect6282" + inkscape:label="256x256" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="256" + x="16" + y="28" /> + </g> + <g + id="layer6" + inkscape:groupmode="layer" + inkscape:label="baseplate" + style="display:none"> + <rect + height="48" + id="rect6284" + inkscape:label="48x48" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="48" + x="296" + y="50" /> + <rect + height="32" + id="rect6592" + inkscape:label="32x32" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="32" + x="303" + y="126" /> + <rect + height="22" + id="rect6749" + inkscape:label="22x22" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="22" + x="303" + y="177" /> + <rect + height="16" + id="rect6833" + inkscape:label="16x16" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="16" + x="303" + y="219" /> + <rect + height="24" + id="rect8104" + inkscape:label="24x24" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + width="24" + x="302" + y="176" /> + <text + id="context" + inkscape:label="context" + style="font-size:18.30070686px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:Bitstream Vera Sans" + x="20.970737" + xml:space="preserve" + y="21.513618"><tspan + id="tspan2716" + sodipodi:role="line" + x="20.970737" + y="21.513618">devices</tspan></text> + <text + id="icon-name" + inkscape:label="icon-name" + sodipodi:linespacing="125%" + style="font-size:18.30070686px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:Droid Sans;-inkscape-font-specification:Droid Sans Bold" + x="141.97073" + xml:space="preserve" + y="21.513618"><tspan + id="tspan3023" + sodipodi:role="line" + x="141.97073" + y="21.513618">input-touchpad</tspan></text> + </g> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="small sizes" + style="display:inline"> + <rect + style="opacity:0.3;color:#000000;fill:none;stroke:url(#linearGradient2910);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect2846-28-6-4" + width="38" + height="35" + x="301.5" + y="55.5" + rx="4" + ry="4" /> + <rect + style="color:#000000;fill:url(#radialGradient3766-2-5-1);fill-opacity:1;fill-rule:nonzero;stroke:#babdb6;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect2846-28-66" + width="35.999939" + height="33.000004" + x="302.50006" + y="56.499996" + rx="3.0000038" + ry="3.0000038" /> + <rect + ry="2" + rx="2" + y="57.5" + x="303.5" + height="25" + width="34" + id="rect3694-0-0" + style="opacity:0.3;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + <g + id="g4205"> + <path + id="rect3694-0-0-9" + d="m 303,84.5 0,2 c 0,1.367703 1.1323,2.5 2.5,2.5 l 14.5,0 0,-2 -14.5,0 c -0.0657,0 -0.1232,-0.02642 -0.1875,-0.03125 C 304.01204,86.871142 303,85.827989 303,84.5 z" + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.1;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" /> + <path + id="rect3694-0-0-9-8" + d="m 338,84.5 0,2 c 0,1.367703 -1.1323,2.5 -2.5,2.5 l -14.5,0 0,-2 14.5,0 c 0.0657,0 0.1232,-0.02642 0.1875,-0.03125 C 336.98796,86.871142 338,85.827989 338,84.5 z" + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.1;color:#000000;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" /> + </g> + <g + id="g2958" + style="fill-opacity:1;stroke:url(#linearGradient2978)"> + <path + sodipodi:nodetypes="ccccccccc" + id="rect2846-28-66-1" + d="m 302.5,80.5 0,6 c 0,1.662002 1.338,3 3,3 l 30,0 c 1.662,0 3,-1.337998 3,-3 l 0,-6 c 0,1.662002 -1.338,3 -3,3 l -30,0 c -1.662,0 -3,-1.337998 -3,-3 z" + style="color:#000000;fill:url(#linearGradient3092);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient2953);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + <path + id="path3112" + d="m 320.5,83.5 0,6" + style="fill:none;stroke:url(#linearGradient2955);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + </g> + <path + style="opacity:0.5;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="m 303.5,83.875 0,2.625 c 0,1.12494 0.87506,2 2,2 l 14,0 0,-4 -14,0 c -0.74347,0 -1.40165,-0.267405 -2,-0.625 z" + id="path3161-2" + sodipodi:nodetypes="ccccccc" /> + <path + style="opacity:0.5;color:#000000;fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + d="m 337.5,83.875 0,2.625 c 0,1.12494 -0.87506,2 -2,2 l -14,0 0,-4 14,0 c 0.74347,0 1.40165,-0.267405 2,-0.625 z" + id="path3161-2-0" + sodipodi:nodetypes="ccccccc" /> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.4;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" + d="m 303,82.65625 0,1.3125 C 303.8401,84.608417 304.86264,85 306,85 l 14,0 0,-1 -14,0 c -1.20201,0 -2.2695,-0.516326 -3,-1.34375 z" + id="rect2846-28-66-0" /> + <path + style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;opacity:0.4;color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Abandoned Bitplane;-inkscape-font-specification:Abandoned Bitplane" + d="m 338,82.65625 0,1.3125 C 337.1599,84.608417 336.13736,85 335,85 l -14,0 0,-1 14,0 c 1.20201,0 2.2695,-0.516326 3,-1.34375 z" + id="rect2846-28-66-0-6" /> + <path + style="opacity:0.1;fill:none;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" + d="m 309.49911,81.5 22.00265,0" + id="path4233" /> + <path + style="opacity:0.1;fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" + d="m 336.5,76.504425 0,-13.00885" + id="path4235" /> + <rect + style="color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237" + width="0.99953973" + height="0.99999803" + x="307.00046" + y="81" /> + <rect + style="color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237-6" + width="0.99953973" + height="0.99999803" + x="333.00046" + y="81" /> + <rect + style="color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237-6-8" + width="0.99953973" + height="0.99999803" + x="336.00046" + y="78" /> + <rect + style="color:#000000;fill:#729fcf;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect4237-6-8-5" + width="0.99953973" + height="0.99999803" + x="336.00046" + y="61" /> + </g> + <g + inkscape:groupmode="layer" + id="layer4" + inkscape:label="hires" + style="display:inline" /> + <g + id="g256" + style="display:inline;enable-background:new" + transform="translate(20,30)" /> + <g + id="g4021" + style="display:inline;enable-background:new" + transform="translate(-577.97771,370.7754)" /> + <g + transform="translate(-457.73144,-1.374928)" + id="g10306" + style="enable-background:new"> + <g + id="layer3" + inkscape:label="plate" + style="display:none"> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect6282-8" + width="256" + height="256" + x="20" + y="20" + inkscape:label="256x256" /> + <rect + inkscape:label="48x48" + y="39.99633" + x="296.0625" + height="48" + width="48" + id="rect6284-8" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect6592-5" + width="32" + height="32" + x="303" + y="115.99633" + inkscape:label="32x32" /> + <rect + inkscape:label="22x22" + y="167.05884" + x="303" + height="22" + width="22" + id="rect6749-0" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect6833-9" + width="16" + height="16" + x="303" + y="209" + inkscape:label="16x16" /> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect5028" + width="24" + height="24" + x="301.95709" + y="165.95343" + inkscape:label="24x24" /> + </g> + <g + id="layer1-6" + inkscape:label="artwork" + style="display:inline"> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:none;overflow:visible;enable-background:accumulate" + id="256x256" + width="256" + height="256" + x="23.5" + y="171.59863" + inkscape:label="256x256" /> + <rect + y="171.59863" + x="-38.5" + height="48" + width="48" + id="48x48" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:none;overflow:visible;enable-background:accumulate" + inkscape:label="48x48" /> + <rect + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:none;overflow:visible;enable-background:accumulate" + id="24x24" + width="24" + height="24" + x="-123.5" + y="171.59863" + inkscape:label="24x24" /> + <rect + y="171.59863" + x="-155.5" + height="16" + width="16" + id="16x16" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:none;overflow:visible;enable-background:accumulate" + inkscape:label="16x16" /> + <rect + inkscape:label="32x32" + y="171.59863" + x="-87.5" + height="32" + width="32" + id="32x32" + style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:none;overflow:visible;enable-background:accumulate" /> + </g> + </g> + <g + id="g4445" + style="display:inline;enable-background:new" + transform="translate(-393,-62.246031)" /> + <g + id="g5542" + style="display:inline;enable-background:new" + transform="translate(-364.39697,166.26869)" /> + </g> +</svg> diff --git a/plugins/mouse/Makefile.am b/plugins/mouse/Makefile.am new file mode 100644 index 0000000..f99aefc --- /dev/null +++ b/plugins/mouse/Makefile.am @@ -0,0 +1,52 @@ +plugin_LTLIBRARIES = libmouse.la + +libmouse_la_SOURCES = \ + gsd-mouse-plugin.h \ + gsd-mouse-plugin.c \ + gsd-mouse-manager.h \ + gsd-mouse-manager.c + +libmouse_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + -DLIBEXECDIR=\""$(libexecdir)"\" \ + $(AM_CPPFLAGS) + +libmouse_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libmouse_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) + +libmouse_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(X11_LIBS) \ + $(XINPUT_LIBS) + +plugin_in_files = mouse.mate-settings-plugin.in + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) + +libexec_PROGRAMS = gsd-locate-pointer + +gsd_locate_pointer_SOURCES = \ + gsd-locate-pointer.h \ + gsd-locate-pointer.c \ + gsd-timeline.h \ + gsd-timeline.c + +gsd_locate_pointer_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +gsd_locate_pointer_LDADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(X11_LIBS) \ + -lm + +EXTRA_DIST = $(plugin_in_files) +CLEANFILES = $(plugin_DATA) +DISTCLEANFILES = $(plugin_DATA) + +@GSD_INTLTOOL_PLUGIN_RULE@ diff --git a/plugins/mouse/Makefile.in b/plugins/mouse/Makefile.in new file mode 100644 index 0000000..c4bc74c --- /dev/null +++ b/plugins/mouse/Makefile.in @@ -0,0 +1,768 @@ +# 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@ +libexec_PROGRAMS = gsd-locate-pointer$(EXEEXT) +subdir = plugins/mouse +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)$(libexecdir)" \ + "$(DESTDIR)$(plugindir)" +LTLIBRARIES = $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +libmouse_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_libmouse_la_OBJECTS = libmouse_la-gsd-mouse-plugin.lo \ + libmouse_la-gsd-mouse-manager.lo +libmouse_la_OBJECTS = $(am_libmouse_la_OBJECTS) +libmouse_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libmouse_la_CFLAGS) \ + $(CFLAGS) $(libmouse_la_LDFLAGS) $(LDFLAGS) -o $@ +PROGRAMS = $(libexec_PROGRAMS) +am_gsd_locate_pointer_OBJECTS = \ + gsd_locate_pointer-gsd-locate-pointer.$(OBJEXT) \ + gsd_locate_pointer-gsd-timeline.$(OBJEXT) +gsd_locate_pointer_OBJECTS = $(am_gsd_locate_pointer_OBJECTS) +gsd_locate_pointer_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +gsd_locate_pointer_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(gsd_locate_pointer_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 = $(libmouse_la_SOURCES) $(gsd_locate_pointer_SOURCES) +DIST_SOURCES = $(libmouse_la_SOURCES) $(gsd_locate_pointer_SOURCES) +DATA = $(plugin_DATA) +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@ +plugin_LTLIBRARIES = libmouse.la +libmouse_la_SOURCES = \ + gsd-mouse-plugin.h \ + gsd-mouse-plugin.c \ + gsd-mouse-manager.h \ + gsd-mouse-manager.c + +libmouse_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + -DLIBEXECDIR=\""$(libexecdir)"\" \ + $(AM_CPPFLAGS) + +libmouse_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libmouse_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) + +libmouse_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(X11_LIBS) \ + $(XINPUT_LIBS) + +plugin_in_files = mouse.mate-settings-plugin.in +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) +gsd_locate_pointer_SOURCES = \ + gsd-locate-pointer.h \ + gsd-locate-pointer.c \ + gsd-timeline.h \ + gsd-timeline.c + +gsd_locate_pointer_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +gsd_locate_pointer_LDADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(X11_LIBS) \ + -lm + +EXTRA_DIST = $(plugin_in_files) +CLEANFILES = $(plugin_DATA) +DISTCLEANFILES = $(plugin_DATA) +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/mouse/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plugins/mouse/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 +libmouse.la: $(libmouse_la_OBJECTS) $(libmouse_la_DEPENDENCIES) + $(libmouse_la_LINK) -rpath $(plugindir) $(libmouse_la_OBJECTS) $(libmouse_la_LIBADD) $(LIBS) +install-libexecPROGRAMS: $(libexec_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(libexecdir)" || $(MKDIR_P) "$(DESTDIR)$(libexecdir)" + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(libexecdir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-libexecPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(libexecdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(libexecdir)" && rm -f $$files + +clean-libexecPROGRAMS: + @list='$(libexec_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 +gsd-locate-pointer$(EXEEXT): $(gsd_locate_pointer_OBJECTS) $(gsd_locate_pointer_DEPENDENCIES) + @rm -f gsd-locate-pointer$(EXEEXT) + $(gsd_locate_pointer_LINK) $(gsd_locate_pointer_OBJECTS) $(gsd_locate_pointer_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsd_locate_pointer-gsd-locate-pointer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsd_locate_pointer-gsd-timeline.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmouse_la-gsd-mouse-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmouse_la-gsd-mouse-plugin.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 $@ $< + +libmouse_la-gsd-mouse-plugin.lo: gsd-mouse-plugin.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmouse_la_CPPFLAGS) $(CPPFLAGS) $(libmouse_la_CFLAGS) $(CFLAGS) -MT libmouse_la-gsd-mouse-plugin.lo -MD -MP -MF $(DEPDIR)/libmouse_la-gsd-mouse-plugin.Tpo -c -o libmouse_la-gsd-mouse-plugin.lo `test -f 'gsd-mouse-plugin.c' || echo '$(srcdir)/'`gsd-mouse-plugin.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libmouse_la-gsd-mouse-plugin.Tpo $(DEPDIR)/libmouse_la-gsd-mouse-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-mouse-plugin.c' object='libmouse_la-gsd-mouse-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) $(libmouse_la_CPPFLAGS) $(CPPFLAGS) $(libmouse_la_CFLAGS) $(CFLAGS) -c -o libmouse_la-gsd-mouse-plugin.lo `test -f 'gsd-mouse-plugin.c' || echo '$(srcdir)/'`gsd-mouse-plugin.c + +libmouse_la-gsd-mouse-manager.lo: gsd-mouse-manager.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmouse_la_CPPFLAGS) $(CPPFLAGS) $(libmouse_la_CFLAGS) $(CFLAGS) -MT libmouse_la-gsd-mouse-manager.lo -MD -MP -MF $(DEPDIR)/libmouse_la-gsd-mouse-manager.Tpo -c -o libmouse_la-gsd-mouse-manager.lo `test -f 'gsd-mouse-manager.c' || echo '$(srcdir)/'`gsd-mouse-manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libmouse_la-gsd-mouse-manager.Tpo $(DEPDIR)/libmouse_la-gsd-mouse-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-mouse-manager.c' object='libmouse_la-gsd-mouse-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) $(libmouse_la_CPPFLAGS) $(CPPFLAGS) $(libmouse_la_CFLAGS) $(CFLAGS) -c -o libmouse_la-gsd-mouse-manager.lo `test -f 'gsd-mouse-manager.c' || echo '$(srcdir)/'`gsd-mouse-manager.c + +gsd_locate_pointer-gsd-locate-pointer.o: gsd-locate-pointer.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gsd_locate_pointer_CFLAGS) $(CFLAGS) -MT gsd_locate_pointer-gsd-locate-pointer.o -MD -MP -MF $(DEPDIR)/gsd_locate_pointer-gsd-locate-pointer.Tpo -c -o gsd_locate_pointer-gsd-locate-pointer.o `test -f 'gsd-locate-pointer.c' || echo '$(srcdir)/'`gsd-locate-pointer.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gsd_locate_pointer-gsd-locate-pointer.Tpo $(DEPDIR)/gsd_locate_pointer-gsd-locate-pointer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-locate-pointer.c' object='gsd_locate_pointer-gsd-locate-pointer.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gsd_locate_pointer_CFLAGS) $(CFLAGS) -c -o gsd_locate_pointer-gsd-locate-pointer.o `test -f 'gsd-locate-pointer.c' || echo '$(srcdir)/'`gsd-locate-pointer.c + +gsd_locate_pointer-gsd-locate-pointer.obj: gsd-locate-pointer.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gsd_locate_pointer_CFLAGS) $(CFLAGS) -MT gsd_locate_pointer-gsd-locate-pointer.obj -MD -MP -MF $(DEPDIR)/gsd_locate_pointer-gsd-locate-pointer.Tpo -c -o gsd_locate_pointer-gsd-locate-pointer.obj `if test -f 'gsd-locate-pointer.c'; then $(CYGPATH_W) 'gsd-locate-pointer.c'; else $(CYGPATH_W) '$(srcdir)/gsd-locate-pointer.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gsd_locate_pointer-gsd-locate-pointer.Tpo $(DEPDIR)/gsd_locate_pointer-gsd-locate-pointer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-locate-pointer.c' object='gsd_locate_pointer-gsd-locate-pointer.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gsd_locate_pointer_CFLAGS) $(CFLAGS) -c -o gsd_locate_pointer-gsd-locate-pointer.obj `if test -f 'gsd-locate-pointer.c'; then $(CYGPATH_W) 'gsd-locate-pointer.c'; else $(CYGPATH_W) '$(srcdir)/gsd-locate-pointer.c'; fi` + +gsd_locate_pointer-gsd-timeline.o: gsd-timeline.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gsd_locate_pointer_CFLAGS) $(CFLAGS) -MT gsd_locate_pointer-gsd-timeline.o -MD -MP -MF $(DEPDIR)/gsd_locate_pointer-gsd-timeline.Tpo -c -o gsd_locate_pointer-gsd-timeline.o `test -f 'gsd-timeline.c' || echo '$(srcdir)/'`gsd-timeline.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gsd_locate_pointer-gsd-timeline.Tpo $(DEPDIR)/gsd_locate_pointer-gsd-timeline.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-timeline.c' object='gsd_locate_pointer-gsd-timeline.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gsd_locate_pointer_CFLAGS) $(CFLAGS) -c -o gsd_locate_pointer-gsd-timeline.o `test -f 'gsd-timeline.c' || echo '$(srcdir)/'`gsd-timeline.c + +gsd_locate_pointer-gsd-timeline.obj: gsd-timeline.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gsd_locate_pointer_CFLAGS) $(CFLAGS) -MT gsd_locate_pointer-gsd-timeline.obj -MD -MP -MF $(DEPDIR)/gsd_locate_pointer-gsd-timeline.Tpo -c -o gsd_locate_pointer-gsd-timeline.obj `if test -f 'gsd-timeline.c'; then $(CYGPATH_W) 'gsd-timeline.c'; else $(CYGPATH_W) '$(srcdir)/gsd-timeline.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gsd_locate_pointer-gsd-timeline.Tpo $(DEPDIR)/gsd_locate_pointer-gsd-timeline.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-timeline.c' object='gsd_locate_pointer-gsd-timeline.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gsd_locate_pointer_CFLAGS) $(CFLAGS) -c -o gsd_locate_pointer-gsd-timeline.obj `if test -f 'gsd-timeline.c'; then $(CYGPATH_W) 'gsd-timeline.c'; else $(CYGPATH_W) '$(srcdir)/gsd-timeline.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +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 + +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) $(PROGRAMS) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -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." +clean: clean-am + +clean-am: clean-generic clean-libexecPROGRAMS clean-libtool \ + clean-pluginLTLIBRARIES 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-pluginDATA install-pluginLTLIBRARIES + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libexecPROGRAMS + +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: uninstall-libexecPROGRAMS uninstall-pluginDATA \ + uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libexecPROGRAMS clean-libtool clean-pluginLTLIBRARIES \ + 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-libexecPROGRAMS install-man \ + install-pdf install-pdf-am install-pluginDATA \ + install-pluginLTLIBRARIES 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 \ + uninstall-libexecPROGRAMS uninstall-pluginDATA \ + uninstall-pluginLTLIBRARIES + + +@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/mouse/gsd-locate-pointer.c b/plugins/mouse/gsd-locate-pointer.c new file mode 100644 index 0000000..acb2445 --- /dev/null +++ b/plugins/mouse/gsd-locate-pointer.c @@ -0,0 +1,504 @@ +/* gsd-locate-pointer.c + * + * Copyright (C) 2008 Carlos Garnacho <[email protected]> + * + * 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 <gtk/gtk.h> +#include "gsd-timeline.h" +#include "gsd-locate-pointer.h" + +#include <gdk/gdkkeysyms.h> +#include <gdk/gdkx.h> +#include <X11/keysym.h> + +#define ANIMATION_LENGTH 750 +#define WINDOW_SIZE 101 +#define N_CIRCLES 4 + +/* All circles are supposed to be moving when progress + * reaches 0.5, and each of them are supposed to long + * for half of the progress, hence the need of 0.5 to + * get the circles interval, and the multiplication + * by 2 to know a circle progress */ +#define CIRCLES_PROGRESS_INTERVAL (0.5 / N_CIRCLES) +#define CIRCLE_PROGRESS(p) (MIN (1., ((gdouble) (p) * 2.))) + +typedef struct GsdLocatePointerData GsdLocatePointerData; + +struct GsdLocatePointerData +{ + GsdTimeline *timeline; + GtkWidget *widget; + GdkWindow *window; + + gdouble progress; +}; + +static GsdLocatePointerData *data = NULL; + +static void +locate_pointer_paint (GsdLocatePointerData *data, + cairo_t *cr, + gboolean composite) +{ + GdkColor color; + gdouble progress, circle_progress; + gint width, height, i; + GtkStyle *style; + + progress = data->progress; + + #if GTK_CHECK_VERSION(3, 0, 0) + width = gdk_window_get_width(GDK_WINDOW(data->window)); + height = gdk_window_get_height(GDK_WINDOW(data->window)); + #else + gdk_drawable_get_size(data->window, &width, &height); + #endif + + style = gtk_widget_get_style (data->widget); + color = style->bg[GTK_STATE_SELECTED]; + + cairo_set_source_rgba (cr, 1., 1., 1., 0.); + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + cairo_paint (cr); + + for (i = 0; i <= N_CIRCLES; i++) + { + if (progress < 0.) + break; + + circle_progress = MIN (1., (progress * 2)); + progress -= CIRCLES_PROGRESS_INTERVAL; + + if (circle_progress >= 1.) + continue; + + if (composite) + { + cairo_set_source_rgba (cr, + color.red / 65535., + color.green / 65535., + color.blue / 65535., + 1 - circle_progress); + cairo_arc (cr, + width / 2, + height / 2, + circle_progress * width / 2, + 0, 2 * G_PI); + + cairo_fill (cr); + cairo_stroke (cr); + } + else + { + cairo_set_source_rgb (cr, 0., 0., 0.); + cairo_set_line_width (cr, 3.); + cairo_arc (cr, + width / 2, + height / 2, + circle_progress * width / 2, + 0, 2 * G_PI); + cairo_stroke (cr); + + cairo_set_source_rgb (cr, 1., 1., 1.); + cairo_set_line_width (cr, 1.); + cairo_arc (cr, + width / 2, + height / 2, + circle_progress * width / 2, + 0, 2 * G_PI); + cairo_stroke (cr); + } + } +} + +static gboolean +locate_pointer_expose (GtkWidget *widget, + GdkEventExpose *event, + gpointer user_data) +{ + GsdLocatePointerData *data = (GsdLocatePointerData *) user_data; + cairo_t *cr; + + if (event->window != data->window) + return FALSE; + + cr = gdk_cairo_create (data->window); + locate_pointer_paint (data, cr, gtk_widget_is_composited (data->widget)); + cairo_destroy (cr); + + return TRUE; +} + +static void +update_shape (GsdLocatePointerData *data) +{ + cairo_t *cr; + GdkBitmap *mask; + + mask = gdk_pixmap_new (data->window, WINDOW_SIZE, WINDOW_SIZE, 1); + cr = gdk_cairo_create (mask); + locate_pointer_paint (data, cr, FALSE); + gdk_window_shape_combine_mask (data->window, mask, 0, 0); + g_object_unref (mask); + cairo_destroy (cr); +} + +static void +timeline_frame_cb (GsdTimeline *timeline, + gdouble progress, + gpointer user_data) +{ + GsdLocatePointerData *data = (GsdLocatePointerData *) user_data; + GdkScreen *screen; + gint cursor_x, cursor_y; + + if (gtk_widget_is_composited (data->widget)) + { + gdk_window_invalidate_rect (data->window, NULL, FALSE); + data->progress = progress; + } + else if (progress >= data->progress + CIRCLES_PROGRESS_INTERVAL) + { + /* only invalidate window each circle interval */ + update_shape (data); + gdk_window_invalidate_rect (data->window, NULL, FALSE); + data->progress += CIRCLES_PROGRESS_INTERVAL; + } + + screen = gdk_drawable_get_screen (data->window); + gdk_window_get_pointer (gdk_screen_get_root_window (screen), + &cursor_x, &cursor_y, NULL); + gdk_window_move (data->window, + cursor_x - WINDOW_SIZE / 2, + cursor_y - WINDOW_SIZE / 2); +} + +static void +set_transparent_shape (GdkWindow *window) +{ + GdkBitmap *mask; + cairo_t *cr; + + mask = gdk_pixmap_new (data->window, WINDOW_SIZE, WINDOW_SIZE, 1); + cr = gdk_cairo_create (mask); + + cairo_set_source_rgba (cr, 1., 1., 1., 0.); + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + cairo_paint (cr); + + gdk_window_shape_combine_mask (data->window, mask, 0, 0); + g_object_unref (mask); + cairo_destroy (cr); +} + +static void +unset_transparent_shape (GdkWindow *window) +{ + gdk_window_shape_combine_mask (data->window, NULL, 0, 0); +} + +static void +composited_changed (GtkWidget *widget, + GsdLocatePointerData *data) +{ + if (!gtk_widget_is_composited (widget)) + set_transparent_shape (data->window); + else + unset_transparent_shape (data->window); +} + +static void +timeline_finished_cb (GsdTimeline *timeline, + gpointer user_data) +{ + GsdLocatePointerData *data = (GsdLocatePointerData *) user_data; + + /* set transparent shape and hide window */ + if (!gtk_widget_is_composited (data->widget)) + set_transparent_shape (data->window); + + gdk_window_hide (data->window); +} + +static void +create_window (GsdLocatePointerData *data, + GdkScreen *screen) +{ + GdkColormap *colormap; + GdkVisual *visual; + GdkWindowAttr attributes; + + colormap = gdk_screen_get_rgba_colormap (screen); + visual = gdk_screen_get_rgba_visual (screen); + + if (!colormap) + { + colormap = gdk_screen_get_rgb_colormap (screen); + visual = gdk_screen_get_rgb_visual (screen); + } + + attributes.window_type = GDK_WINDOW_TEMP; + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.visual = visual; + attributes.colormap = colormap; + attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK; + attributes.width = 1; + attributes.height = 1; + + data->window = gdk_window_new (gdk_screen_get_root_window (screen), + &attributes, + GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP); + + gdk_window_set_user_data (data->window, data->widget); +} + +static GsdLocatePointerData * +gsd_locate_pointer_data_new (GdkScreen *screen) +{ + GsdLocatePointerData *data; + + data = g_new0 (GsdLocatePointerData, 1); + + /* this widget will never be shown, it's + * mainly used to get signals/events from + */ + data->widget = gtk_window_new (GTK_WINDOW_POPUP); + gtk_widget_realize (data->widget); + + g_signal_connect (G_OBJECT (data->widget), "expose_event", + G_CALLBACK (locate_pointer_expose), + data); + + data->timeline = gsd_timeline_new (ANIMATION_LENGTH); + g_signal_connect (data->timeline, "frame", + G_CALLBACK (timeline_frame_cb), data); + g_signal_connect (data->timeline, "finished", + G_CALLBACK (timeline_finished_cb), data); + + create_window (data, screen); + + return data; +} + +static void +move_locate_pointer_window (GsdLocatePointerData *data, + GdkScreen *screen) +{ + gint cursor_x, cursor_y; + GdkBitmap *mask; + GdkColor col; + GdkGC *gc; + + gdk_window_get_pointer (gdk_screen_get_root_window (screen), &cursor_x, &cursor_y, NULL); + + gdk_window_move_resize (data->window, + cursor_x - WINDOW_SIZE / 2, + cursor_y - WINDOW_SIZE / 2, + WINDOW_SIZE, WINDOW_SIZE); + + col.pixel = 0; + mask = gdk_pixmap_new (data->window, WINDOW_SIZE, WINDOW_SIZE, 1); + + gc = gdk_gc_new (mask); + gdk_gc_set_foreground (gc, &col); + gdk_draw_rectangle (mask, gc, TRUE, 0, 0, WINDOW_SIZE, WINDOW_SIZE); + + /* allow events to happen through the window */ + gdk_window_input_shape_combine_mask (data->window, mask, 0, 0); + + g_object_unref (mask); + g_object_unref (gc); +} + +void +gsd_locate_pointer (GdkScreen *screen) +{ + if (!data) + data = gsd_locate_pointer_data_new (screen); + + gsd_timeline_pause (data->timeline); + gsd_timeline_rewind (data->timeline); + + /* Create again the window if it is not for the current screen */ + if (gdk_screen_get_number (screen) != gdk_screen_get_number (gdk_drawable_get_screen (data->window))) + { + gdk_window_set_user_data (data->window, NULL); + gdk_window_destroy (data->window); + + create_window (data, screen); + } + + data->progress = 0.; + + g_signal_connect (data->widget, "composited-changed", + G_CALLBACK (composited_changed), data); + + move_locate_pointer_window (data, screen); + composited_changed (data->widget, data); + gdk_window_show (data->window); + + gsd_timeline_start (data->timeline); +} + + +#define KEYBOARD_GROUP_SHIFT 13 +#define KEYBOARD_GROUP_MASK ((1 << 13) | (1 << 14)) + +/* Owen magic */ +static GdkFilterReturn +filter (GdkXEvent *xevent, + GdkEvent *event, + gpointer data) +{ + XEvent *xev = (XEvent *) xevent; + guint keyval; + gint group; + + GdkScreen *screen = (GdkScreen *)data; + + if (xev->type == KeyPress || xev->type == KeyRelease) + { + /* get the keysym */ + group = (xev->xkey.state & KEYBOARD_GROUP_MASK) >> KEYBOARD_GROUP_SHIFT; + gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (), + xev->xkey.keycode, + xev->xkey.state, + group, + &keyval, + NULL, NULL, NULL); + if (keyval == GDK_Control_L || keyval == GDK_Control_R) + { + if (xev->type == KeyPress) + { + XAllowEvents (xev->xkey.display, + SyncKeyboard, + xev->xkey.time); + } + else + { + XAllowEvents (xev->xkey.display, + AsyncKeyboard, + xev->xkey.time); + gsd_locate_pointer (screen); + } + } + else + { + XAllowEvents (xev->xkey.display, + ReplayKeyboard, + xev->xkey.time); + XUngrabKeyboard (gdk_x11_get_default_xdisplay (), + xev->xkey.time); + } + } + + return GDK_FILTER_CONTINUE; +} + +static void +set_locate_pointer (void) +{ + GdkKeymapKey *keys; + GdkDisplay *display; + int n_screens; + int n_keys; + gboolean has_entries; + static const guint keyvals[] = { GDK_Control_L, GDK_Control_R }; + unsigned j; + + display = gdk_display_get_default (); + n_screens = gdk_display_get_n_screens (display); + + for (j = 0 ; j < G_N_ELEMENTS (keyvals) ; j++) + { + has_entries = gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (), + keyvals[j], + &keys, + &n_keys); + if (has_entries) + { + gint i, j; + for (i = 0; i < n_keys; i++) + { + for (j=0; j< n_screens; j++) + { + GdkScreen *screen; + Window xroot; + + screen = gdk_display_get_screen (display, j); + xroot = gdk_x11_drawable_get_xid (gdk_screen_get_root_window (screen)); + + XGrabKey (GDK_DISPLAY_XDISPLAY (display), + keys[i].keycode, + 0, + xroot, + False, + GrabModeAsync, + GrabModeSync); + XGrabKey (GDK_DISPLAY_XDISPLAY (display), + keys[i].keycode, + LockMask, + xroot, + False, + GrabModeAsync, + GrabModeSync); + XGrabKey (GDK_DISPLAY_XDISPLAY (display), + keys[i].keycode, + Mod2Mask, + xroot, + False, + GrabModeAsync, + GrabModeSync); + XGrabKey (GDK_DISPLAY_XDISPLAY (display), + keys[i].keycode, + Mod4Mask, + xroot, + False, + GrabModeAsync, + GrabModeSync); + } + } + + g_free (keys); + + for (i = 0; i < n_screens; i++) + { + GdkScreen *screen; + + screen = gdk_display_get_screen (display, i); + gdk_window_add_filter (gdk_screen_get_root_window (screen), + filter, + screen); + } + } + } +} + + +int +main (int argc, char *argv[]) +{ + gtk_init (&argc, &argv); + + set_locate_pointer (); + + gtk_main (); + + return 0; +} + diff --git a/plugins/mouse/gsd-locate-pointer.h b/plugins/mouse/gsd-locate-pointer.h new file mode 100644 index 0000000..3b261a5 --- /dev/null +++ b/plugins/mouse/gsd-locate-pointer.h @@ -0,0 +1,24 @@ +/* + * Copyright � 2001 Jonathan Blandford <[email protected]> + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * Authors: Jonathan Blandford + */ + +#ifndef LOCATE_POINTER_H +#define LOCATE_POINTER_H + +#include <gdk/gdk.h> + +void gsd_locate_pointer (GdkScreen *screen); + +#endif diff --git a/plugins/mouse/gsd-mouse-manager.c b/plugins/mouse/gsd-mouse-manager.c new file mode 100644 index 0000000..124653a --- /dev/null +++ b/plugins/mouse/gsd-mouse-manager.c @@ -0,0 +1,1124 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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 <sys/types.h> +#include <sys/wait.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <math.h> + +#include <locale.h> + +#include <glib.h> +#include <glib/gi18n.h> +#include <gtk/gtk.h> +#include <gdk/gdk.h> +#include <gdk/gdkx.h> +#include <gdk/gdkkeysyms.h> +#include <X11/keysym.h> +#include <X11/Xatom.h> + +#ifdef HAVE_X11_EXTENSIONS_XINPUT_H +#include <X11/extensions/XInput.h> +#include <X11/extensions/XIproto.h> +#endif +#include <mateconf/mateconf.h> +#include <mateconf/mateconf-client.h> + +#include "mate-settings-profile.h" +#include "gsd-mouse-manager.h" + +#define GSD_MOUSE_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_MOUSE_MANAGER, GsdMouseManagerPrivate)) + +#define MATECONF_MOUSE_DIR "/desktop/mate/peripherals/mouse" +#define MATECONF_MOUSE_A11Y_DIR "/desktop/mate/accessibility/mouse" +#define MATECONF_TOUCHPAD_DIR "/desktop/mate/peripherals/touchpad" + +#define KEY_LEFT_HANDED MATECONF_MOUSE_DIR "/left_handed" +#define KEY_MOTION_ACCELERATION MATECONF_MOUSE_DIR "/motion_acceleration" +#define KEY_MOTION_THRESHOLD MATECONF_MOUSE_DIR "/motion_threshold" +#define KEY_LOCATE_POINTER MATECONF_MOUSE_DIR "/locate_pointer" +#define KEY_DWELL_ENABLE MATECONF_MOUSE_A11Y_DIR "/dwell_enable" +#define KEY_DELAY_ENABLE MATECONF_MOUSE_A11Y_DIR "/delay_enable" +#define KEY_TOUCHPAD_DISABLE_W_TYPING MATECONF_TOUCHPAD_DIR "/disable_while_typing" +#ifdef HAVE_X11_EXTENSIONS_XINPUT_H +#define KEY_TAP_TO_CLICK MATECONF_TOUCHPAD_DIR "/tap_to_click" +#define KEY_SCROLL_METHOD MATECONF_TOUCHPAD_DIR "/scroll_method" +#define KEY_PAD_HORIZ_SCROLL MATECONF_TOUCHPAD_DIR "/horiz_scroll_enabled" +#define KEY_TOUCHPAD_ENABLED MATECONF_TOUCHPAD_DIR "/touchpad_enabled" +#endif + +struct GsdMouseManagerPrivate +{ + guint notify; + guint notify_a11y; + guint notify_touchpad; + + gboolean mousetweaks_daemon_running; + gboolean syndaemon_spawned; + GPid syndaemon_pid; + gboolean locate_pointer_spawned; + GPid locate_pointer_pid; +}; + +static void gsd_mouse_manager_class_init (GsdMouseManagerClass *klass); +static void gsd_mouse_manager_init (GsdMouseManager *mouse_manager); +static void gsd_mouse_manager_finalize (GObject *object); +static void set_mouse_settings (GsdMouseManager *manager); +#ifdef HAVE_X11_EXTENSIONS_XINPUT_H +static int set_tap_to_click (gboolean state, gboolean left_handed); +static XDevice* device_is_touchpad (XDeviceInfo deviceinfo); +#endif + +G_DEFINE_TYPE (GsdMouseManager, gsd_mouse_manager, G_TYPE_OBJECT) + +static gpointer manager_object = NULL; + +static void +gsd_mouse_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GsdMouseManager *self; + + self = GSD_MOUSE_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gsd_mouse_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GsdMouseManager *self; + + self = GSD_MOUSE_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +gsd_mouse_manager_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GsdMouseManager *mouse_manager; + GsdMouseManagerClass *klass; + + klass = GSD_MOUSE_MANAGER_CLASS (g_type_class_peek (GSD_TYPE_MOUSE_MANAGER)); + + mouse_manager = GSD_MOUSE_MANAGER (G_OBJECT_CLASS (gsd_mouse_manager_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + + return G_OBJECT (mouse_manager); +} + +static void +gsd_mouse_manager_dispose (GObject *object) +{ + GsdMouseManager *mouse_manager; + + mouse_manager = GSD_MOUSE_MANAGER (object); + + G_OBJECT_CLASS (gsd_mouse_manager_parent_class)->dispose (object); +} + +static void +gsd_mouse_manager_class_init (GsdMouseManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gsd_mouse_manager_get_property; + object_class->set_property = gsd_mouse_manager_set_property; + object_class->constructor = gsd_mouse_manager_constructor; + object_class->dispose = gsd_mouse_manager_dispose; + object_class->finalize = gsd_mouse_manager_finalize; + + g_type_class_add_private (klass, sizeof (GsdMouseManagerPrivate)); +} + + +#ifdef HAVE_X11_EXTENSIONS_XINPUT_H +static gboolean +supports_xinput_devices (void) +{ + gint op_code, event, error; + + return XQueryExtension (GDK_DISPLAY (), + "XInputExtension", + &op_code, + &event, + &error); +} +#endif + +static void +configure_button_layout (guchar *buttons, + gint n_buttons, + gboolean left_handed) +{ + const gint left_button = 1; + gint right_button; + gint i; + + /* if the button is higher than 2 (3rd button) then it's + * probably one direction of a scroll wheel or something else + * uninteresting + */ + right_button = MIN (n_buttons, 3); + + /* If we change things we need to make sure we only swap buttons. + * If we end up with multiple physical buttons assigned to the same + * logical button the server will complain. This code assumes physical + * button 0 is the physical left mouse button, and that the physical + * button other than 0 currently assigned left_button or right_button + * is the physical right mouse button. + */ + + /* check if the current mapping satisfies the above assumptions */ + if (buttons[left_button - 1] != left_button && + buttons[left_button - 1] != right_button) + /* The current mapping is weird. Swapping buttons is probably not a + * good idea. + */ + return; + + /* check if we are left_handed and currently not swapped */ + if (left_handed && buttons[left_button - 1] == left_button) { + /* find the right button */ + for (i = 0; i < n_buttons; i++) { + if (buttons[i] == right_button) { + buttons[i] = left_button; + break; + } + } + /* swap the buttons */ + buttons[left_button - 1] = right_button; + } + /* check if we are not left_handed but are swapped */ + else if (!left_handed && buttons[left_button - 1] == right_button) { + /* find the right button */ + for (i = 0; i < n_buttons; i++) { + if (buttons[i] == left_button) { + buttons[i] = right_button; + break; + } + } + /* swap the buttons */ + buttons[left_button - 1] = left_button; + } +} + +#ifdef HAVE_X11_EXTENSIONS_XINPUT_H +static gboolean +xinput_device_has_buttons (XDeviceInfo *device_info) +{ + int i; + XAnyClassInfo *class_info; + + class_info = device_info->inputclassinfo; + for (i = 0; i < device_info->num_classes; i++) { + if (class_info->class == ButtonClass) { + XButtonInfo *button_info; + + button_info = (XButtonInfo *) class_info; + if (button_info->num_buttons > 0) + return TRUE; + } + + class_info = (XAnyClassInfo *) (((guchar *) class_info) + + class_info->length); + } + return FALSE; +} + +static gboolean +touchpad_has_single_button (XDevice *device) +{ + Atom type, prop; + int format; + unsigned long nitems, bytes_after; + unsigned char *data; + gboolean is_single_button = FALSE; + int rc; + + prop = XInternAtom (GDK_DISPLAY (), "Synaptics Capabilities", False); + if (!prop) + return FALSE; + + gdk_error_trap_push (); + rc = XGetDeviceProperty (GDK_DISPLAY (), device, prop, 0, 1, False, + XA_INTEGER, &type, &format, &nitems, + &bytes_after, &data); + if (rc == Success && type == XA_INTEGER && format == 8 && nitems >= 3) + is_single_button = (data[0] == 1 && data[1] == 0 && data[2] == 0); + + if (rc == Success) + XFree (data); + + gdk_error_trap_pop (); + + return is_single_button; +} + + +static void +set_xinput_devices_left_handed (gboolean left_handed) +{ + XDeviceInfo *device_info; + gint n_devices; + guchar *buttons; + gsize buttons_capacity = 16; + gint n_buttons; + gint i; + + device_info = XListInputDevices (GDK_DISPLAY (), &n_devices); + + if (n_devices > 0) + buttons = g_new (guchar, buttons_capacity); + else + buttons = NULL; + + for (i = 0; i < n_devices; i++) { + XDevice *device = NULL; + + if ((device_info[i].use == IsXPointer) || + (device_info[i].use == IsXKeyboard) || + (!xinput_device_has_buttons (&device_info[i]))) + continue; + + /* If the device is a touchpad, swap tap buttons + * around too, otherwise a tap would be a right-click */ + device = device_is_touchpad (device_info[i]); + if (device != NULL) { + MateConfClient *client = mateconf_client_get_default (); + gboolean tap = mateconf_client_get_bool (client, KEY_TAP_TO_CLICK, NULL); + gboolean single_button = touchpad_has_single_button (device); + + if (tap && !single_button) + set_tap_to_click (tap, left_handed); + XCloseDevice (GDK_DISPLAY (), device); + g_object_unref (client); + + if (single_button) + continue; + } + + gdk_error_trap_push (); + + device = XOpenDevice (GDK_DISPLAY (), device_info[i].id); + + if ((gdk_error_trap_pop () != 0) || + (device == NULL)) + continue; + + n_buttons = XGetDeviceButtonMapping (GDK_DISPLAY (), device, + buttons, + buttons_capacity); + + while (n_buttons > buttons_capacity) { + buttons_capacity = n_buttons; + buttons = (guchar *) g_realloc (buttons, + buttons_capacity * sizeof (guchar)); + + n_buttons = XGetDeviceButtonMapping (GDK_DISPLAY (), device, + buttons, + buttons_capacity); + } + + configure_button_layout (buttons, n_buttons, left_handed); + + XSetDeviceButtonMapping (GDK_DISPLAY (), device, buttons, n_buttons); + XCloseDevice (GDK_DISPLAY (), device); + } + g_free (buttons); + + if (device_info != NULL) + XFreeDeviceList (device_info); +} + +static GdkFilterReturn +devicepresence_filter (GdkXEvent *xevent, + GdkEvent *event, + gpointer data) +{ + XEvent *xev = (XEvent *) xevent; + XEventClass class_presence; + int xi_presence; + + DevicePresence (gdk_x11_get_default_xdisplay (), xi_presence, class_presence); + + if (xev->type == xi_presence) + { + XDevicePresenceNotifyEvent *dpn = (XDevicePresenceNotifyEvent *) xev; + if (dpn->devchange == DeviceEnabled) + set_mouse_settings ((GsdMouseManager *) data); + } + return GDK_FILTER_CONTINUE; +} + +static void +set_devicepresence_handler (GsdMouseManager *manager) +{ + Display *display; + XEventClass class_presence; + int xi_presence; + + if (!supports_xinput_devices ()) + return; + + display = gdk_x11_get_default_xdisplay (); + + gdk_error_trap_push (); + DevicePresence (display, xi_presence, class_presence); + XSelectExtensionEvent (display, + RootWindow (display, DefaultScreen (display)), + &class_presence, 1); + + gdk_flush (); + if (!gdk_error_trap_pop ()) + gdk_window_add_filter (NULL, devicepresence_filter, manager); +} +#endif + +static void +set_left_handed (GsdMouseManager *manager, + gboolean left_handed) +{ + guchar *buttons ; + gsize buttons_capacity = 16; + gint n_buttons, i; + +#ifdef HAVE_X11_EXTENSIONS_XINPUT_H + if (supports_xinput_devices ()) { + /* When XInput support is available, never set the + * button ordering on the core pointer as that would + * revert the changes we make on the devices themselves */ + set_xinput_devices_left_handed (left_handed); + return; + } +#endif + + buttons = g_new (guchar, buttons_capacity); + n_buttons = XGetPointerMapping (GDK_DISPLAY (), + buttons, + (gint) buttons_capacity); + while (n_buttons > buttons_capacity) { + buttons_capacity = n_buttons; + buttons = (guchar *) g_realloc (buttons, + buttons_capacity * sizeof (guchar)); + + n_buttons = XGetPointerMapping (GDK_DISPLAY (), + buttons, + (gint) buttons_capacity); + } + + configure_button_layout (buttons, n_buttons, left_handed); + + /* X refuses to change the mapping while buttons are engaged, + * so if this is the case we'll retry a few times + */ + for (i = 0; + i < 20 && XSetPointerMapping (GDK_DISPLAY (), buttons, n_buttons) == MappingBusy; + ++i) { + g_usleep (300); + } + + g_free (buttons); +} + +static void +set_motion_acceleration (GsdMouseManager *manager, + gfloat motion_acceleration) +{ + gint numerator, denominator; + + if (motion_acceleration >= 1.0) { + /* we want to get the acceleration, with a resolution of 0.5 + */ + if ((motion_acceleration - floor (motion_acceleration)) < 0.25) { + numerator = floor (motion_acceleration); + denominator = 1; + } else if ((motion_acceleration - floor (motion_acceleration)) < 0.5) { + numerator = ceil (2.0 * motion_acceleration); + denominator = 2; + } else if ((motion_acceleration - floor (motion_acceleration)) < 0.75) { + numerator = floor (2.0 *motion_acceleration); + denominator = 2; + } else { + numerator = ceil (motion_acceleration); + denominator = 1; + } + } else if (motion_acceleration < 1.0 && motion_acceleration > 0) { + /* This we do to 1/10ths */ + numerator = floor (motion_acceleration * 10) + 1; + denominator= 10; + } else { + numerator = -1; + denominator = -1; + } + + XChangePointerControl (GDK_DISPLAY (), True, False, + numerator, denominator, + 0); +} + +static void +set_motion_threshold (GsdMouseManager *manager, + int motion_threshold) +{ + XChangePointerControl (GDK_DISPLAY (), False, True, + 0, 0, motion_threshold); +} + +#ifdef HAVE_X11_EXTENSIONS_XINPUT_H +static XDevice* +device_is_touchpad (XDeviceInfo deviceinfo) +{ + XDevice *device; + Atom realtype, prop; + int realformat; + unsigned long nitems, bytes_after; + unsigned char *data; + + if (deviceinfo.type != XInternAtom (GDK_DISPLAY (), XI_TOUCHPAD, False)) + return NULL; + + prop = XInternAtom (GDK_DISPLAY (), "Synaptics Off", False); + if (!prop) + return NULL; + + gdk_error_trap_push (); + device = XOpenDevice (GDK_DISPLAY (), deviceinfo.id); + if (gdk_error_trap_pop () || (device == NULL)) + return NULL; + + gdk_error_trap_push (); + if ((XGetDeviceProperty (GDK_DISPLAY (), device, prop, 0, 1, False, + XA_INTEGER, &realtype, &realformat, &nitems, + &bytes_after, &data) == Success) && (realtype != None)) { + gdk_error_trap_pop (); + XFree (data); + return device; + } + gdk_error_trap_pop (); + + XCloseDevice (GDK_DISPLAY (), device); + return NULL; +} +#endif + +static int +set_disable_w_typing (GsdMouseManager *manager, gboolean state) +{ + + if (state) { + GError *error = NULL; + char *args[5]; + + if (manager->priv->syndaemon_spawned) + return 0; + + args[0] = "syndaemon"; + args[1] = "-i"; + args[2] = "0.5"; + args[3] = "-k"; + args[4] = NULL; + + if (!g_find_program_in_path (args[0])) + return 0; + + g_spawn_async (g_get_home_dir (), args, NULL, + G_SPAWN_SEARCH_PATH, NULL, NULL, + &manager->priv->syndaemon_pid, &error); + + manager->priv->syndaemon_spawned = (error == NULL); + + if (error) { + MateConfClient *client; + client = mateconf_client_get_default (); + mateconf_client_set_bool (client, KEY_TOUCHPAD_DISABLE_W_TYPING, FALSE, NULL); + g_object_unref (client); + g_error_free (error); + } + + } else if (manager->priv->syndaemon_spawned) + { + kill (manager->priv->syndaemon_pid, SIGHUP); + g_spawn_close_pid (manager->priv->syndaemon_pid); + manager->priv->syndaemon_spawned = FALSE; + } + + return 0; +} + +#ifdef HAVE_X11_EXTENSIONS_XINPUT_H +static int +set_tap_to_click (gboolean state, gboolean left_handed) +{ + int numdevices, i, format, rc; + unsigned long nitems, bytes_after; + XDeviceInfo *devicelist = XListInputDevices (GDK_DISPLAY (), &numdevices); + XDevice * device; + unsigned char* data; + Atom prop, type; + + if (devicelist == NULL) + return 0; + + prop = XInternAtom (GDK_DISPLAY (), "Synaptics Tap Action", False); + + if (!prop) + return 0; + + for (i = 0; i < numdevices; i++) { + if ((device = device_is_touchpad (devicelist[i]))) { + gdk_error_trap_push (); + rc = XGetDeviceProperty (GDK_DISPLAY (), device, prop, 0, 2, + False, XA_INTEGER, &type, &format, &nitems, + &bytes_after, &data); + + if (rc == Success && type == XA_INTEGER && format == 8 && nitems >= 7) + { + /* Set RLM mapping for 1/2/3 fingers*/ + data[4] = (state) ? ((left_handed) ? 3 : 1) : 0; + data[5] = (state) ? ((left_handed) ? 1 : 3) : 0; + data[6] = (state) ? 2 : 0; + XChangeDeviceProperty (GDK_DISPLAY (), device, prop, XA_INTEGER, 8, + PropModeReplace, data, nitems); + } + + if (rc == Success) + XFree (data); + XCloseDevice (GDK_DISPLAY (), device); + if (gdk_error_trap_pop ()) { + g_warning ("Error in setting tap to click on \"%s\"", devicelist[i].name); + continue; + } + } + } + + XFreeDeviceList (devicelist); + return 0; +} + +static int +set_horiz_scroll (gboolean state) +{ + int numdevices, i, rc; + XDeviceInfo *devicelist = XListInputDevices (GDK_DISPLAY (), &numdevices); + XDevice *device; + Atom act_type, prop_edge, prop_twofinger; + int act_format; + unsigned long nitems, bytes_after; + unsigned char *data; + + if (devicelist == NULL) + return 0; + + prop_edge = XInternAtom (GDK_DISPLAY (), "Synaptics Edge Scrolling", False); + prop_twofinger = XInternAtom (GDK_DISPLAY (), "Synaptics Two-Finger Scrolling", False); + + if (!prop_edge || !prop_twofinger) + return 0; + + for (i = 0; i < numdevices; i++) { + if ((device = device_is_touchpad (devicelist[i]))) { + gdk_error_trap_push (); + rc = XGetDeviceProperty (GDK_DISPLAY (), device, + prop_edge, 0, 1, False, + XA_INTEGER, &act_type, &act_format, &nitems, + &bytes_after, &data); + if (rc == Success && act_type == XA_INTEGER && + act_format == 8 && nitems >= 2) { + data[1] = (state && data[0]); + XChangeDeviceProperty (GDK_DISPLAY (), device, + prop_edge, XA_INTEGER, 8, + PropModeReplace, data, nitems); + } + + XFree (data); + + rc = XGetDeviceProperty (GDK_DISPLAY (), device, + prop_twofinger, 0, 1, False, + XA_INTEGER, &act_type, &act_format, &nitems, + &bytes_after, &data); + if (rc == Success && act_type == XA_INTEGER && + act_format == 8 && nitems >= 2) { + data[1] = (state && data[0]); + XChangeDeviceProperty (GDK_DISPLAY (), device, + prop_twofinger, XA_INTEGER, 8, + PropModeReplace, data, nitems); + } + + XFree (data); + XCloseDevice (GDK_DISPLAY (), device); + if (gdk_error_trap_pop ()) { + g_warning ("Error in setting horiz scroll on \"%s\"", devicelist[i].name); + continue; + } + } + } + + XFreeDeviceList (devicelist); + return 0; +} + + +/** + * Scroll methods are: 0 - disabled, 1 - edge scrolling, 2 - twofinger + * scrolling + */ +static int +set_edge_scroll (int method) +{ + int numdevices, i, rc; + XDeviceInfo *devicelist = XListInputDevices (GDK_DISPLAY (), &numdevices); + XDevice *device; + Atom act_type, prop_edge, prop_twofinger; + int act_format; + unsigned long nitems, bytes_after; + unsigned char *data; + + if (devicelist == NULL) + return 0; + + prop_edge = XInternAtom (GDK_DISPLAY (), "Synaptics Edge Scrolling", False); + prop_twofinger = XInternAtom (GDK_DISPLAY (), "Synaptics Two-Finger Scrolling", False); + + if (!prop_edge || !prop_twofinger) + return 0; + + for (i = 0; i < numdevices; i++) { + if ((device = device_is_touchpad (devicelist[i]))) { + gdk_error_trap_push (); + rc = XGetDeviceProperty (GDK_DISPLAY (), device, + prop_edge, 0, 1, False, + XA_INTEGER, &act_type, &act_format, &nitems, + &bytes_after, &data); + if (rc == Success && act_type == XA_INTEGER && + act_format == 8 && nitems >= 2) { + data[0] = (method == 1) ? 1 : 0; + XChangeDeviceProperty (GDK_DISPLAY (), device, + prop_edge, XA_INTEGER, 8, + PropModeReplace, data, nitems); + } + + XFree (data); + + rc = XGetDeviceProperty (GDK_DISPLAY (), device, + prop_twofinger, 0, 1, False, + XA_INTEGER, &act_type, &act_format, &nitems, + &bytes_after, &data); + if (rc == Success && act_type == XA_INTEGER && + act_format == 8 && nitems >= 2) { + data[0] = (method == 2) ? 1 : 0; + XChangeDeviceProperty (GDK_DISPLAY (), device, + prop_twofinger, XA_INTEGER, 8, + PropModeReplace, data, nitems); + } + + XFree (data); + XCloseDevice (GDK_DISPLAY (), device); + if (gdk_error_trap_pop ()) { + g_warning ("Error in setting edge scroll on \"%s\"", devicelist[i].name); + continue; + } + } + } + + XFreeDeviceList (devicelist); + return 0; +} + +static int +set_touchpad_enabled (gboolean state) +{ + int numdevices, i; + XDeviceInfo *devicelist = XListInputDevices (GDK_DISPLAY (), &numdevices); + XDevice *device; + Atom prop_enabled; + + if (devicelist == NULL) + return 0; + + prop_enabled = XInternAtom (GDK_DISPLAY (), "Device Enabled", False); + + if (!prop_enabled) + return 0; + + for (i = 0; i < numdevices; i++) { + if ((device = device_is_touchpad (devicelist[i]))) { + unsigned char data = state; + gdk_error_trap_push (); + XChangeDeviceProperty (GDK_DISPLAY (), device, + prop_enabled, XA_INTEGER, 8, + PropModeReplace, &data, 1); + XCloseDevice (GDK_DISPLAY (), device); + gdk_flush (); + if (gdk_error_trap_pop ()) { + g_warning ("Error %s device \"%s\"", + (state) ? "enabling" : "disabling", + devicelist[i].name); + continue; + } + } + } + + XFreeDeviceList (devicelist); + return 0; +} +#endif + +static void +set_locate_pointer (GsdMouseManager *manager, + gboolean state) +{ + if (state) { + GError *error = NULL; + char *args[2]; + + if (manager->priv->locate_pointer_spawned) + return; + + args[0] = LIBEXECDIR "/gsd-locate-pointer"; + args[1] = NULL; + + g_spawn_async (NULL, args, NULL, + 0, NULL, NULL, + &manager->priv->locate_pointer_pid, &error); + + manager->priv->locate_pointer_spawned = (error == NULL); + + if (error) { + MateConfClient *client; + client = mateconf_client_get_default (); + mateconf_client_set_bool (client, KEY_LOCATE_POINTER, FALSE, NULL); + g_object_unref (client); + g_error_free (error); + } + + } + else if (manager->priv->locate_pointer_spawned) { + kill (manager->priv->locate_pointer_pid, SIGHUP); + g_spawn_close_pid (manager->priv->locate_pointer_pid); + manager->priv->locate_pointer_spawned = FALSE; + } +} + +static void +set_mousetweaks_daemon (GsdMouseManager *manager, + gboolean dwell_enable, + gboolean delay_enable) +{ + GError *error = NULL; + gchar *comm; + gboolean run_daemon = dwell_enable || delay_enable; + + if (run_daemon || manager->priv->mousetweaks_daemon_running) + comm = g_strdup_printf ("mousetweaks %s", + run_daemon ? "" : "-s"); + else + return; + + if (run_daemon) + manager->priv->mousetweaks_daemon_running = TRUE; + + + if (! g_spawn_command_line_async (comm, &error)) { + if (error->code == G_SPAWN_ERROR_NOENT && + (dwell_enable || delay_enable)) { + GtkWidget *dialog; + MateConfClient *client; + + client = mateconf_client_get_default (); + if (dwell_enable) + mateconf_client_set_bool (client, + KEY_DWELL_ENABLE, + FALSE, NULL); + else if (delay_enable) + mateconf_client_set_bool (client, + KEY_DELAY_ENABLE, + FALSE, NULL); + g_object_unref (client); + + dialog = gtk_message_dialog_new (NULL, 0, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_OK, + _("Could not enable mouse accessibility features")); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + _("Mouse accessibility requires Mousetweaks " + "to be installed on your system.")); + gtk_window_set_title (GTK_WINDOW (dialog), + _("Mouse Preferences")); + gtk_window_set_icon_name (GTK_WINDOW (dialog), + "input-mouse"); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + } + g_error_free (error); + } + g_free (comm); +} + +static void +set_mouse_settings (GsdMouseManager *manager) +{ + MateConfClient *client = mateconf_client_get_default (); + gboolean left_handed = mateconf_client_get_bool (client, KEY_LEFT_HANDED, NULL); + + set_left_handed (manager, left_handed); + set_motion_acceleration (manager, mateconf_client_get_float (client, KEY_MOTION_ACCELERATION , NULL)); + set_motion_threshold (manager, mateconf_client_get_int (client, KEY_MOTION_THRESHOLD, NULL)); + + set_disable_w_typing (manager, mateconf_client_get_bool (client, KEY_TOUCHPAD_DISABLE_W_TYPING, NULL)); +#ifdef HAVE_X11_EXTENSIONS_XINPUT_H + set_tap_to_click (mateconf_client_get_bool (client, KEY_TAP_TO_CLICK, NULL), left_handed); + set_edge_scroll (mateconf_client_get_int (client, KEY_SCROLL_METHOD, NULL)); + set_horiz_scroll (mateconf_client_get_bool (client, KEY_PAD_HORIZ_SCROLL, NULL)); + set_touchpad_enabled (mateconf_client_get_bool (client, KEY_TOUCHPAD_ENABLED, NULL)); +#endif + + g_object_unref (client); +} + +static void +mouse_callback (MateConfClient *client, + guint cnxn_id, + MateConfEntry *entry, + GsdMouseManager *manager) +{ + if (! strcmp (entry->key, KEY_LEFT_HANDED)) { + if (entry->value->type == MATECONF_VALUE_BOOL) { + set_left_handed (manager, mateconf_value_get_bool (entry->value)); + } + } else if (! strcmp (entry->key, KEY_MOTION_ACCELERATION)) { + if (entry->value->type == MATECONF_VALUE_FLOAT) { + set_motion_acceleration (manager, mateconf_value_get_float (entry->value)); + } + } else if (! strcmp (entry->key, KEY_MOTION_THRESHOLD)) { + if (entry->value->type == MATECONF_VALUE_INT) { + set_motion_threshold (manager, mateconf_value_get_int (entry->value)); + } + } else if (! strcmp (entry->key, KEY_TOUCHPAD_DISABLE_W_TYPING)) { + if (entry->value->type == MATECONF_VALUE_BOOL) + set_disable_w_typing (manager, mateconf_value_get_bool (entry->value)); +#ifdef HAVE_X11_EXTENSIONS_XINPUT_H + } else if (! strcmp (entry->key, KEY_TAP_TO_CLICK)) { + if (entry->value->type == MATECONF_VALUE_BOOL) { + set_tap_to_click (mateconf_value_get_bool (entry->value), + mateconf_client_get_bool (client, KEY_LEFT_HANDED, NULL)); + } + } else if (! strcmp (entry->key, KEY_SCROLL_METHOD)) { + if (entry->value->type == MATECONF_VALUE_INT) { + set_edge_scroll (mateconf_value_get_int (entry->value)); + set_horiz_scroll (mateconf_client_get_bool (client, KEY_PAD_HORIZ_SCROLL, NULL)); + } + } else if (! strcmp (entry->key, KEY_PAD_HORIZ_SCROLL)) { + if (entry->value->type == MATECONF_VALUE_BOOL) + set_horiz_scroll (mateconf_value_get_bool (entry->value)); +#endif + } else if (! strcmp (entry->key, KEY_LOCATE_POINTER)) { + if (entry->value->type == MATECONF_VALUE_BOOL) { + set_locate_pointer (manager, mateconf_value_get_bool (entry->value)); + } +#ifdef HAVE_X11_EXTENSIONS_XINPUT_H + } else if (! strcmp (entry->key, KEY_TOUCHPAD_ENABLED)) { + if (entry->value->type == MATECONF_VALUE_BOOL) { + set_touchpad_enabled (mateconf_value_get_bool (entry->value)); + } +#endif + } else if (! strcmp (entry->key, KEY_DWELL_ENABLE)) { + if (entry->value->type == MATECONF_VALUE_BOOL) { + set_mousetweaks_daemon (manager, + mateconf_value_get_bool (entry->value), + mateconf_client_get_bool (client, KEY_DELAY_ENABLE, NULL)); + } + } else if (! strcmp (entry->key, KEY_DELAY_ENABLE)) { + if (entry->value->type == MATECONF_VALUE_BOOL) { + set_mousetweaks_daemon (manager, + mateconf_client_get_bool (client, KEY_DWELL_ENABLE, NULL), + mateconf_value_get_bool (entry->value)); + } + } +} + +static guint +register_config_callback (GsdMouseManager *manager, + MateConfClient *client, + const char *path, + MateConfClientNotifyFunc func) +{ + mateconf_client_add_dir (client, path, MATECONF_CLIENT_PRELOAD_ONELEVEL, NULL); + return mateconf_client_notify_add (client, path, func, manager, NULL, NULL); +} + +static void +gsd_mouse_manager_init (GsdMouseManager *manager) +{ + manager->priv = GSD_MOUSE_MANAGER_GET_PRIVATE (manager); +} + +static gboolean +gsd_mouse_manager_idle_cb (GsdMouseManager *manager) +{ + MateConfClient *client; + + mate_settings_profile_start (NULL); + + client = mateconf_client_get_default (); + + manager->priv->notify = + register_config_callback (manager, + client, + MATECONF_MOUSE_DIR, + (MateConfClientNotifyFunc) mouse_callback); + manager->priv->notify_a11y = + register_config_callback (manager, + client, + MATECONF_MOUSE_A11Y_DIR, + (MateConfClientNotifyFunc) mouse_callback); + manager->priv->notify_touchpad = + register_config_callback (manager, + client, + MATECONF_TOUCHPAD_DIR, + (MateConfClientNotifyFunc) mouse_callback); + manager->priv->syndaemon_spawned = FALSE; + +#ifdef HAVE_X11_EXTENSIONS_XINPUT_H + set_devicepresence_handler (manager); +#endif + set_mouse_settings (manager); + set_locate_pointer (manager, mateconf_client_get_bool (client, KEY_LOCATE_POINTER, NULL)); + set_mousetweaks_daemon (manager, + mateconf_client_get_bool (client, KEY_DWELL_ENABLE, NULL), + mateconf_client_get_bool (client, KEY_DELAY_ENABLE, NULL)); + + set_disable_w_typing (manager, mateconf_client_get_bool (client, KEY_TOUCHPAD_DISABLE_W_TYPING, NULL)); +#ifdef HAVE_X11_EXTENSIONS_XINPUT_H + set_tap_to_click (mateconf_client_get_bool (client, KEY_TAP_TO_CLICK, NULL), + mateconf_client_get_bool (client, KEY_LEFT_HANDED, NULL)); + set_edge_scroll (mateconf_client_get_int (client, KEY_SCROLL_METHOD, NULL)); + set_horiz_scroll (mateconf_client_get_bool (client, KEY_PAD_HORIZ_SCROLL, NULL)); + set_touchpad_enabled (mateconf_client_get_bool (client, KEY_TOUCHPAD_ENABLED, NULL)); +#endif + + g_object_unref (client); + + mate_settings_profile_end (NULL); + + return FALSE; +} + +gboolean +gsd_mouse_manager_start (GsdMouseManager *manager, + GError **error) +{ + mate_settings_profile_start (NULL); + + g_idle_add ((GSourceFunc) gsd_mouse_manager_idle_cb, manager); + + mate_settings_profile_end (NULL); + + return TRUE; +} + +void +gsd_mouse_manager_stop (GsdMouseManager *manager) +{ + GsdMouseManagerPrivate *p = manager->priv; + MateConfClient *client; + + g_debug ("Stopping mouse manager"); + + client = mateconf_client_get_default (); + + if (p->notify != 0) { + mateconf_client_remove_dir (client, MATECONF_MOUSE_DIR, NULL); + mateconf_client_notify_remove (client, p->notify); + p->notify = 0; + } + + if (p->notify_a11y != 0) { + mateconf_client_remove_dir (client, MATECONF_MOUSE_A11Y_DIR, NULL); + mateconf_client_notify_remove (client, p->notify_a11y); + p->notify_a11y = 0; + } + + if (p->notify_touchpad != 0) { + mateconf_client_remove_dir (client, MATECONF_TOUCHPAD_DIR, NULL); + mateconf_client_notify_remove (client, p->notify_touchpad); + p->notify_touchpad = 0; + } + + g_object_unref (client); + + set_locate_pointer (manager, FALSE); + +#ifdef HAVE_X11_EXTENSIONS_XINPUT_H + gdk_window_remove_filter (NULL, devicepresence_filter, manager); +#endif +} + +static void +gsd_mouse_manager_finalize (GObject *object) +{ + GsdMouseManager *mouse_manager; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_MOUSE_MANAGER (object)); + + mouse_manager = GSD_MOUSE_MANAGER (object); + + g_return_if_fail (mouse_manager->priv != NULL); + + G_OBJECT_CLASS (gsd_mouse_manager_parent_class)->finalize (object); +} + +GsdMouseManager * +gsd_mouse_manager_new (void) +{ + if (manager_object != NULL) { + g_object_ref (manager_object); + } else { + manager_object = g_object_new (GSD_TYPE_MOUSE_MANAGER, NULL); + g_object_add_weak_pointer (manager_object, + (gpointer *) &manager_object); + } + + return GSD_MOUSE_MANAGER (manager_object); +} diff --git a/plugins/mouse/gsd-mouse-manager.h b/plugins/mouse/gsd-mouse-manager.h new file mode 100644 index 0000000..f8f513c --- /dev/null +++ b/plugins/mouse/gsd-mouse-manager.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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_MOUSE_MANAGER_H +#define __GSD_MOUSE_MANAGER_H + +#include <glib-object.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_MOUSE_MANAGER (gsd_mouse_manager_get_type ()) +#define GSD_MOUSE_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_MOUSE_MANAGER, GsdMouseManager)) +#define GSD_MOUSE_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_MOUSE_MANAGER, GsdMouseManagerClass)) +#define GSD_IS_MOUSE_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_MOUSE_MANAGER)) +#define GSD_IS_MOUSE_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_MOUSE_MANAGER)) +#define GSD_MOUSE_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_MOUSE_MANAGER, GsdMouseManagerClass)) + +typedef struct GsdMouseManagerPrivate GsdMouseManagerPrivate; + +typedef struct +{ + GObject parent; + GsdMouseManagerPrivate *priv; +} GsdMouseManager; + +typedef struct +{ + GObjectClass parent_class; +} GsdMouseManagerClass; + +GType gsd_mouse_manager_get_type (void); + +GsdMouseManager * gsd_mouse_manager_new (void); +gboolean gsd_mouse_manager_start (GsdMouseManager *manager, + GError **error); +void gsd_mouse_manager_stop (GsdMouseManager *manager); + +#ifdef __cplusplus +} +#endif + +#endif /* __GSD_MOUSE_MANAGER_H */ diff --git a/plugins/mouse/gsd-mouse-plugin.c b/plugins/mouse/gsd-mouse-plugin.c new file mode 100644 index 0000000..900a6d5 --- /dev/null +++ b/plugins/mouse/gsd-mouse-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 <[email protected]> + * + * 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 <glib/gi18n-lib.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" +#include "gsd-mouse-plugin.h" +#include "gsd-mouse-manager.h" + +struct GsdMousePluginPrivate { + GsdMouseManager *manager; +}; + +#define GSD_MOUSE_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSD_TYPE_MOUSE_PLUGIN, GsdMousePluginPrivate)) + +MATE_SETTINGS_PLUGIN_REGISTER (GsdMousePlugin, gsd_mouse_plugin) + +static void +gsd_mouse_plugin_init (GsdMousePlugin *plugin) +{ + plugin->priv = GSD_MOUSE_PLUGIN_GET_PRIVATE (plugin); + + g_debug ("GsdMousePlugin initializing"); + + plugin->priv->manager = gsd_mouse_manager_new (); +} + +static void +gsd_mouse_plugin_finalize (GObject *object) +{ + GsdMousePlugin *plugin; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_MOUSE_PLUGIN (object)); + + g_debug ("GsdMousePlugin finalizing"); + + plugin = GSD_MOUSE_PLUGIN (object); + + g_return_if_fail (plugin->priv != NULL); + + if (plugin->priv->manager != NULL) { + g_object_unref (plugin->priv->manager); + } + + G_OBJECT_CLASS (gsd_mouse_plugin_parent_class)->finalize (object); +} + +static void +impl_activate (MateSettingsPlugin *plugin) +{ + gboolean res; + GError *error; + + g_debug ("Activating mouse plugin"); + + error = NULL; + res = gsd_mouse_manager_start (GSD_MOUSE_PLUGIN (plugin)->priv->manager, &error); + if (! res) { + g_warning ("Unable to start mouse manager: %s", error->message); + g_error_free (error); + } +} + +static void +impl_deactivate (MateSettingsPlugin *plugin) +{ + g_debug ("Deactivating mouse plugin"); + gsd_mouse_manager_stop (GSD_MOUSE_PLUGIN (plugin)->priv->manager); +} + +static void +gsd_mouse_plugin_class_init (GsdMousePluginClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MateSettingsPluginClass *plugin_class = MATE_SETTINGS_PLUGIN_CLASS (klass); + + object_class->finalize = gsd_mouse_plugin_finalize; + + plugin_class->activate = impl_activate; + plugin_class->deactivate = impl_deactivate; + + g_type_class_add_private (klass, sizeof (GsdMousePluginPrivate)); +} diff --git a/plugins/mouse/gsd-mouse-plugin.h b/plugins/mouse/gsd-mouse-plugin.h new file mode 100644 index 0000000..e442450 --- /dev/null +++ b/plugins/mouse/gsd-mouse-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 <[email protected]> + * + * 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_MOUSE_PLUGIN_H__ +#define __GSD_MOUSE_PLUGIN_H__ + +#include <glib.h> +#include <glib-object.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_MOUSE_PLUGIN (gsd_mouse_plugin_get_type ()) +#define GSD_MOUSE_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_MOUSE_PLUGIN, GsdMousePlugin)) +#define GSD_MOUSE_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_MOUSE_PLUGIN, GsdMousePluginClass)) +#define GSD_IS_MOUSE_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_MOUSE_PLUGIN)) +#define GSD_IS_MOUSE_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_MOUSE_PLUGIN)) +#define GSD_MOUSE_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_MOUSE_PLUGIN, GsdMousePluginClass)) + +typedef struct GsdMousePluginPrivate GsdMousePluginPrivate; + +typedef struct +{ + MateSettingsPlugin parent; + GsdMousePluginPrivate *priv; +} GsdMousePlugin; + +typedef struct +{ + MateSettingsPluginClass parent_class; +} GsdMousePluginClass; + +GType gsd_mouse_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_MOUSE_PLUGIN_H__ */ diff --git a/plugins/mouse/gsd-timeline.c b/plugins/mouse/gsd-timeline.c new file mode 100644 index 0000000..748a0ad --- /dev/null +++ b/plugins/mouse/gsd-timeline.c @@ -0,0 +1,848 @@ +/* gsd-timeline.c + * + * Copyright (C) 2008 Carlos Garnacho <[email protected]> + * + * 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 <glib.h> +#include <gtk/gtk.h> +#include <math.h> +#include "gsd-timeline.h" + +#define GSD_TIMELINE_GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GSD_TYPE_TIMELINE, GsdTimelinePriv)) +#define MSECS_PER_SEC 1000 +#define FRAME_INTERVAL(nframes) (MSECS_PER_SEC / nframes) +#define DEFAULT_FPS 30 + +typedef struct GsdTimelinePriv GsdTimelinePriv; + +struct GsdTimelinePriv +{ + guint duration; + guint fps; + guint source_id; + + GTimer *timer; + + GdkScreen *screen; + GsdTimelineProgressType progress_type; + GsdTimelineProgressFunc progress_func; + + guint loop : 1; + guint direction : 1; +}; + +enum { + PROP_0, + PROP_FPS, + PROP_DURATION, + PROP_LOOP, + PROP_DIRECTION, + PROP_SCREEN, + PROP_PROGRESS_TYPE, +}; + +enum { + STARTED, + PAUSED, + FINISHED, + FRAME, + LAST_SIGNAL +}; + +static guint signals [LAST_SIGNAL] = { 0, }; + + +static void gsd_timeline_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gsd_timeline_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void gsd_timeline_finalize (GObject *object); + + +G_DEFINE_TYPE (GsdTimeline, gsd_timeline, G_TYPE_OBJECT) + + +GType +gsd_timeline_direction_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) + { + static const GEnumValue values[] = { + { GSD_TIMELINE_DIRECTION_FORWARD, "GSD_TIMELINE_DIRECTION_FORWARD", "forward" }, + { GSD_TIMELINE_DIRECTION_BACKWARD, "GSD_TIMELINE_DIRECTION_BACKWARD", "backward" }, + { 0, NULL, NULL } + }; + + type = g_enum_register_static (g_intern_static_string ("GsdTimelineDirection"), values); + } + + return type; +} + +GType +gsd_timeline_progress_type_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) + { + static const GEnumValue values[] = { + { GSD_TIMELINE_PROGRESS_LINEAR, "GSD_TIMELINE_PROGRESS_LINEAR", "linear" }, + { GSD_TIMELINE_PROGRESS_SINUSOIDAL, "GSD_TIMELINE_PROGRESS_SINUSOIDAL", "sinusoidal" }, + { GSD_TIMELINE_PROGRESS_EXPONENTIAL, "GSD_TIMELINE_PROGRESS_EXPONENTIAL", "exponential" }, + { 0, NULL, NULL } + }; + + type = g_enum_register_static (g_intern_static_string ("GsdTimelineProgressType"), values); + } + + return type; +} + +static void +gsd_timeline_class_init (GsdTimelineClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->set_property = gsd_timeline_set_property; + object_class->get_property = gsd_timeline_get_property; + object_class->finalize = gsd_timeline_finalize; + + g_object_class_install_property (object_class, + PROP_FPS, + g_param_spec_uint ("fps", + "FPS", + "Frames per second for the timeline", + 1, + G_MAXUINT, + DEFAULT_FPS, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_DURATION, + g_param_spec_uint ("duration", + "Animation Duration", + "Animation Duration", + 0, + G_MAXUINT, + 0, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_LOOP, + g_param_spec_boolean ("loop", + "Loop", + "Whether the timeline loops or not", + FALSE, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_DIRECTION, + g_param_spec_enum ("direction", + "Direction", + "Whether the timeline moves forward or backward in time", + GSD_TYPE_TIMELINE_DIRECTION, + GSD_TIMELINE_DIRECTION_FORWARD, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_DIRECTION, + g_param_spec_enum ("progress-type", + "Progress type", + "Type of progress through the timeline", + GSD_TYPE_TIMELINE_PROGRESS_TYPE, + GSD_TIMELINE_PROGRESS_LINEAR, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_SCREEN, + g_param_spec_object ("screen", + "Screen", + "Screen to get the settings from", + GDK_TYPE_SCREEN, + G_PARAM_READWRITE)); + + signals[STARTED] = + g_signal_new ("started", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GsdTimelineClass, started), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[PAUSED] = + g_signal_new ("paused", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GsdTimelineClass, paused), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[FINISHED] = + g_signal_new ("finished", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GsdTimelineClass, finished), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[FRAME] = + g_signal_new ("frame", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GsdTimelineClass, frame), + NULL, NULL, + g_cclosure_marshal_VOID__DOUBLE, + G_TYPE_NONE, 1, + G_TYPE_DOUBLE); + + g_type_class_add_private (class, sizeof (GsdTimelinePriv)); +} + +static void +gsd_timeline_init (GsdTimeline *timeline) +{ + GsdTimelinePriv *priv; + + priv = GSD_TIMELINE_GET_PRIV (timeline); + + priv->fps = DEFAULT_FPS; + priv->duration = 0; + priv->direction = GSD_TIMELINE_DIRECTION_FORWARD; + priv->screen = gdk_screen_get_default (); +} + +static void +gsd_timeline_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GsdTimeline *timeline; + GsdTimelinePriv *priv; + + timeline = GSD_TIMELINE (object); + priv = GSD_TIMELINE_GET_PRIV (timeline); + + switch (prop_id) + { + case PROP_FPS: + gsd_timeline_set_fps (timeline, g_value_get_uint (value)); + break; + case PROP_DURATION: + gsd_timeline_set_duration (timeline, g_value_get_uint (value)); + break; + case PROP_LOOP: + gsd_timeline_set_loop (timeline, g_value_get_boolean (value)); + break; + case PROP_DIRECTION: + gsd_timeline_set_direction (timeline, g_value_get_enum (value)); + break; + case PROP_SCREEN: + gsd_timeline_set_screen (timeline, + GDK_SCREEN (g_value_get_object (value))); + break; + case PROP_PROGRESS_TYPE: + gsd_timeline_set_progress_type (timeline, g_value_get_enum (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gsd_timeline_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GsdTimeline *timeline; + GsdTimelinePriv *priv; + + timeline = GSD_TIMELINE (object); + priv = GSD_TIMELINE_GET_PRIV (timeline); + + switch (prop_id) + { + case PROP_FPS: + g_value_set_uint (value, priv->fps); + break; + case PROP_DURATION: + g_value_set_uint (value, priv->duration); + break; + case PROP_LOOP: + g_value_set_boolean (value, priv->loop); + break; + case PROP_DIRECTION: + g_value_set_enum (value, priv->direction); + break; + case PROP_SCREEN: + g_value_set_object (value, priv->screen); + break; + case PROP_PROGRESS_TYPE: + g_value_set_enum (value, priv->progress_type); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gsd_timeline_finalize (GObject *object) +{ + GsdTimelinePriv *priv; + + priv = GSD_TIMELINE_GET_PRIV (object); + + if (priv->source_id) + { + g_source_remove (priv->source_id); + priv->source_id = 0; + } + + if (priv->timer) + g_timer_destroy (priv->timer); + + G_OBJECT_CLASS (gsd_timeline_parent_class)->finalize (object); +} + +/* Sinusoidal progress */ +static gdouble +sinusoidal_progress (gdouble progress) +{ + return (sinf ((progress * G_PI) / 2)); +} + +static gdouble +exponential_progress (gdouble progress) +{ + return progress * progress; +} + +static GsdTimelineProgressFunc +progress_type_to_func (GsdTimelineProgressType type) +{ + if (type == GSD_TIMELINE_PROGRESS_SINUSOIDAL) + return sinusoidal_progress; + else if (type == GSD_TIMELINE_PROGRESS_EXPONENTIAL) + return exponential_progress; + + return NULL; +} + +static gboolean +gsd_timeline_run_frame (GsdTimeline *timeline, + gboolean enable_animations) +{ + GsdTimelinePriv *priv; + gdouble linear_progress, progress; + guint elapsed_time; + GsdTimelineProgressFunc progress_func = NULL; + + priv = GSD_TIMELINE_GET_PRIV (timeline); + + if (enable_animations) + { + elapsed_time = (guint) (g_timer_elapsed (priv->timer, NULL) * 1000); + + linear_progress = (gdouble) elapsed_time / priv->duration; + + if (priv->direction == GSD_TIMELINE_DIRECTION_BACKWARD) + linear_progress = 1 - linear_progress; + + linear_progress = CLAMP (linear_progress, 0., 1.); + + if (priv->progress_func) + progress_func = priv->progress_func; + else if (priv->progress_type) + progress_func = progress_type_to_func (priv->progress_type); + + if (progress_func) + progress = (progress_func) (linear_progress); + else + progress = linear_progress; + } + else + progress = (priv->direction == GSD_TIMELINE_DIRECTION_FORWARD) ? 1.0 : 0.0; + + g_signal_emit (timeline, signals [FRAME], 0, + CLAMP (progress, 0.0, 1.0)); + + if ((priv->direction == GSD_TIMELINE_DIRECTION_FORWARD && progress >= 1.0) || + (priv->direction == GSD_TIMELINE_DIRECTION_BACKWARD && progress <= 0.0)) + { + if (!priv->loop) + { + if (priv->source_id) + { + g_source_remove (priv->source_id); + priv->source_id = 0; + } + + g_signal_emit (timeline, signals [FINISHED], 0); + return FALSE; + } + else + gsd_timeline_rewind (timeline); + } + + return TRUE; +} + +static gboolean +gsd_timeline_frame_idle_func (GsdTimeline *timeline) +{ + return gsd_timeline_run_frame (timeline, TRUE); +} + +/** + * gsd_timeline_new: + * @duration: duration in milliseconds for the timeline + * + * Creates a new #GsdTimeline with the specified number of frames. + * + * Return Value: the newly created #GsdTimeline + **/ +GsdTimeline * +gsd_timeline_new (guint duration) +{ + return g_object_new (GSD_TYPE_TIMELINE, + "duration", duration, + NULL); +} + +GsdTimeline * +gsd_timeline_new_for_screen (guint duration, + GdkScreen *screen) +{ + return g_object_new (GSD_TYPE_TIMELINE, + "duration", duration, + "screen", screen, + NULL); +} + +/** + * gsd_timeline_start: + * @timeline: A #GsdTimeline + * + * Runs the timeline from the current frame. + **/ +void +gsd_timeline_start (GsdTimeline *timeline) +{ + GsdTimelinePriv *priv; + GtkSettings *settings; + gboolean enable_animations = FALSE; + + g_return_if_fail (GSD_IS_TIMELINE (timeline)); + + priv = GSD_TIMELINE_GET_PRIV (timeline); + + if (priv->screen) + { + settings = gtk_settings_get_for_screen (priv->screen); + g_object_get (settings, "gtk-enable-animations", &enable_animations, NULL); + } + + if (enable_animations) + { + if (!priv->source_id) + { + if (priv->timer) + g_timer_continue (priv->timer); + else + priv->timer = g_timer_new (); + + /* sanity check */ + g_assert (priv->fps > 0); + + g_signal_emit (timeline, signals [STARTED], 0); + + priv->source_id = gdk_threads_add_timeout (FRAME_INTERVAL (priv->fps), + (GSourceFunc) gsd_timeline_frame_idle_func, + timeline); + } + } + else + { + /* If animations are not enabled, only run the last frame, + * it take us instantaneously to the last state of the animation. + * The only potential flaw happens when people use the ::finished + * signal to trigger another animation, or even worse, finally + * loop into this animation again. + */ + g_signal_emit (timeline, signals [STARTED], 0); + gsd_timeline_run_frame (timeline, FALSE); + } +} + +/** + * gsd_timeline_pause: + * @timeline: A #GsdTimeline + * + * Pauses the timeline. + **/ +void +gsd_timeline_pause (GsdTimeline *timeline) +{ + GsdTimelinePriv *priv; + + g_return_if_fail (GSD_IS_TIMELINE (timeline)); + + priv = GSD_TIMELINE_GET_PRIV (timeline); + + if (priv->source_id) + { + g_source_remove (priv->source_id); + priv->source_id = 0; + g_timer_stop (priv->timer); + g_signal_emit (timeline, signals [PAUSED], 0); + } +} + +/** + * gsd_timeline_rewind: + * @timeline: A #GsdTimeline + * + * Rewinds the timeline. + **/ +void +gsd_timeline_rewind (GsdTimeline *timeline) +{ + GsdTimelinePriv *priv; + + g_return_if_fail (GSD_IS_TIMELINE (timeline)); + + priv = GSD_TIMELINE_GET_PRIV (timeline); + + /* destroy and re-create timer if neccesary */ + if (priv->timer) + { + g_timer_destroy (priv->timer); + + if (gsd_timeline_is_running (timeline)) + priv->timer = g_timer_new (); + else + priv->timer = NULL; + } +} + +/** + * gsd_timeline_is_running: + * @timeline: A #GsdTimeline + * + * Returns whether the timeline is running or not. + * + * Return Value: %TRUE if the timeline is running + **/ +gboolean +gsd_timeline_is_running (GsdTimeline *timeline) +{ + GsdTimelinePriv *priv; + + g_return_val_if_fail (GSD_IS_TIMELINE (timeline), FALSE); + + priv = GSD_TIMELINE_GET_PRIV (timeline); + + return (priv->source_id != 0); +} + +/** + * gsd_timeline_get_fps: + * @timeline: A #GsdTimeline + * + * Returns the number of frames per second. + * + * Return Value: frames per second + **/ +guint +gsd_timeline_get_fps (GsdTimeline *timeline) +{ + GsdTimelinePriv *priv; + + g_return_val_if_fail (GSD_IS_TIMELINE (timeline), 1); + + priv = GSD_TIMELINE_GET_PRIV (timeline); + return priv->fps; +} + +/** + * gsd_timeline_set_fps: + * @timeline: A #GsdTimeline + * @fps: frames per second + * + * Sets the number of frames per second that + * the timeline will play. + **/ +void +gsd_timeline_set_fps (GsdTimeline *timeline, + guint fps) +{ + GsdTimelinePriv *priv; + + g_return_if_fail (GSD_IS_TIMELINE (timeline)); + g_return_if_fail (fps > 0); + + priv = GSD_TIMELINE_GET_PRIV (timeline); + + priv->fps = fps; + + if (gsd_timeline_is_running (timeline)) + { + g_source_remove (priv->source_id); + priv->source_id = gdk_threads_add_timeout (FRAME_INTERVAL (priv->fps), + (GSourceFunc) gsd_timeline_run_frame, + timeline); + } + + g_object_notify (G_OBJECT (timeline), "fps"); +} + +/** + * gsd_timeline_get_loop: + * @timeline: A #GsdTimeline + * + * Returns whether the timeline loops to the + * beginning when it has reached the end. + * + * Return Value: %TRUE if the timeline loops + **/ +gboolean +gsd_timeline_get_loop (GsdTimeline *timeline) +{ + GsdTimelinePriv *priv; + + g_return_val_if_fail (GSD_IS_TIMELINE (timeline), FALSE); + + priv = GSD_TIMELINE_GET_PRIV (timeline); + return priv->loop; +} + +/** + * gsd_timeline_set_loop: + * @timeline: A #GsdTimeline + * @loop: %TRUE to make the timeline loop + * + * Sets whether the timeline loops to the beginning + * when it has reached the end. + **/ +void +gsd_timeline_set_loop (GsdTimeline *timeline, + gboolean loop) +{ + GsdTimelinePriv *priv; + + g_return_if_fail (GSD_IS_TIMELINE (timeline)); + + priv = GSD_TIMELINE_GET_PRIV (timeline); + priv->loop = loop; + + g_object_notify (G_OBJECT (timeline), "loop"); +} + +void +gsd_timeline_set_duration (GsdTimeline *timeline, + guint duration) +{ + GsdTimelinePriv *priv; + + g_return_if_fail (GSD_IS_TIMELINE (timeline)); + + priv = GSD_TIMELINE_GET_PRIV (timeline); + + priv->duration = duration; + + g_object_notify (G_OBJECT (timeline), "duration"); +} + +guint +gsd_timeline_get_duration (GsdTimeline *timeline) +{ + GsdTimelinePriv *priv; + + g_return_val_if_fail (GSD_IS_TIMELINE (timeline), 0); + + priv = GSD_TIMELINE_GET_PRIV (timeline); + + return priv->duration; +} + +/** + * gsd_timeline_get_direction: + * @timeline: A #GsdTimeline + * + * Returns the direction of the timeline. + * + * Return Value: direction + **/ +GsdTimelineDirection +gsd_timeline_get_direction (GsdTimeline *timeline) +{ + GsdTimelinePriv *priv; + + g_return_val_if_fail (GSD_IS_TIMELINE (timeline), GSD_TIMELINE_DIRECTION_FORWARD); + + priv = GSD_TIMELINE_GET_PRIV (timeline); + return priv->direction; +} + +/** + * gsd_timeline_set_direction: + * @timeline: A #GsdTimeline + * @direction: direction + * + * Sets the direction of the timeline. + **/ +void +gsd_timeline_set_direction (GsdTimeline *timeline, + GsdTimelineDirection direction) +{ + GsdTimelinePriv *priv; + + g_return_if_fail (GSD_IS_TIMELINE (timeline)); + + priv = GSD_TIMELINE_GET_PRIV (timeline); + priv->direction = direction; + + g_object_notify (G_OBJECT (timeline), "direction"); +} + +GdkScreen * +gsd_timeline_get_screen (GsdTimeline *timeline) +{ + GsdTimelinePriv *priv; + + g_return_val_if_fail (GSD_IS_TIMELINE (timeline), NULL); + + priv = GSD_TIMELINE_GET_PRIV (timeline); + return priv->screen; +} + +void +gsd_timeline_set_screen (GsdTimeline *timeline, + GdkScreen *screen) +{ + GsdTimelinePriv *priv; + + g_return_if_fail (GSD_IS_TIMELINE (timeline)); + g_return_if_fail (GDK_IS_SCREEN (screen)); + + priv = GSD_TIMELINE_GET_PRIV (timeline); + + if (priv->screen) + g_object_unref (priv->screen); + + priv->screen = g_object_ref (screen); + + g_object_notify (G_OBJECT (timeline), "screen"); +} + +void +gsd_timeline_set_progress_type (GsdTimeline *timeline, + GsdTimelineProgressType type) +{ + GsdTimelinePriv *priv; + + g_return_if_fail (GSD_IS_TIMELINE (timeline)); + + priv = GSD_TIMELINE_GET_PRIV (timeline); + + priv->progress_type = type; + + g_object_notify (G_OBJECT (timeline), "progress-type"); +} + +GsdTimelineProgressType +gsd_timeline_get_progress_type (GsdTimeline *timeline) +{ + GsdTimelinePriv *priv; + + g_return_val_if_fail (GSD_IS_TIMELINE (timeline), GSD_TIMELINE_PROGRESS_LINEAR); + + priv = GSD_TIMELINE_GET_PRIV (timeline); + + if (priv->progress_func) + return GSD_TIMELINE_PROGRESS_LINEAR; + + return priv->progress_type; +} + +/** + * gsd_timeline_set_progress_func: + * @timeline: A #GsdTimeline + * @progress_func: progress function + * + * Sets the progress function. This function will be used to calculate + * a different progress to pass to the ::frame signal based on the + * linear progress through the timeline. Setting progress_func + * to %NULL will make the timeline use the default function, + * which is just a linear progress. + * + * All progresses are in the [0.0, 1.0] range. + **/ +void +gsd_timeline_set_progress_func (GsdTimeline *timeline, + GsdTimelineProgressFunc progress_func) +{ + GsdTimelinePriv *priv; + + g_return_if_fail (GSD_IS_TIMELINE (timeline)); + + priv = GSD_TIMELINE_GET_PRIV (timeline); + priv->progress_func = progress_func; +} + +gdouble +gsd_timeline_get_progress (GsdTimeline *timeline) +{ + GsdTimelinePriv *priv; + GsdTimelineProgressFunc progress_func = NULL; + gdouble linear_progress, progress; + guint elapsed_time; + + g_return_val_if_fail (GSD_IS_TIMELINE (timeline), 0.0); + + priv = GSD_TIMELINE_GET_PRIV (timeline); + + if (!priv->timer) + return 0.; + + elapsed_time = (guint) (g_timer_elapsed (priv->timer, NULL) * 1000); + + linear_progress = (gdouble) elapsed_time / priv->duration; + + if (priv->direction == GSD_TIMELINE_DIRECTION_BACKWARD) + linear_progress = 1 - linear_progress; + + linear_progress = CLAMP (linear_progress, 0., 1.); + + if (priv->progress_func) + progress_func = priv->progress_func; + else if (priv->progress_type) + progress_func = progress_type_to_func (priv->progress_type); + + if (progress_func) + progress = (progress_func) (linear_progress); + else + progress = linear_progress; + + return CLAMP (progress, 0., 1.); +} diff --git a/plugins/mouse/gsd-timeline.h b/plugins/mouse/gsd-timeline.h new file mode 100644 index 0000000..d4ecbcc --- /dev/null +++ b/plugins/mouse/gsd-timeline.h @@ -0,0 +1,127 @@ +/* gsdtimeline.c + * + * Copyright (C) 2008 Carlos Garnacho <[email protected]> + * + * 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_TIMELINE_H__ +#define __GSD_TIMELINE_H__ + +#include <glib-object.h> +#include <gdk/gdk.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_TIMELINE_DIRECTION (gsd_timeline_direction_get_type ()) +#define GSD_TYPE_TIMELINE_PROGRESS_TYPE (gsd_timeline_progress_type_get_type ()) +#define GSD_TYPE_TIMELINE (gsd_timeline_get_type ()) +#define GSD_TIMELINE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSD_TYPE_TIMELINE, GsdTimeline)) +#define GSD_TIMELINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSD_TYPE_TIMELINE, GsdTimelineClass)) +#define GSD_IS_TIMELINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSD_TYPE_TIMELINE)) +#define GSD_IS_TIMELINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSD_TYPE_TIMELINE)) +#define GSD_TIMELINE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSD_TYPE_TIMELINE, GsdTimelineClass)) + +typedef enum { + GSD_TIMELINE_DIRECTION_FORWARD, + GSD_TIMELINE_DIRECTION_BACKWARD +} GsdTimelineDirection; + +typedef enum { + GSD_TIMELINE_PROGRESS_LINEAR, + GSD_TIMELINE_PROGRESS_SINUSOIDAL, + GSD_TIMELINE_PROGRESS_EXPONENTIAL +} GsdTimelineProgressType; + +typedef struct GsdTimeline GsdTimeline; +typedef struct GsdTimelineClass GsdTimelineClass; + +struct GsdTimeline +{ + GObject parent_instance; +}; + +struct GsdTimelineClass +{ + GObjectClass parent_class; + + void (* started) (GsdTimeline *timeline); + void (* finished) (GsdTimeline *timeline); + void (* paused) (GsdTimeline *timeline); + + void (* frame) (GsdTimeline *timeline, + gdouble progress); + + void (* __gsd_reserved1) (void); + void (* __gsd_reserved2) (void); + void (* __gsd_reserved3) (void); + void (* __gsd_reserved4) (void); +}; + +typedef gdouble (*GsdTimelineProgressFunc) (gdouble progress); + + +GType gsd_timeline_get_type (void) G_GNUC_CONST; +GType gsd_timeline_direction_get_type (void) G_GNUC_CONST; +GType gsd_timeline_progress_type_get_type (void) G_GNUC_CONST; + +GsdTimeline *gsd_timeline_new (guint duration); +GsdTimeline *gsd_timeline_new_for_screen (guint duration, + GdkScreen *screen); + +void gsd_timeline_start (GsdTimeline *timeline); +void gsd_timeline_pause (GsdTimeline *timeline); +void gsd_timeline_rewind (GsdTimeline *timeline); + +gboolean gsd_timeline_is_running (GsdTimeline *timeline); + +guint gsd_timeline_get_fps (GsdTimeline *timeline); +void gsd_timeline_set_fps (GsdTimeline *timeline, + guint fps); + +gboolean gsd_timeline_get_loop (GsdTimeline *timeline); +void gsd_timeline_set_loop (GsdTimeline *timeline, + gboolean loop); + +guint gsd_timeline_get_duration (GsdTimeline *timeline); +void gsd_timeline_set_duration (GsdTimeline *timeline, + guint duration); + +GdkScreen *gsd_timeline_get_screen (GsdTimeline *timeline); +void gsd_timeline_set_screen (GsdTimeline *timeline, + GdkScreen *screen); + +GsdTimelineDirection gsd_timeline_get_direction (GsdTimeline *timeline); +void gsd_timeline_set_direction (GsdTimeline *timeline, + GsdTimelineDirection direction); + +GsdTimelineProgressType gsd_timeline_get_progress_type (GsdTimeline *timeline); +void gsd_timeline_set_progress_type (GsdTimeline *timeline, + GsdTimelineProgressType type); +void gsd_timeline_get_progress_func (GsdTimeline *timeline); + +void gsd_timeline_set_progress_func (GsdTimeline *timeline, + GsdTimelineProgressFunc progress_func); + +gdouble gsd_timeline_get_progress (GsdTimeline *timeline); + + +#ifdef __cplusplus +} +#endif + +#endif /* __GSD_TIMELINE_H__ */ diff --git a/plugins/mouse/mouse.mate-settings-plugin.in b/plugins/mouse/mouse.mate-settings-plugin.in new file mode 100644 index 0000000..8cf5272 --- /dev/null +++ b/plugins/mouse/mouse.mate-settings-plugin.in @@ -0,0 +1,8 @@ +[MATE Settings Plugin] +Module=mouse +IAge=0 +_Name=Mouse +_Description=Mouse plugin +Authors= +Copyright=Copyright © 2007 +Website= diff --git a/plugins/smartcard/Makefile.am b/plugins/smartcard/Makefile.am new file mode 100644 index 0000000..a70e0a0 --- /dev/null +++ b/plugins/smartcard/Makefile.am @@ -0,0 +1,47 @@ +plugin_LTLIBRARIES = \ + libsmartcard.la + +libsmartcard_la_SOURCES = \ + gsd-smartcard-plugin.h \ + gsd-smartcard-plugin.c \ + gsd-smartcard.h \ + gsd-smartcard.c \ + gsd-smartcard-manager.h \ + gsd-smartcard-manager.c + +libsmartcard_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DGSD_SMARTCARD_MANAGER_NSS_DB=\""$(NSS_DATABASE)"\" \ + $(AM_CPPFLAGS) + +libsmartcard_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(MATE_CFLAGS) \ + $(NSS_CFLAGS) \ + $(AM_CFLAGS) + +libsmartcard_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) + +libsmartcard_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(NSS_LIBS) + +@GSD_INTLTOOL_PLUGIN_RULE@ + +plugin_in_files = \ + smartcard.mate-settings-plugin.in + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) + +EXTRA_DIST = \ + $(plugin_in_files) + +CLEANFILES = \ + $(plugin_DATA) + +DISTCLEANFILES = \ + $(plugin_DATA) diff --git a/plugins/smartcard/Makefile.in b/plugins/smartcard/Makefile.in new file mode 100644 index 0000000..5e77c45 --- /dev/null +++ b/plugins/smartcard/Makefile.in @@ -0,0 +1,684 @@ +# 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/smartcard +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)$(plugindir)" +LTLIBRARIES = $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +libsmartcard_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_libsmartcard_la_OBJECTS = libsmartcard_la-gsd-smartcard-plugin.lo \ + libsmartcard_la-gsd-smartcard.lo \ + libsmartcard_la-gsd-smartcard-manager.lo +libsmartcard_la_OBJECTS = $(am_libsmartcard_la_OBJECTS) +libsmartcard_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libsmartcard_la_CFLAGS) \ + $(CFLAGS) $(libsmartcard_la_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 = $(libsmartcard_la_SOURCES) +DIST_SOURCES = $(libsmartcard_la_SOURCES) +DATA = $(plugin_DATA) +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@ +plugin_LTLIBRARIES = \ + libsmartcard.la + +libsmartcard_la_SOURCES = \ + gsd-smartcard-plugin.h \ + gsd-smartcard-plugin.c \ + gsd-smartcard.h \ + gsd-smartcard.c \ + gsd-smartcard-manager.h \ + gsd-smartcard-manager.c + +libsmartcard_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + -DSYSCONFDIR=\""$(sysconfdir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DGSD_SMARTCARD_MANAGER_NSS_DB=\""$(NSS_DATABASE)"\" \ + $(AM_CPPFLAGS) + +libsmartcard_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(MATE_CFLAGS) \ + $(NSS_CFLAGS) \ + $(AM_CFLAGS) + +libsmartcard_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) + +libsmartcard_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(NSS_LIBS) + +plugin_in_files = \ + smartcard.mate-settings-plugin.in + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) +EXTRA_DIST = \ + $(plugin_in_files) + +CLEANFILES = \ + $(plugin_DATA) + +DISTCLEANFILES = \ + $(plugin_DATA) + +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/smartcard/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plugins/smartcard/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 +libsmartcard.la: $(libsmartcard_la_OBJECTS) $(libsmartcard_la_DEPENDENCIES) + $(libsmartcard_la_LINK) -rpath $(plugindir) $(libsmartcard_la_OBJECTS) $(libsmartcard_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsmartcard_la-gsd-smartcard-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsmartcard_la-gsd-smartcard-plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsmartcard_la-gsd-smartcard.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 $@ $< + +libsmartcard_la-gsd-smartcard-plugin.lo: gsd-smartcard-plugin.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsmartcard_la_CPPFLAGS) $(CPPFLAGS) $(libsmartcard_la_CFLAGS) $(CFLAGS) -MT libsmartcard_la-gsd-smartcard-plugin.lo -MD -MP -MF $(DEPDIR)/libsmartcard_la-gsd-smartcard-plugin.Tpo -c -o libsmartcard_la-gsd-smartcard-plugin.lo `test -f 'gsd-smartcard-plugin.c' || echo '$(srcdir)/'`gsd-smartcard-plugin.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libsmartcard_la-gsd-smartcard-plugin.Tpo $(DEPDIR)/libsmartcard_la-gsd-smartcard-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-smartcard-plugin.c' object='libsmartcard_la-gsd-smartcard-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) $(libsmartcard_la_CPPFLAGS) $(CPPFLAGS) $(libsmartcard_la_CFLAGS) $(CFLAGS) -c -o libsmartcard_la-gsd-smartcard-plugin.lo `test -f 'gsd-smartcard-plugin.c' || echo '$(srcdir)/'`gsd-smartcard-plugin.c + +libsmartcard_la-gsd-smartcard.lo: gsd-smartcard.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsmartcard_la_CPPFLAGS) $(CPPFLAGS) $(libsmartcard_la_CFLAGS) $(CFLAGS) -MT libsmartcard_la-gsd-smartcard.lo -MD -MP -MF $(DEPDIR)/libsmartcard_la-gsd-smartcard.Tpo -c -o libsmartcard_la-gsd-smartcard.lo `test -f 'gsd-smartcard.c' || echo '$(srcdir)/'`gsd-smartcard.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libsmartcard_la-gsd-smartcard.Tpo $(DEPDIR)/libsmartcard_la-gsd-smartcard.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-smartcard.c' object='libsmartcard_la-gsd-smartcard.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) $(libsmartcard_la_CPPFLAGS) $(CPPFLAGS) $(libsmartcard_la_CFLAGS) $(CFLAGS) -c -o libsmartcard_la-gsd-smartcard.lo `test -f 'gsd-smartcard.c' || echo '$(srcdir)/'`gsd-smartcard.c + +libsmartcard_la-gsd-smartcard-manager.lo: gsd-smartcard-manager.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsmartcard_la_CPPFLAGS) $(CPPFLAGS) $(libsmartcard_la_CFLAGS) $(CFLAGS) -MT libsmartcard_la-gsd-smartcard-manager.lo -MD -MP -MF $(DEPDIR)/libsmartcard_la-gsd-smartcard-manager.Tpo -c -o libsmartcard_la-gsd-smartcard-manager.lo `test -f 'gsd-smartcard-manager.c' || echo '$(srcdir)/'`gsd-smartcard-manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libsmartcard_la-gsd-smartcard-manager.Tpo $(DEPDIR)/libsmartcard_la-gsd-smartcard-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-smartcard-manager.c' object='libsmartcard_la-gsd-smartcard-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) $(libsmartcard_la_CPPFLAGS) $(CPPFLAGS) $(libsmartcard_la_CFLAGS) $(CFLAGS) -c -o libsmartcard_la-gsd-smartcard-manager.lo `test -f 'gsd-smartcard-manager.c' || echo '$(srcdir)/'`gsd-smartcard-manager.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +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 + +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) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -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." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ + 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-pluginDATA install-pluginLTLIBRARIES + +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: uninstall-pluginDATA uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-pluginLTLIBRARIES 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-pluginDATA \ + install-pluginLTLIBRARIES 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 \ + uninstall-pluginDATA uninstall-pluginLTLIBRARIES + + +@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/smartcard/gsd-smartcard-manager.c b/plugins/smartcard/gsd-smartcard-manager.c new file mode 100644 index 0000000..a231e20 --- /dev/null +++ b/plugins/smartcard/gsd-smartcard-manager.c @@ -0,0 +1,1372 @@ +/* gsd-smartcard-manager.c - object for monitoring smartcard insertion and + * removal events + * + * Copyright (C) 2006, 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written By: Ray Strode + */ +#include "config.h" + +#include "gsd-smartcard-manager.h" + +#define SMARTCARD_ENABLE_INTERNAL_API +#include "gsd-smartcard.h" + +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <poll.h> +#include <signal.h> +#include <stdlib.h> +#include <string.h> +#include <sys/resource.h> +#include <sys/time.h> +#include <sys/wait.h> +#include <unistd.h> + +#include <glib.h> +#include <glib/gi18n.h> + +#include <prerror.h> +#include <nss.h> +#include <pk11func.h> +#include <secmod.h> +#include <secerr.h> + +#ifndef GSD_SMARTCARD_MANAGER_NSS_DB +#define GSD_SMARTCARD_MANAGER_NSS_DB SYSCONFDIR"/pki/nssdb" +#endif + +typedef enum _GsdSmartcardManagerState GsdSmartcardManagerState; +typedef struct _GsdSmartcardManagerWorker GsdSmartcardManagerWorker; + +enum _GsdSmartcardManagerState { + GSD_SMARTCARD_MANAGER_STATE_STOPPED = 0, + GSD_SMARTCARD_MANAGER_STATE_STARTING, + GSD_SMARTCARD_MANAGER_STATE_STARTED, + GSD_SMARTCARD_MANAGER_STATE_STOPPING, +}; + +struct _GsdSmartcardManagerPrivate { + GsdSmartcardManagerState state; + SECMODModule *module; + char *module_path; + + GSource *smartcard_event_source; + GPid smartcard_event_watcher_pid; + GHashTable *smartcards; + + GThread *worker_thread; + + guint poll_timeout_id; + + guint32 is_unstoppable : 1; + guint32 nss_is_loaded : 1; +}; + +struct _GsdSmartcardManagerWorker { + SECMODModule *module; + GHashTable *smartcards; + int write_fd; + + guint32 nss_is_loaded : 1; +}; + +static void gsd_smartcard_manager_finalize (GObject *object); +static void gsd_smartcard_manager_class_install_signals (GsdSmartcardManagerClass *service_class); +static void gsd_smartcard_manager_class_install_properties (GsdSmartcardManagerClass *service_class); +static void gsd_smartcard_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gsd_smartcard_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void gsd_smartcard_manager_set_module_path (GsdSmartcardManager *manager, + const char *module_path); +static void gsd_smartcard_manager_card_removed_handler (GsdSmartcardManager *manager, + GsdSmartcard *card); +static void gsd_smartcard_manager_card_inserted_handler (GsdSmartcardManager *manager_class, + GsdSmartcard *card); +static gboolean gsd_smartcard_manager_stop_now (GsdSmartcardManager *manager); +static void gsd_smartcard_manager_queue_stop (GsdSmartcardManager *manager); + +static gboolean gsd_smartcard_manager_create_worker (GsdSmartcardManager *manager, + int *worker_fd, GThread **worker_thread); + +static GsdSmartcardManagerWorker * gsd_smartcard_manager_worker_new (int write_fd); +static void gsd_smartcard_manager_worker_free (GsdSmartcardManagerWorker *worker); +static gboolean open_pipe (int *write_fd, int *read_fd); +static gboolean read_bytes (int fd, gpointer bytes, gsize num_bytes); +static gboolean write_bytes (int fd, gconstpointer bytes, gsize num_bytes); +static GsdSmartcard *read_smartcard (int fd, SECMODModule *module); +static gboolean write_smartcard (int fd, GsdSmartcard *card); + +enum { + PROP_0 = 0, + PROP_MODULE_PATH, + NUMBER_OF_PROPERTIES +}; + +enum { + SMARTCARD_INSERTED = 0, + SMARTCARD_REMOVED, + ERROR, + NUMBER_OF_SIGNALS +}; + +static guint gsd_smartcard_manager_signals[NUMBER_OF_SIGNALS]; + +G_DEFINE_TYPE (GsdSmartcardManager, + gsd_smartcard_manager, + G_TYPE_OBJECT); + +static void +gsd_smartcard_manager_class_init (GsdSmartcardManagerClass *manager_class) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (manager_class); + + gobject_class->finalize = gsd_smartcard_manager_finalize; + + gsd_smartcard_manager_class_install_signals (manager_class); + gsd_smartcard_manager_class_install_properties (manager_class); + + g_type_class_add_private (manager_class, + sizeof (GsdSmartcardManagerPrivate)); +} + +static void +gsd_smartcard_manager_class_install_properties (GsdSmartcardManagerClass *card_class) +{ + GObjectClass *object_class; + GParamSpec *param_spec; + + object_class = G_OBJECT_CLASS (card_class); + object_class->set_property = gsd_smartcard_manager_set_property; + object_class->get_property = gsd_smartcard_manager_get_property; + + param_spec = g_param_spec_string ("module-path", _("Module Path"), + _("path to smartcard PKCS #11 driver"), + NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, PROP_MODULE_PATH, param_spec); +} + +static void +gsd_smartcard_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GsdSmartcardManager *manager = GSD_SMARTCARD_MANAGER (object); + + switch (prop_id) { + case PROP_MODULE_PATH: + gsd_smartcard_manager_set_module_path (manager, + g_value_get_string (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gsd_smartcard_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GsdSmartcardManager *manager = GSD_SMARTCARD_MANAGER (object); + char *module_path; + + switch (prop_id) { + case PROP_MODULE_PATH: + module_path = gsd_smartcard_manager_get_module_path (manager); + g_value_set_string (value, module_path); + g_free (module_path); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +char * +gsd_smartcard_manager_get_module_path (GsdSmartcardManager *manager) +{ + return manager->priv->module_path; +} + +static void +gsd_smartcard_manager_set_module_path (GsdSmartcardManager *manager, + const char *module_path) +{ + if ((manager->priv->module_path == NULL) && (module_path == NULL)) { + return; + } + + if (((manager->priv->module_path == NULL) || + (module_path == NULL) || + (strcmp (manager->priv->module_path, module_path) != 0))) { + g_free (manager->priv->module_path); + manager->priv->module_path = g_strdup (module_path); + g_object_notify (G_OBJECT (manager), "module-path"); + } +} + +static void +gsd_smartcard_manager_card_removed_handler (GsdSmartcardManager *manager, + GsdSmartcard *card) +{ + g_debug ("informing smartcard of its removal"); + _gsd_smartcard_set_state (card, GSD_SMARTCARD_STATE_REMOVED); + g_debug ("done"); +} + +static void +gsd_smartcard_manager_card_inserted_handler (GsdSmartcardManager *manager, + GsdSmartcard *card) +{ + g_debug ("informing smartcard of its insertion"); + + _gsd_smartcard_set_state (card, GSD_SMARTCARD_STATE_INSERTED); + g_debug ("done"); + +} + +static void +gsd_smartcard_manager_class_install_signals (GsdSmartcardManagerClass *manager_class) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (manager_class); + + gsd_smartcard_manager_signals[SMARTCARD_INSERTED] = + g_signal_new ("smartcard-inserted", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GsdSmartcardManagerClass, + smartcard_inserted), + NULL, NULL, g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + manager_class->smartcard_inserted = gsd_smartcard_manager_card_inserted_handler; + + gsd_smartcard_manager_signals[SMARTCARD_REMOVED] = + g_signal_new ("smartcard-removed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GsdSmartcardManagerClass, + smartcard_removed), + NULL, NULL, g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + manager_class->smartcard_removed = gsd_smartcard_manager_card_removed_handler; + + gsd_smartcard_manager_signals[ERROR] = + g_signal_new ("error", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GsdSmartcardManagerClass, error), + NULL, NULL, g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + manager_class->error = NULL; +} + +static gboolean +slot_id_equal (CK_SLOT_ID *slot_id_1, + CK_SLOT_ID *slot_id_2) +{ + g_assert (slot_id_1 != NULL); + g_assert (slot_id_2 != NULL); + + return *slot_id_1 == *slot_id_2; +} + +static gboolean +slot_id_hash (CK_SLOT_ID *slot_id) +{ + guint32 upper_bits, lower_bits; + int temp; + + if (sizeof (CK_SLOT_ID) == sizeof (int)) { + return g_int_hash (slot_id); + } + + upper_bits = ((*slot_id) >> 31) - 1; + lower_bits = (*slot_id) & 0xffffffff; + + /* The upper bits are almost certainly always zero, + * so let's degenerate to g_int_hash for the + * (very) common case + */ + temp = lower_bits + upper_bits; + return upper_bits + g_int_hash (&temp); +} + +static void +gsd_smartcard_manager_init (GsdSmartcardManager *manager) +{ + g_debug ("initializing smartcard manager"); + + manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager, + GSD_TYPE_SMARTCARD_MANAGER, + GsdSmartcardManagerPrivate); + manager->priv->poll_timeout_id = 0; + manager->priv->is_unstoppable = FALSE; + manager->priv->module = NULL; + + manager->priv->smartcards = + g_hash_table_new_full (g_str_hash, + g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_object_unref); + + if (!g_thread_supported ()) { + g_thread_init (NULL); + } + +} + +static void +gsd_smartcard_manager_finalize (GObject *object) +{ + GsdSmartcardManager *manager; + GObjectClass *gobject_class; + + manager = GSD_SMARTCARD_MANAGER (object); + gobject_class = + G_OBJECT_CLASS (gsd_smartcard_manager_parent_class); + + gsd_smartcard_manager_stop_now (manager); + + g_hash_table_destroy (manager->priv->smartcards); + manager->priv->smartcards = NULL; + + gobject_class->finalize (object); +} + +GQuark +gsd_smartcard_manager_error_quark (void) +{ + static GQuark error_quark = 0; + + if (error_quark == 0) { + error_quark = g_quark_from_static_string ("gsd-smartcard-manager-error-quark"); + } + + return error_quark; +} + +GsdSmartcardManager * +gsd_smartcard_manager_new (const char *module_path) +{ + GsdSmartcardManager *instance; + + instance = GSD_SMARTCARD_MANAGER (g_object_new (GSD_TYPE_SMARTCARD_MANAGER, + "module-path", module_path, + NULL)); + + return instance; +} + +static void +gsd_smartcard_manager_emit_error (GsdSmartcardManager *manager, + GError *error) +{ + manager->priv->is_unstoppable = TRUE; + g_signal_emit (manager, gsd_smartcard_manager_signals[ERROR], 0, + error); + manager->priv->is_unstoppable = FALSE; +} + +static void +gsd_smartcard_manager_emit_smartcard_inserted (GsdSmartcardManager *manager, + GsdSmartcard *card) +{ + manager->priv->is_unstoppable = TRUE; + g_signal_emit (manager, gsd_smartcard_manager_signals[SMARTCARD_INSERTED], 0, + card); + manager->priv->is_unstoppable = FALSE; +} + +static void +gsd_smartcard_manager_emit_smartcard_removed (GsdSmartcardManager *manager, + GsdSmartcard *card) +{ + GsdSmartcardManagerState old_state; + + old_state = manager->priv->state; + manager->priv->is_unstoppable = TRUE; + g_signal_emit (manager, gsd_smartcard_manager_signals[SMARTCARD_REMOVED], 0, + card); + manager->priv->is_unstoppable = FALSE; +} + +static gboolean +gsd_smartcard_manager_check_for_and_process_events (GIOChannel *io_channel, + GIOCondition condition, + GsdSmartcardManager *manager) +{ + GsdSmartcard *card; + gboolean should_stop; + gchar event_type; + char *card_name; + int fd; + + card = NULL; + should_stop = (condition & G_IO_HUP) || (condition & G_IO_ERR); + + if (should_stop) { + g_debug ("received %s on event socket, stopping " + "manager...", + (condition & G_IO_HUP) && (condition & G_IO_ERR)? + "error and hangup" : + (condition & G_IO_HUP)? + "hangup" : "error"); + } + + if (!(condition & G_IO_IN)) { + goto out; + } + + fd = g_io_channel_unix_get_fd (io_channel); + + event_type = '\0'; + if (!read_bytes (fd, &event_type, 1)) { + should_stop = TRUE; + goto out; + } + + card = read_smartcard (fd, manager->priv->module); + + if (card == NULL) { + should_stop = TRUE; + goto out; + } + + card_name = gsd_smartcard_get_name (card); + + switch (event_type) { + case 'I': + g_hash_table_replace (manager->priv->smartcards, + card_name, card); + card_name = NULL; + + gsd_smartcard_manager_emit_smartcard_inserted (manager, card); + card = NULL; + break; + + case 'R': + gsd_smartcard_manager_emit_smartcard_removed (manager, card); + if (!g_hash_table_remove (manager->priv->smartcards, card_name)) { + g_debug ("got removal event of unknown card!"); + } + g_free (card_name); + card_name = NULL; + card = NULL; + break; + + default: + g_free (card_name); + card_name = NULL; + g_object_unref (card); + + should_stop = TRUE; + break; + } + +out: + if (should_stop) { + GError *error; + + error = g_error_new (GSD_SMARTCARD_MANAGER_ERROR, + GSD_SMARTCARD_MANAGER_ERROR_WATCHING_FOR_EVENTS, + "%s", (condition & G_IO_IN) ? g_strerror (errno) : _("received error or hang up from event source")); + + gsd_smartcard_manager_emit_error (manager, error); + g_error_free (error); + gsd_smartcard_manager_stop_now (manager); + return FALSE; + } + + return TRUE; +} + +static void +gsd_smartcard_manager_event_processing_stopped_handler (GsdSmartcardManager *manager) +{ + manager->priv->smartcard_event_source = NULL; + gsd_smartcard_manager_stop_now (manager); +} + +static gboolean +open_pipe (int *write_fd, + int *read_fd) +{ + int pipe_fds[2] = { -1, -1 }; + + g_assert (write_fd != NULL); + g_assert (read_fd != NULL); + + if (pipe (pipe_fds) < 0) { + return FALSE; + } + + if (fcntl (pipe_fds[0], F_SETFD, FD_CLOEXEC) < 0) { + close (pipe_fds[0]); + close (pipe_fds[1]); + return FALSE; + } + + if (fcntl (pipe_fds[1], F_SETFD, FD_CLOEXEC) < 0) { + close (pipe_fds[0]); + close (pipe_fds[1]); + return FALSE; + } + + *read_fd = pipe_fds[0]; + *write_fd = pipe_fds[1]; + + return TRUE; +} + +static void +gsd_smartcard_manager_stop_watching_for_events (GsdSmartcardManager *manager) +{ + if (manager->priv->smartcard_event_source != NULL) { + g_source_destroy (manager->priv->smartcard_event_source); + manager->priv->smartcard_event_source = NULL; + } + + if (manager->priv->worker_thread != NULL) { + SECMOD_CancelWait (manager->priv->module); + manager->priv->worker_thread = NULL; + } +} + +static gboolean +load_nss (GError **error) +{ + SECStatus status = SECSuccess; + static const guint32 flags = + NSS_INIT_READONLY | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | + NSS_INIT_FORCEOPEN | NSS_INIT_NOROOTINIT | + NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD; + + g_debug ("attempting to load NSS database '%s'", + GSD_SMARTCARD_MANAGER_NSS_DB); + + status = NSS_Initialize (GSD_SMARTCARD_MANAGER_NSS_DB, + "", "", SECMOD_DB, flags); + + if (status != SECSuccess) { + gsize error_message_size; + char *error_message; + + error_message_size = PR_GetErrorTextLength (); + + if (error_message_size == 0) { + g_debug ("NSS security system could not be initialized"); + g_set_error (error, + GSD_SMARTCARD_MANAGER_ERROR, + GSD_SMARTCARD_MANAGER_ERROR_WITH_NSS, + _("NSS security system could not be initialized")); + goto out; + } + + error_message = g_slice_alloc0 (error_message_size); + PR_GetErrorText (error_message); + + g_set_error (error, + GSD_SMARTCARD_MANAGER_ERROR, + GSD_SMARTCARD_MANAGER_ERROR_WITH_NSS, + "%s", error_message); + g_debug ("NSS security system could not be initialized - %s", + error_message); + + g_slice_free1 (error_message_size, error_message); + + goto out; + } + + g_debug ("NSS database sucessfully loaded"); + return TRUE; + +out: + g_debug ("NSS database couldn't be sucessfully loaded"); + return FALSE; +} + +static SECMODModule * +load_driver (char *module_path, + GError **error) +{ + SECMODModule *module; + char *module_spec; + gboolean module_explicitly_specified; + + g_debug ("attempting to load driver..."); + + module = NULL; + module_explicitly_specified = module_path != NULL; + if (module_explicitly_specified) { + module_spec = g_strdup_printf ("library=\"%s\"", module_path); + g_debug ("loading smartcard driver using spec '%s'", + module_spec); + + module = SECMOD_LoadUserModule (module_spec, + NULL /* parent */, + FALSE /* recurse */); + g_free (module_spec); + module_spec = NULL; + + } else { + SECMODModuleList *modules, *tmp; + + modules = SECMOD_GetDefaultModuleList (); + + for (tmp = modules; tmp != NULL; tmp = tmp->next) { + if (!SECMOD_HasRemovableSlots (tmp->module) || + !tmp->module->loaded) + continue; + + module = SECMOD_ReferenceModule (tmp->module); + break; + } + } + + if (!module_explicitly_specified && module == NULL) { + g_set_error (error, + GSD_SMARTCARD_MANAGER_ERROR, + GSD_SMARTCARD_MANAGER_ERROR_LOADING_DRIVER, + _("no suitable smartcard driver could be found")); + } else if (module == NULL || !module->loaded) { + + gsize error_message_size; + char *error_message; + + if (module != NULL && !module->loaded) { + g_debug ("module found but not loaded?!"); + SECMOD_DestroyModule (module); + module = NULL; + } + + error_message_size = PR_GetErrorTextLength (); + + if (error_message_size == 0) { + g_debug ("smartcard driver '%s' could not be loaded", + module_path); + g_set_error (error, + GSD_SMARTCARD_MANAGER_ERROR, + GSD_SMARTCARD_MANAGER_ERROR_LOADING_DRIVER, + _("smartcard driver '%s' could not be " + "loaded"), module_path); + goto out; + } + + error_message = g_slice_alloc0 (error_message_size); + PR_GetErrorText (error_message); + + g_set_error (error, + GSD_SMARTCARD_MANAGER_ERROR, + GSD_SMARTCARD_MANAGER_ERROR_LOADING_DRIVER, + "%s", error_message); + + g_debug ("smartcard driver '%s' could not be loaded - %s", + module_path, error_message); + g_slice_free1 (error_message_size, error_message); + } + +out: + return module; +} + +static void +gsd_smartcard_manager_get_all_cards (GsdSmartcardManager *manager) +{ + int i; + + for (i = 0; i < manager->priv->module->slotCount; i++) { + GsdSmartcard *card; + CK_SLOT_ID slot_id; + int slot_series; + char *card_name; + + slot_id = PK11_GetSlotID (manager->priv->module->slots[i]); + slot_series = PK11_GetSlotSeries (manager->priv->module->slots[i]); + + card = _gsd_smartcard_new (manager->priv->module, + slot_id, slot_series); + + card_name = gsd_smartcard_get_name (card); + + g_hash_table_replace (manager->priv->smartcards, + card_name, card); + } +} + +gboolean +gsd_smartcard_manager_start (GsdSmartcardManager *manager, + GError **error) +{ + GError *watching_error; + int worker_fd; + GPid worker_pid; + GIOChannel *io_channel; + GSource *source; + GIOFlags channel_flags; + GError *nss_error; + + if (manager->priv->state == GSD_SMARTCARD_MANAGER_STATE_STARTED) { + g_debug ("smartcard manager already started"); + return TRUE; + } + + manager->priv->state = GSD_SMARTCARD_MANAGER_STATE_STARTING; + + worker_fd = -1; + worker_pid = 0; + + nss_error = NULL; + if (!manager->priv->nss_is_loaded && !load_nss (&nss_error)) { + g_propagate_error (error, nss_error); + goto out; + } + manager->priv->nss_is_loaded = TRUE; + + if (manager->priv->module == NULL) { + manager->priv->module = load_driver (manager->priv->module_path, &nss_error); + } + + if (manager->priv->module == NULL) { + g_propagate_error (error, nss_error); + goto out; + } + + if (!gsd_smartcard_manager_create_worker (manager, &worker_fd, &manager->priv->worker_thread)) { + + g_set_error (error, + GSD_SMARTCARD_MANAGER_ERROR, + GSD_SMARTCARD_MANAGER_ERROR_WATCHING_FOR_EVENTS, + _("could not watch for incoming card events - %s"), + g_strerror (errno)); + + goto out; + } + + io_channel = g_io_channel_unix_new (worker_fd); + + channel_flags = g_io_channel_get_flags (io_channel); + watching_error = NULL; + + source = g_io_create_watch (io_channel, G_IO_IN | G_IO_HUP); + g_io_channel_unref (io_channel); + io_channel = NULL; + + manager->priv->smartcard_event_source = source; + + g_source_set_callback (manager->priv->smartcard_event_source, + (GSourceFunc) (GIOFunc) + gsd_smartcard_manager_check_for_and_process_events, + manager, + (GDestroyNotify) + gsd_smartcard_manager_event_processing_stopped_handler); + g_source_attach (manager->priv->smartcard_event_source, NULL); + g_source_unref (manager->priv->smartcard_event_source); + + /* populate the hash with cards that are already inserted + */ + gsd_smartcard_manager_get_all_cards (manager); + + manager->priv->state = GSD_SMARTCARD_MANAGER_STATE_STARTED; + +out: + /* don't leave it in a half started state + */ + if (manager->priv->state != GSD_SMARTCARD_MANAGER_STATE_STARTED) { + g_debug ("smartcard manager could not be completely started"); + gsd_smartcard_manager_stop (manager); + } else { + g_debug ("smartcard manager started"); + } + + return manager->priv->state == GSD_SMARTCARD_MANAGER_STATE_STARTED; +} + +static gboolean +gsd_smartcard_manager_stop_now (GsdSmartcardManager *manager) +{ + if (manager->priv->state == GSD_SMARTCARD_MANAGER_STATE_STOPPED) { + return FALSE; + } + + manager->priv->state = GSD_SMARTCARD_MANAGER_STATE_STOPPED; + gsd_smartcard_manager_stop_watching_for_events (manager); + + if (manager->priv->module != NULL) { + SECMOD_DestroyModule (manager->priv->module); + manager->priv->module = NULL; + } + + if (manager->priv->nss_is_loaded) { + NSS_Shutdown (); + manager->priv->nss_is_loaded = FALSE; + } + + g_debug ("smartcard manager stopped"); + + return FALSE; +} + +static void +gsd_smartcard_manager_queue_stop (GsdSmartcardManager *manager) +{ + + manager->priv->state = GSD_SMARTCARD_MANAGER_STATE_STOPPING; + + g_idle_add ((GSourceFunc) gsd_smartcard_manager_stop_now, manager); +} + +void +gsd_smartcard_manager_stop (GsdSmartcardManager *manager) +{ + if (manager->priv->state == GSD_SMARTCARD_MANAGER_STATE_STOPPED) { + return; + } + + if (manager->priv->is_unstoppable) { + gsd_smartcard_manager_queue_stop (manager); + return; + } + + gsd_smartcard_manager_stop_now (manager); +} + +static void +gsd_smartcard_manager_check_for_login_card (CK_SLOT_ID slot_id, + GsdSmartcard *card, + gboolean *is_inserted) +{ + g_assert (is_inserted != NULL); + + if (gsd_smartcard_is_login_card (card)) { + *is_inserted = TRUE; + } + +} + +gboolean +gsd_smartcard_manager_login_card_is_inserted (GsdSmartcardManager *manager) + +{ + gboolean is_inserted; + + is_inserted = FALSE; + g_hash_table_foreach (manager->priv->smartcards, + (GHFunc) + gsd_smartcard_manager_check_for_login_card, + &is_inserted); + return is_inserted; +} + +static GsdSmartcardManagerWorker * +gsd_smartcard_manager_worker_new (int write_fd) +{ + GsdSmartcardManagerWorker *worker; + + worker = g_slice_new0 (GsdSmartcardManagerWorker); + worker->write_fd = write_fd; + worker->module = NULL; + + worker->smartcards = + g_hash_table_new_full ((GHashFunc) slot_id_hash, + (GEqualFunc) slot_id_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_object_unref); + + return worker; +} + +static void +gsd_smartcard_manager_worker_free (GsdSmartcardManagerWorker *worker) +{ + if (worker->smartcards != NULL) { + g_hash_table_destroy (worker->smartcards); + worker->smartcards = NULL; + } + + g_slice_free (GsdSmartcardManagerWorker, worker); +} + +static gboolean +read_bytes (int fd, + gpointer bytes, + gsize num_bytes) +{ + size_t bytes_left; + size_t total_bytes_read; + ssize_t bytes_read; + + bytes_left = (size_t) num_bytes; + total_bytes_read = 0; + + do { + bytes_read = read (fd, + (char *) bytes + total_bytes_read, + bytes_left); + g_assert (bytes_read <= (ssize_t) bytes_left); + + if (bytes_read <= 0) { + if ((bytes_read < 0) && (errno == EINTR || errno == EAGAIN)) { + continue; + } + + bytes_left = 0; + } else { + bytes_left -= bytes_read; + total_bytes_read += bytes_read; + } + } while (bytes_left > 0); + + if (total_bytes_read < (size_t) num_bytes) { + return FALSE; + } + + return TRUE; +} + +static gboolean +write_bytes (int fd, + gconstpointer bytes, + gsize num_bytes) +{ + size_t bytes_left; + size_t total_bytes_written; + ssize_t bytes_written; + + bytes_left = (size_t) num_bytes; + total_bytes_written = 0; + + do { + bytes_written = write (fd, + (char *) bytes + total_bytes_written, + bytes_left); + g_assert (bytes_written <= (ssize_t) bytes_left); + + if (bytes_written <= 0) { + if ((bytes_written < 0) && (errno == EINTR || errno == EAGAIN)) { + continue; + } + + bytes_left = 0; + } else { + bytes_left -= bytes_written; + total_bytes_written += bytes_written; + } + } while (bytes_left > 0); + + if (total_bytes_written < (size_t) num_bytes) { + return FALSE; + } + + return TRUE; +} + +static GsdSmartcard * +read_smartcard (int fd, + SECMODModule *module) +{ + GsdSmartcard *card; + char *card_name; + gsize card_name_size; + + card_name_size = 0; + if (!read_bytes (fd, &card_name_size, sizeof (card_name_size))) { + return NULL; + } + + card_name = g_slice_alloc0 (card_name_size); + if (!read_bytes (fd, card_name, card_name_size)) { + g_slice_free1 (card_name_size, card_name); + return NULL; + } + card = _gsd_smartcard_new_from_name (module, card_name); + g_slice_free1 (card_name_size, card_name); + + return card; +} + +static gboolean +write_smartcard (int fd, + GsdSmartcard *card) +{ + gsize card_name_size; + char *card_name; + + card_name = gsd_smartcard_get_name (card); + card_name_size = strlen (card_name) + 1; + + if (!write_bytes (fd, &card_name_size, sizeof (card_name_size))) { + g_free (card_name); + return FALSE; + } + + if (!write_bytes (fd, card_name, card_name_size)) { + g_free (card_name); + return FALSE; + } + g_free (card_name); + + return TRUE; +} + +static gboolean +gsd_smartcard_manager_worker_emit_smartcard_removed (GsdSmartcardManagerWorker *worker, + GsdSmartcard *card, + GError **error) +{ + g_debug ("card '%s' removed!", gsd_smartcard_get_name (card)); + + if (!write_bytes (worker->write_fd, "R", 1)) { + goto error_out; + } + + if (!write_smartcard (worker->write_fd, card)) { + goto error_out; + } + + return TRUE; + +error_out: + g_set_error (error, GSD_SMARTCARD_MANAGER_ERROR, + GSD_SMARTCARD_MANAGER_ERROR_REPORTING_EVENTS, + "%s", g_strerror (errno)); + return FALSE; +} + +static gboolean +gsd_smartcard_manager_worker_emit_smartcard_inserted (GsdSmartcardManagerWorker *worker, + GsdSmartcard *card, + GError **error) +{ + GError *write_error; + + write_error = NULL; + g_debug ("card '%s' inserted!", gsd_smartcard_get_name (card)); + if (!write_bytes (worker->write_fd, "I", 1)) { + goto error_out; + } + + if (!write_smartcard (worker->write_fd, card)) { + goto error_out; + } + + return TRUE; + +error_out: + g_set_error (error, GSD_SMARTCARD_MANAGER_ERROR, + GSD_SMARTCARD_MANAGER_ERROR_REPORTING_EVENTS, + "%s", g_strerror (errno)); + return FALSE; +} + +static gboolean +gsd_smartcard_manager_worker_watch_for_and_process_event (GsdSmartcardManagerWorker *worker, + GError **error) +{ + PK11SlotInfo *slot; + CK_SLOT_ID slot_id, *key; + int slot_series, card_slot_series; + GsdSmartcard *card; + GError *processing_error; + gboolean ret; + + g_debug ("waiting for card event"); + ret = FALSE; + + slot = SECMOD_WaitForAnyTokenEvent (worker->module, 0, PR_SecondsToInterval (1)); + processing_error = NULL; + + if (slot == NULL) { + int error_code; + + error_code = PORT_GetError (); + if ((error_code == 0) || (error_code == SEC_ERROR_NO_EVENT)) { + g_debug ("spurrious event occurred"); + return TRUE; + } + + /* FIXME: is there a function to convert from a PORT error + * code to a translated string? + */ + g_set_error (error, GSD_SMARTCARD_MANAGER_ERROR, + GSD_SMARTCARD_MANAGER_ERROR_WITH_NSS, + _("encountered unexpected error while " + "waiting for smartcard events")); + goto out; + } + + /* the slot id and series together uniquely identify a card. + * You can never have two cards with the same slot id at the + * same time, however (I think), so we can key off of it. + */ + slot_id = PK11_GetSlotID (slot); + slot_series = PK11_GetSlotSeries (slot); + + /* First check to see if there is a card that we're currently + * tracking in the slot. + */ + key = g_new (CK_SLOT_ID, 1); + *key = slot_id; + card = g_hash_table_lookup (worker->smartcards, key); + + if (card != NULL) { + card_slot_series = gsd_smartcard_get_slot_series (card); + } else { + card_slot_series = -1; + } + + if (PK11_IsPresent (slot)) { + /* Now, check to see if their is a new card in the slot. + * If there was a different card in the slot now than + * there was before, then we need to emit a removed signal + * for the old card (we don't want unpaired insertion events). + */ + if ((card != NULL) && + card_slot_series != slot_series) { + if (!gsd_smartcard_manager_worker_emit_smartcard_removed (worker, card, &processing_error)) { + g_propagate_error (error, processing_error); + goto out; + } + } + + card = _gsd_smartcard_new (worker->module, + slot_id, slot_series); + + g_hash_table_replace (worker->smartcards, + key, card); + key = NULL; + + if (!gsd_smartcard_manager_worker_emit_smartcard_inserted (worker, + card, + &processing_error)) { + g_propagate_error (error, processing_error); + goto out; + } + } else { + /* if we aren't tracking the card, just discard the event. + * We don't want unpaired remove events. Note on startup + * NSS will generate an "insertion" event if a card is + * already inserted in the slot. + */ + if ((card != NULL)) { + /* FIXME: i'm not sure about this code. Maybe we + * shouldn't do this at all, or maybe we should do it + * n times (where n = slot_series - card_slot_series + 1) + * + * Right now, i'm just doing it once. + */ + if ((slot_series - card_slot_series) > 1) { + + if (!gsd_smartcard_manager_worker_emit_smartcard_removed (worker, card, &processing_error)) { + g_propagate_error (error, processing_error); + goto out; + } + g_hash_table_remove (worker->smartcards, key); + + card = _gsd_smartcard_new (worker->module, + slot_id, slot_series); + g_hash_table_replace (worker->smartcards, + key, card); + key = NULL; + if (!gsd_smartcard_manager_worker_emit_smartcard_inserted (worker, card, &processing_error)) { + g_propagate_error (error, processing_error); + goto out; + } + } + + if (!gsd_smartcard_manager_worker_emit_smartcard_removed (worker, card, &processing_error)) { + g_propagate_error (error, processing_error); + goto out; + } + + g_hash_table_remove (worker->smartcards, key); + card = NULL; + } else { + g_debug ("got spurious remove event"); + } + } + + ret = TRUE; + +out: + g_free (key); + PK11_FreeSlot (slot); + + return ret; +} + +static void +gsd_smartcard_manager_worker_run (GsdSmartcardManagerWorker *worker) +{ + GError *error; + + + error = NULL; + + while (gsd_smartcard_manager_worker_watch_for_and_process_event (worker, &error)); + + if (error != NULL) { + g_debug ("could not process card event - %s", error->message); + g_error_free (error); + } + + gsd_smartcard_manager_worker_free (worker); +} + +static gboolean +gsd_smartcard_manager_create_worker (GsdSmartcardManager *manager, + int *worker_fd, + GThread **worker_thread) +{ + GsdSmartcardManagerWorker *worker; + int write_fd, read_fd; + + write_fd = -1; + read_fd = -1; + if (!open_pipe (&write_fd, &read_fd)) { + return FALSE; + } + + worker = gsd_smartcard_manager_worker_new (write_fd); + worker->module = manager->priv->module; + + *worker_thread = g_thread_create ((GThreadFunc) + gsd_smartcard_manager_worker_run, + worker, FALSE, NULL); + + if (*worker_thread == NULL) { + gsd_smartcard_manager_worker_free (worker); + return FALSE; + } + + if (worker_fd) { + *worker_fd = read_fd; + } + + return TRUE; +} + +#ifdef GSD_SMARTCARD_MANAGER_ENABLE_TEST +#include <glib.h> + +static GMainLoop *event_loop; +static gboolean should_exit_on_next_remove = FALSE; + +static gboolean +on_timeout (GsdSmartcardManager *manager) +{ + GError *error; + g_print ("Re-enabling manager.\n"); + + if (!gsd_smartcard_manager_start (manager, &error)) { + g_warning ("could not start smartcard manager - %s", + error->message); + g_error_free (error); + return 1; + } + g_print ("Please re-insert smartcard\n"); + + should_exit_on_next_remove = TRUE; + + return FALSE; +} + +static void +on_device_inserted (GsdSmartcardManager *manager, + GsdSmartcard *card) +{ + g_print ("smartcard inserted!\n"); + g_print ("Please remove it.\n"); +} + +static void +on_device_removed (GsdSmartcardManager *manager, + GsdSmartcard *card) +{ + g_print ("smartcard removed!\n"); + + if (should_exit_on_next_remove) { + g_main_loop_quit (event_loop); + } else { + g_print ("disabling manager for 2 seconds\n"); + gsd_smartcard_manager_stop (manager); + g_timeout_add (2000, (GSourceFunc) on_timeout, manager); + } +} + +int +main (int argc, + char *argv[]) +{ + GsdSmartcardManager *manager; + GError *error; + + g_log_set_always_fatal (G_LOG_LEVEL_ERROR + | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING); + + g_type_init (); + + g_message ("creating instance of 'smartcard manager' object..."); + manager = gsd_smartcard_manager_new (NULL); + g_message ("'smartcard manager' object created successfully"); + + g_signal_connect (manager, "smartcard-inserted", + G_CALLBACK (on_device_inserted), NULL); + + g_signal_connect (manager, "smartcard-removed", + G_CALLBACK (on_device_removed), NULL); + + g_message ("starting listener..."); + + error = NULL; + if (!gsd_smartcard_manager_start (manager, &error)) { + g_warning ("could not start smartcard manager - %s", + error->message); + g_error_free (error); + return 1; + } + + event_loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (event_loop); + g_main_loop_unref (event_loop); + event_loop = NULL; + + g_message ("destroying previously created 'smartcard manager' object..."); + g_object_unref (manager); + manager = NULL; + g_message ("'smartcard manager' object destroyed successfully"); + + return 0; +} +#endif diff --git a/plugins/smartcard/gsd-smartcard-manager.h b/plugins/smartcard/gsd-smartcard-manager.h new file mode 100644 index 0000000..9663124 --- /dev/null +++ b/plugins/smartcard/gsd-smartcard-manager.h @@ -0,0 +1,90 @@ +/* gsd-smartcard-manager.h - object for monitoring smartcard insertion and + * removal events + * + * Copyright (C) 2006, 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: Ray Strode + */ +#ifndef GSD_SMARTCARD_MANAGER_H +#define GSD_SMARTCARD_MANAGER_H + +#define GSD_SMARTCARD_ENABLE_INTERNAL_API +#include "gsd-smartcard.h" + +#include <glib.h> +#include <glib-object.h> + +#ifdef __cplusplus +extern "C" { +#endif +#define GSD_TYPE_SMARTCARD_MANAGER (gsd_smartcard_manager_get_type ()) +#define GSD_SMARTCARD_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSD_TYPE_SMARTCARD_MANAGER, GsdSmartcardManager)) +#define GSD_SMARTCARD_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSD_TYPE_SMARTCARD_MANAGER, GsdSmartcardManagerClass)) +#define GSD_IS_SMARTCARD_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_SMARTCARD_MANAGER)) +#define GSD_IS_SMARTCARD_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SC_TYPE_SMARTCARD_MANAGER)) +#define GSD_SMARTCARD_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GSD_TYPE_SMARTCARD_MANAGER, GsdSmartcardManagerClass)) +#define GSD_SMARTCARD_MANAGER_ERROR (gsd_smartcard_manager_error_quark ()) +typedef struct _GsdSmartcardManager GsdSmartcardManager; +typedef struct _GsdSmartcardManagerClass GsdSmartcardManagerClass; +typedef struct _GsdSmartcardManagerPrivate GsdSmartcardManagerPrivate; +typedef enum _GsdSmartcardManagerError GsdSmartcardManagerError; + +struct _GsdSmartcardManager { + GObject parent; + + /*< private > */ + GsdSmartcardManagerPrivate *priv; +}; + +struct _GsdSmartcardManagerClass { + GObjectClass parent_class; + + /* Signals */ + void (*smartcard_inserted) (GsdSmartcardManager *manager, + GsdSmartcard *token); + void (*smartcard_removed) (GsdSmartcardManager *manager, + GsdSmartcard *token); + void (*error) (GsdSmartcardManager *manager, + GError *error); +}; + +enum _GsdSmartcardManagerError { + GSD_SMARTCARD_MANAGER_ERROR_GENERIC = 0, + GSD_SMARTCARD_MANAGER_ERROR_WITH_NSS, + GSD_SMARTCARD_MANAGER_ERROR_LOADING_DRIVER, + GSD_SMARTCARD_MANAGER_ERROR_WATCHING_FOR_EVENTS, + GSD_SMARTCARD_MANAGER_ERROR_REPORTING_EVENTS +}; + +GType gsd_smartcard_manager_get_type (void) G_GNUC_CONST; +GQuark gsd_smartcard_manager_error_quark (void) G_GNUC_CONST; + +GsdSmartcardManager *gsd_smartcard_manager_new (const char *module); + +gboolean gsd_smartcard_manager_start (GsdSmartcardManager *manager, + GError **error); + +void gsd_smartcard_manager_stop (GsdSmartcardManager *manager); + +char *gsd_smartcard_manager_get_module_path (GsdSmartcardManager *manager); +gboolean gsd_smartcard_manager_login_card_is_inserted (GsdSmartcardManager *manager); + +#ifdef __cplusplus +} +#endif +#endif /* GSD_SMARTCARD_MANAGER_H */ diff --git a/plugins/smartcard/gsd-smartcard-plugin.c b/plugins/smartcard/gsd-smartcard-plugin.c new file mode 100644 index 0000000..9e3b4f2 --- /dev/null +++ b/plugins/smartcard/gsd-smartcard-plugin.c @@ -0,0 +1,340 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2010 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, 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 <glib/gi18n-lib.h> +#include <gmodule.h> + +#include <glib.h> +#include <glib-object.h> + +#include <dbus/dbus-glib.h> + +#include <mateconf/mateconf-client.h> + +#include "mate-settings-plugin.h" +#include "gsd-smartcard-plugin.h" +#include "gsd-smartcard-manager.h" + +struct GsdSmartcardPluginPrivate { + GsdSmartcardManager *manager; + DBusGConnection *bus_connection; + + guint32 is_active : 1; +}; + +typedef enum +{ + GSD_SMARTCARD_REMOVE_ACTION_NONE, + GSD_SMARTCARD_REMOVE_ACTION_LOCK_SCREEN, + GSD_SMARTCARD_REMOVE_ACTION_FORCE_LOGOUT, +} GsdSmartcardRemoveAction; + +#define SCREENSAVER_DBUS_NAME "org.mate.ScreenSaver" +#define SCREENSAVER_DBUS_PATH "/" +#define SCREENSAVER_DBUS_INTERFACE "org.mate.ScreenSaver" + +#define SM_DBUS_NAME "org.mate.SessionManager" +#define SM_DBUS_PATH "/org/mate/SessionManager" +#define SM_DBUS_INTERFACE "org.mate.SessionManager" +#define SM_LOGOUT_MODE_FORCE 2 + +#define GSD_SMARTCARD_KEY "/desktop/mate/peripherals/smartcard" +#define KEY_REMOVE_ACTION GSD_SMARTCARD_KEY "/removal_action" + +#define GSD_SMARTCARD_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSD_TYPE_SMARTCARD_PLUGIN, GsdSmartcardPluginPrivate)) + +MATE_SETTINGS_PLUGIN_REGISTER (GsdSmartcardPlugin, gsd_smartcard_plugin); + +static void +simulate_user_activity (GsdSmartcardPlugin *plugin) +{ + DBusGProxy *screensaver_proxy; + + g_debug ("GsdSmartcardPlugin telling screensaver about smart card insertion"); + screensaver_proxy = dbus_g_proxy_new_for_name (plugin->priv->bus_connection, + SCREENSAVER_DBUS_NAME, + SCREENSAVER_DBUS_PATH, + SCREENSAVER_DBUS_INTERFACE); + + dbus_g_proxy_call_no_reply (screensaver_proxy, + "SimulateUserActivity", + G_TYPE_INVALID, G_TYPE_INVALID); + + g_object_unref (screensaver_proxy); +} + +static void +lock_screen (GsdSmartcardPlugin *plugin) +{ + DBusGProxy *screensaver_proxy; + + g_debug ("GsdSmartcardPlugin telling screensaver to lock screen"); + screensaver_proxy = dbus_g_proxy_new_for_name (plugin->priv->bus_connection, + SCREENSAVER_DBUS_NAME, + SCREENSAVER_DBUS_PATH, + SCREENSAVER_DBUS_INTERFACE); + + dbus_g_proxy_call_no_reply (screensaver_proxy, + "Lock", + G_TYPE_INVALID, G_TYPE_INVALID); + + g_object_unref (screensaver_proxy); +} + +static void +force_logout (GsdSmartcardPlugin *plugin) +{ + DBusGProxy *sm_proxy; + GError *error; + gboolean res; + + g_debug ("GsdSmartcardPlugin telling session manager to force logout"); + sm_proxy = dbus_g_proxy_new_for_name (plugin->priv->bus_connection, + SM_DBUS_NAME, + SM_DBUS_PATH, + SM_DBUS_INTERFACE); + + error = NULL; + res = dbus_g_proxy_call (sm_proxy, + "Logout", + &error, + G_TYPE_UINT, SM_LOGOUT_MODE_FORCE, + G_TYPE_INVALID, G_TYPE_INVALID); + + if (! res) { + g_warning ("GsdSmartcardPlugin Unable to force logout: %s", error->message); + g_error_free (error); + } + + g_object_unref (sm_proxy); +} + +static void +gsd_smartcard_plugin_init (GsdSmartcardPlugin *plugin) +{ + plugin->priv = GSD_SMARTCARD_PLUGIN_GET_PRIVATE (plugin); + + g_debug ("GsdSmartcardPlugin initializing"); + + plugin->priv->manager = gsd_smartcard_manager_new (NULL); +} + +static void +gsd_smartcard_plugin_finalize (GObject *object) +{ + GsdSmartcardPlugin *plugin; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_SMARTCARD_PLUGIN (object)); + + g_debug ("GsdSmartcardPlugin finalizing"); + + plugin = GSD_SMARTCARD_PLUGIN (object); + + g_return_if_fail (plugin->priv != NULL); + + if (plugin->priv->manager != NULL) { + g_object_unref (plugin->priv->manager); + } + + G_OBJECT_CLASS (gsd_smartcard_plugin_parent_class)->finalize (object); +} + +static void +smartcard_inserted_cb (GsdSmartcardManager *card_monitor, + GsdSmartcard *card, + GsdSmartcardPlugin *plugin) +{ + char *name; + + name = gsd_smartcard_get_name (card); + g_debug ("GsdSmartcardPlugin smart card '%s' inserted", name); + g_free (name); + + simulate_user_activity (plugin); +} + +static gboolean +user_logged_in_with_smartcard (void) +{ + return g_getenv ("PKCS11_LOGIN_TOKEN_NAME") != NULL; +} + +static GsdSmartcardRemoveAction +get_configured_remove_action (GsdSmartcardPlugin *plugin) +{ + MateConfClient *client; + char *remove_action_string; + GsdSmartcardRemoveAction remove_action; + + client = mateconf_client_get_default (); + remove_action_string = mateconf_client_get_string (client, + KEY_REMOVE_ACTION, NULL); + + if (remove_action_string == NULL) { + g_warning ("GsdSmartcardPlugin unable to get smartcard remove action"); + remove_action = GSD_SMARTCARD_REMOVE_ACTION_NONE; + } else if (strcmp (remove_action_string, "none") == 0) { + remove_action = GSD_SMARTCARD_REMOVE_ACTION_NONE; + } else if (strcmp (remove_action_string, "lock_screen") == 0) { + remove_action = GSD_SMARTCARD_REMOVE_ACTION_LOCK_SCREEN; + } else if (strcmp (remove_action_string, "force_logout") == 0) { + remove_action = GSD_SMARTCARD_REMOVE_ACTION_FORCE_LOGOUT; + } else { + g_warning ("GsdSmartcardPlugin unknown smartcard remove action"); + remove_action = GSD_SMARTCARD_REMOVE_ACTION_NONE; + } + + g_object_unref (client); + + return remove_action; +} + +static void +process_smartcard_removal (GsdSmartcardPlugin *plugin) +{ + GsdSmartcardRemoveAction remove_action; + + g_debug ("GsdSmartcardPlugin processing smartcard removal"); + remove_action = get_configured_remove_action (plugin); + + switch (remove_action) + { + case GSD_SMARTCARD_REMOVE_ACTION_NONE: + return; + case GSD_SMARTCARD_REMOVE_ACTION_LOCK_SCREEN: + lock_screen (plugin); + break; + case GSD_SMARTCARD_REMOVE_ACTION_FORCE_LOGOUT: + force_logout (plugin); + break; + } +} + +static void +smartcard_removed_cb (GsdSmartcardManager *card_monitor, + GsdSmartcard *card, + GsdSmartcardPlugin *plugin) +{ + + char *name; + + name = gsd_smartcard_get_name (card); + g_debug ("GsdSmartcardPlugin smart card '%s' removed", name); + g_free (name); + + if (!gsd_smartcard_is_login_card (card)) { + g_debug ("GsdSmartcardPlugin removed smart card was not used to login"); + return; + } + + process_smartcard_removal (plugin); +} + +static void +impl_activate (MateSettingsPlugin *plugin) +{ + GError *error; + GsdSmartcardPlugin *smartcard_plugin = GSD_SMARTCARD_PLUGIN (plugin); + + if (smartcard_plugin->priv->is_active) { + g_debug ("GsdSmartcardPlugin Not activating smartcard plugin, because it's " + "already active"); + return; + } + + if (!user_logged_in_with_smartcard ()) { + g_debug ("GsdSmartcardPlugin Not activating smartcard plugin, because user didn't use " + " smartcard to log in"); + smartcard_plugin->priv->is_active = FALSE; + return; + } + + g_debug ("GsdSmartcardPlugin Activating smartcard plugin"); + + error = NULL; + smartcard_plugin->priv->bus_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + + if (smartcard_plugin->priv->bus_connection == NULL) { + g_warning ("GsdSmartcardPlugin Unable to connect to session bus: %s", error->message); + return; + } + + if (!gsd_smartcard_manager_start (smartcard_plugin->priv->manager, &error)) { + g_warning ("GsdSmartcardPlugin Unable to start smartcard manager: %s", error->message); + g_error_free (error); + } + + g_signal_connect (smartcard_plugin->priv->manager, + "smartcard-removed", + G_CALLBACK (smartcard_removed_cb), smartcard_plugin); + + g_signal_connect (smartcard_plugin->priv->manager, + "smartcard-inserted", + G_CALLBACK (smartcard_inserted_cb), smartcard_plugin); + + if (!gsd_smartcard_manager_login_card_is_inserted (smartcard_plugin->priv->manager)) { + g_debug ("GsdSmartcardPlugin processing smartcard removal immediately user logged in with smartcard " + "and it's not inserted"); + process_smartcard_removal (smartcard_plugin); + } + + smartcard_plugin->priv->is_active = TRUE; +} + +static void +impl_deactivate (MateSettingsPlugin *plugin) +{ + GsdSmartcardPlugin *smartcard_plugin = GSD_SMARTCARD_PLUGIN (plugin); + + if (!smartcard_plugin->priv->is_active) { + g_debug ("GsdSmartcardPlugin Not deactivating smartcard plugin, " + "because it's already inactive"); + return; + } + + g_debug ("GsdSmartcardPlugin Deactivating smartcard plugin"); + + gsd_smartcard_manager_stop (smartcard_plugin->priv->manager); + + g_signal_handlers_disconnect_by_func (smartcard_plugin->priv->manager, + smartcard_removed_cb, smartcard_plugin); + + g_signal_handlers_disconnect_by_func (smartcard_plugin->priv->manager, + smartcard_inserted_cb, smartcard_plugin); + smartcard_plugin->priv->bus_connection = NULL; + smartcard_plugin->priv->is_active = FALSE; +} + +static void +gsd_smartcard_plugin_class_init (GsdSmartcardPluginClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MateSettingsPluginClass *plugin_class = MATE_SETTINGS_PLUGIN_CLASS (klass); + + object_class->finalize = gsd_smartcard_plugin_finalize; + + plugin_class->activate = impl_activate; + plugin_class->deactivate = impl_deactivate; + + g_type_class_add_private (klass, sizeof (GsdSmartcardPluginPrivate)); +} diff --git a/plugins/smartcard/gsd-smartcard-plugin.h b/plugins/smartcard/gsd-smartcard-plugin.h new file mode 100644 index 0000000..4c61686 --- /dev/null +++ b/plugins/smartcard/gsd-smartcard-plugin.h @@ -0,0 +1,63 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2010 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, 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_SMARTCARD_PLUGIN_H__ +#define __GSD_SMARTCARD_PLUGIN_H__ + +#include <glib.h> +#include <glib-object.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_SMARTCARD_PLUGIN (gsd_smartcard_plugin_get_type ()) +#define GSD_SMARTCARD_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_SMARTCARD_PLUGIN, GsdSmartcardPlugin)) +#define GSD_SMARTCARD_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GSD_TYPE_SMARTCARD_PLUGIN, GsdSmartcardPluginClass)) +#define GSD_IS_SMARTCARD_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_SMARTCARD_PLUGIN)) +#define GSD_IS_SMARTCARD_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_SMARTCARD_PLUGIN)) +#define GSD_SMARTCARD_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_SMARTCARD_PLUGIN, GsdSmartcardPluginClass)) + +typedef struct GsdSmartcardPluginPrivate GsdSmartcardPluginPrivate; + +typedef struct +{ + MateSettingsPlugin parent; + GsdSmartcardPluginPrivate *priv; +} GsdSmartcardPlugin; + +typedef struct +{ + MateSettingsPluginClass parent_class; +} GsdSmartcardPluginClass; + +GType gsd_smartcard_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_SMARTCARD_PLUGIN_H__ */ diff --git a/plugins/smartcard/gsd-smartcard.c b/plugins/smartcard/gsd-smartcard.c new file mode 100644 index 0000000..22f4e12 --- /dev/null +++ b/plugins/smartcard/gsd-smartcard.c @@ -0,0 +1,555 @@ +/* gsd-smartcard.c - smartcard object + * + * Copyright (C) 2006 Ray Strode <[email protected]> + * + * 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. + */ +#define GSD_SMARTCARD_ENABLE_INTERNAL_API +#include "gsd-smartcard.h" + +#include <errno.h> +#include <string.h> +#include <unistd.h> + +#include <glib.h> +#include <glib/gi18n.h> + +#include <cert.h> +#include <nss.h> +#include <pk11func.h> +#include <prerror.h> +#include <secmod.h> +#include <secerr.h> + +struct _GsdSmartcardPrivate { + SECMODModule *module; + GsdSmartcardState state; + + CK_SLOT_ID slot_id; + int slot_series; + + PK11SlotInfo *slot; + char *name; + + CERTCertificate *signing_certificate; + CERTCertificate *encryption_certificate; +}; + +static void gsd_smartcard_finalize (GObject *object); +static void gsd_smartcard_class_install_signals (GsdSmartcardClass *card_class); +static void gsd_smartcard_class_install_properties (GsdSmartcardClass *card_class); +static void gsd_smartcard_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gsd_smartcard_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void gsd_smartcard_set_name (GsdSmartcard *card, const char *name); +static void gsd_smartcard_set_slot_id (GsdSmartcard *card, + int slot_id); +static void gsd_smartcard_set_slot_series (GsdSmartcard *card, + int slot_series); +static void gsd_smartcard_set_module (GsdSmartcard *card, + SECMODModule *module); + +static PK11SlotInfo *gsd_smartcard_find_slot_from_id (GsdSmartcard *card, + int slot_id); + +static PK11SlotInfo *gsd_smartcard_find_slot_from_card_name (GsdSmartcard *card, + const char *card_name); +#ifndef GSD_SMARTCARD_DEFAULT_SLOT_ID +#define GSD_SMARTCARD_DEFAULT_SLOT_ID ((gulong) -1) +#endif + +#ifndef GSD_SMARTCARD_DEFAULT_SLOT_SERIES +#define GSD_SMARTCARD_DEFAULT_SLOT_SERIES -1 +#endif + +enum { + PROP_0 = 0, + PROP_NAME, + PROP_SLOT_ID, + PROP_SLOT_SERIES, + PROP_MODULE, + NUMBER_OF_PROPERTIES +}; + +enum { + INSERTED, + REMOVED, + NUMBER_OF_SIGNALS +}; + +static guint gsd_smartcard_signals[NUMBER_OF_SIGNALS]; + +G_DEFINE_TYPE (GsdSmartcard, gsd_smartcard, G_TYPE_OBJECT); + +static void +gsd_smartcard_class_init (GsdSmartcardClass *card_class) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (card_class); + + gobject_class->finalize = gsd_smartcard_finalize; + + gsd_smartcard_class_install_signals (card_class); + gsd_smartcard_class_install_properties (card_class); + + g_type_class_add_private (card_class, + sizeof (GsdSmartcardPrivate)); +} + +static void +gsd_smartcard_class_install_signals (GsdSmartcardClass *card_class) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (card_class); + + gsd_smartcard_signals[INSERTED] = + g_signal_new ("inserted", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GsdSmartcardClass, + inserted), + NULL, NULL, g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + gsd_smartcard_signals[REMOVED] = + g_signal_new ("removed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GsdSmartcardClass, + removed), + NULL, NULL, g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +gsd_smartcard_class_install_properties (GsdSmartcardClass *card_class) +{ + GObjectClass *object_class; + GParamSpec *param_spec; + + object_class = G_OBJECT_CLASS (card_class); + object_class->set_property = gsd_smartcard_set_property; + object_class->get_property = gsd_smartcard_get_property; + + param_spec = g_param_spec_ulong ("slot-id", _("Slot ID"), + _("The slot the card is in"), + 1, G_MAXULONG, + GSD_SMARTCARD_DEFAULT_SLOT_ID, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, PROP_SLOT_ID, param_spec); + + param_spec = g_param_spec_int ("slot-series", _("Slot Series"), + _("per-slot card identifier"), + -1, G_MAXINT, + GSD_SMARTCARD_DEFAULT_SLOT_SERIES, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, PROP_SLOT_SERIES, param_spec); + + param_spec = g_param_spec_string ("name", _("name"), + _("name"), NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, PROP_NAME, param_spec); + + param_spec = g_param_spec_pointer ("module", _("Module"), + _("smartcard driver"), + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, PROP_MODULE, param_spec); +} + +static void +gsd_smartcard_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GsdSmartcard *card = GSD_SMARTCARD (object); + + switch (prop_id) { + case PROP_NAME: + gsd_smartcard_set_name (card, g_value_get_string (value)); + break; + + case PROP_SLOT_ID: + gsd_smartcard_set_slot_id (card, + g_value_get_ulong (value)); + break; + + case PROP_SLOT_SERIES: + gsd_smartcard_set_slot_series (card, + g_value_get_int (value)); + break; + + case PROP_MODULE: + gsd_smartcard_set_module (card, + (SECMODModule *) + g_value_get_pointer (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +CK_SLOT_ID +gsd_smartcard_get_slot_id (GsdSmartcard *card) +{ + return card->priv->slot_id; +} + +GsdSmartcardState +gsd_smartcard_get_state (GsdSmartcard *card) +{ + return card->priv->state; +} + +char * +gsd_smartcard_get_name (GsdSmartcard *card) +{ + return g_strdup (card->priv->name); +} + +gboolean +gsd_smartcard_is_login_card (GsdSmartcard *card) +{ + const char *login_card_name; + login_card_name = g_getenv ("PKCS11_LOGIN_TOKEN_NAME"); + + if ((login_card_name == NULL) || (card->priv->name == NULL)) { + return FALSE; + } + + if (strcmp (card->priv->name, login_card_name) == 0) { + return TRUE; + } + + return FALSE; +} + +static void +gsd_smartcard_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GsdSmartcard *card = GSD_SMARTCARD (object); + + switch (prop_id) { + case PROP_NAME: + g_value_take_string (value, + gsd_smartcard_get_name (card)); + break; + + case PROP_SLOT_ID: + g_value_set_ulong (value, + (gulong) gsd_smartcard_get_slot_id (card)); + break; + + case PROP_SLOT_SERIES: + g_value_set_int (value, + gsd_smartcard_get_slot_series (card)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gsd_smartcard_set_name (GsdSmartcard *card, + const char *name) +{ + if (name == NULL) { + return; + } + + if ((card->priv->name == NULL) || + (strcmp (card->priv->name, name) != 0)) { + g_free (card->priv->name); + card->priv->name = g_strdup (name); + + if (card->priv->slot == NULL) { + card->priv->slot = gsd_smartcard_find_slot_from_card_name (card, + card->priv->name); + + if (card->priv->slot != NULL) { + int slot_id, slot_series; + + slot_id = PK11_GetSlotID (card->priv->slot); + if (slot_id != card->priv->slot_id) { + gsd_smartcard_set_slot_id (card, slot_id); + } + + slot_series = PK11_GetSlotSeries (card->priv->slot); + if (slot_series != card->priv->slot_series) { + gsd_smartcard_set_slot_series (card, slot_series); + } + + _gsd_smartcard_set_state (card, GSD_SMARTCARD_STATE_INSERTED); + } else { + _gsd_smartcard_set_state (card, GSD_SMARTCARD_STATE_REMOVED); + } + } + + g_object_notify (G_OBJECT (card), "name"); + } +} + +static void +gsd_smartcard_set_slot_id (GsdSmartcard *card, + int slot_id) +{ + if (card->priv->slot_id != slot_id) { + card->priv->slot_id = slot_id; + + if (card->priv->slot == NULL) { + card->priv->slot = gsd_smartcard_find_slot_from_id (card, + card->priv->slot_id); + + if (card->priv->slot != NULL) { + const char *card_name; + + card_name = PK11_GetTokenName (card->priv->slot); + if ((card->priv->name == NULL) || + ((card_name != NULL) && + (strcmp (card_name, card->priv->name) != 0))) { + gsd_smartcard_set_name (card, card_name); + } + + _gsd_smartcard_set_state (card, GSD_SMARTCARD_STATE_INSERTED); + } else { + _gsd_smartcard_set_state (card, GSD_SMARTCARD_STATE_REMOVED); + } + } + + g_object_notify (G_OBJECT (card), "slot-id"); + } +} + +static void +gsd_smartcard_set_slot_series (GsdSmartcard *card, + int slot_series) +{ + if (card->priv->slot_series != slot_series) { + card->priv->slot_series = slot_series; + g_object_notify (G_OBJECT (card), "slot-series"); + } +} + +static void +gsd_smartcard_set_module (GsdSmartcard *card, + SECMODModule *module) +{ + gboolean should_notify; + + if (card->priv->module != module) { + should_notify = TRUE; + } else { + should_notify = FALSE; + } + + if (card->priv->module != NULL) { + SECMOD_DestroyModule (card->priv->module); + card->priv->module = NULL; + } + + if (module != NULL) { + card->priv->module = SECMOD_ReferenceModule (module); + } + + if (should_notify) { + g_object_notify (G_OBJECT (card), "module"); + } +} + +int +gsd_smartcard_get_slot_series (GsdSmartcard *card) +{ + return card->priv->slot_series; +} + +static void +gsd_smartcard_init (GsdSmartcard *card) +{ + + g_debug ("initializing smartcard "); + + card->priv = G_TYPE_INSTANCE_GET_PRIVATE (card, + GSD_TYPE_SMARTCARD, + GsdSmartcardPrivate); + + if (card->priv->slot != NULL) { + card->priv->name = g_strdup (PK11_GetTokenName (card->priv->slot)); + } +} + +static void gsd_smartcard_finalize (GObject *object) +{ + GsdSmartcard *card; + GObjectClass *gobject_class; + + card = GSD_SMARTCARD (object); + + g_free (card->priv->name); + + gsd_smartcard_set_module (card, NULL); + + gobject_class = G_OBJECT_CLASS (gsd_smartcard_parent_class); + + gobject_class->finalize (object); +} + +GQuark gsd_smartcard_error_quark (void) +{ + static GQuark error_quark = 0; + + if (error_quark == 0) { + error_quark = g_quark_from_static_string ("gsd-smartcard-error-quark"); + } + + return error_quark; +} + +GsdSmartcard * +_gsd_smartcard_new (SECMODModule *module, + CK_SLOT_ID slot_id, + int slot_series) +{ + GsdSmartcard *card; + + g_return_val_if_fail (module != NULL, NULL); + g_return_val_if_fail (slot_id >= 1, NULL); + g_return_val_if_fail (slot_series > 0, NULL); + g_return_val_if_fail (sizeof (gulong) == sizeof (slot_id), NULL); + + card = GSD_SMARTCARD (g_object_new (GSD_TYPE_SMARTCARD, + "module", module, + "slot-id", (gulong) slot_id, + "slot-series", slot_series, + NULL)); + return card; +} + +GsdSmartcard * +_gsd_smartcard_new_from_name (SECMODModule *module, + const char *name) +{ + GsdSmartcard *card; + + g_return_val_if_fail (module != NULL, NULL); + g_return_val_if_fail (name != NULL, NULL); + + card = GSD_SMARTCARD (g_object_new (GSD_TYPE_SMARTCARD, + "module", module, + "name", name, + NULL)); + return card; +} + +void +_gsd_smartcard_set_state (GsdSmartcard *card, + GsdSmartcardState state) +{ + if (card->priv->state != state) { + card->priv->state = state; + + if (state == GSD_SMARTCARD_STATE_INSERTED) { + g_signal_emit (card, gsd_smartcard_signals[INSERTED], 0); + } else if (state == GSD_SMARTCARD_STATE_REMOVED) { + g_signal_emit (card, gsd_smartcard_signals[REMOVED], 0); + } else { + g_assert_not_reached (); + } + } +} + +/* So we could conceivably make the closure data a pointer to the card + * or something similiar and then emit signals when we want passwords, + * but it's probably easier to just get the password up front and use + * it. So we just take the passed in g_malloc'd (well probably, who knows) + * and strdup it using NSPR's memory allocation routines. + */ +static char * +gsd_smartcard_password_handler (PK11SlotInfo *slot, + PRBool is_retrying, + const char *password) +{ + if (is_retrying) { + return NULL; + } + + return password != NULL? PL_strdup (password): NULL; +} + +gboolean +gsd_smartcard_unlock (GsdSmartcard *card, + const char *password) +{ + SECStatus status; + + PK11_SetPasswordFunc ((PK11PasswordFunc) gsd_smartcard_password_handler); + + /* we pass PR_TRUE to load certificates + */ + status = PK11_Authenticate (card->priv->slot, PR_TRUE, (gpointer) password); + + if (status != SECSuccess) { + g_debug ("could not unlock card - %d", status); + return FALSE; + } + return TRUE; +} + +static PK11SlotInfo * +gsd_smartcard_find_slot_from_card_name (GsdSmartcard *card, + const char *card_name) +{ + int i; + + for (i = 0; i < card->priv->module->slotCount; i++) { + const char *slot_card_name; + + slot_card_name = PK11_GetTokenName (card->priv->module->slots[i]); + + if ((slot_card_name != NULL) && + (strcmp (slot_card_name, card_name) == 0)) { + return card->priv->module->slots[i]; + } + } + + return NULL; +} + +static PK11SlotInfo * +gsd_smartcard_find_slot_from_id (GsdSmartcard *card, + int slot_id) +{ + int i; + + for (i = 0; i < card->priv->module->slotCount; i++) { + if (PK11_GetSlotID (card->priv->module->slots[i]) == slot_id) { + return card->priv->module->slots[i]; + } + } + + return NULL; +} diff --git a/plugins/smartcard/gsd-smartcard.h b/plugins/smartcard/gsd-smartcard.h new file mode 100644 index 0000000..c8c1ea7 --- /dev/null +++ b/plugins/smartcard/gsd-smartcard.h @@ -0,0 +1,98 @@ +/* securitycard.h - api for reading and writing data to a security card + * + * Copyright (C) 2006 Ray Strode + * + * 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_SMARTCARD_H +#define GSD_SMARTCARD_H + +#include <glib.h> +#include <glib-object.h> + +#include <secmod.h> + +#ifdef __cplusplus +extern "C" { +#endif +#define GSD_TYPE_SMARTCARD (gsd_smartcard_get_type ()) +#define GSD_SMARTCARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSD_TYPE_SMARTCARD, GsdSmartcard)) +#define GSD_SMARTCARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSD_TYPE_SMARTCARD, GsdSmartcardClass)) +#define GSD_IS_SMARTCARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSD_TYPE_SMARTCARD)) +#define GSD_IS_SMARTCARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSD_TYPE_SMARTCARD)) +#define GSD_SMARTCARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GSD_TYPE_SMARTCARD, GsdSmartcardClass)) +#define GSD_SMARTCARD_ERROR (gsd_smartcard_error_quark ()) +typedef struct _GsdSmartcardClass GsdSmartcardClass; +typedef struct _GsdSmartcard GsdSmartcard; +typedef struct _GsdSmartcardPrivate GsdSmartcardPrivate; +typedef enum _GsdSmartcardError GsdSmartcardError; +typedef enum _GsdSmartcardState GsdSmartcardState; + +typedef struct _GsdSmartcardRequest GsdSmartcardRequest; + +struct _GsdSmartcard { + GObject parent; + + /*< private > */ + GsdSmartcardPrivate *priv; +}; + +struct _GsdSmartcardClass { + GObjectClass parent_class; + + void (* inserted) (GsdSmartcard *card); + void (* removed) (GsdSmartcard *card); +}; + +enum _GsdSmartcardError { + GSD_SMARTCARD_ERROR_GENERIC = 0, +}; + +enum _GsdSmartcardState { + GSD_SMARTCARD_STATE_INSERTED = 0, + GSD_SMARTCARD_STATE_REMOVED, +}; + +GType gsd_smartcard_get_type (void) G_GNUC_CONST; +GQuark gsd_smartcard_error_quark (void) G_GNUC_CONST; + +CK_SLOT_ID gsd_smartcard_get_slot_id (GsdSmartcard *card); +gint gsd_smartcard_get_slot_series (GsdSmartcard *card); +GsdSmartcardState gsd_smartcard_get_state (GsdSmartcard *card); + +char *gsd_smartcard_get_name (GsdSmartcard *card); +gboolean gsd_smartcard_is_login_card (GsdSmartcard *card); + +gboolean gsd_smartcard_unlock (GsdSmartcard *card, + const char *password); + +/* don't under any circumstances call these functions */ +#ifdef GSD_SMARTCARD_ENABLE_INTERNAL_API + +GsdSmartcard *_gsd_smartcard_new (SECMODModule *module, + CK_SLOT_ID slot_id, + gint slot_series); +GsdSmartcard *_gsd_smartcard_new_from_name (SECMODModule *module, + const char *name); + +void _gsd_smartcard_set_state (GsdSmartcard *card, + GsdSmartcardState state); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* GSD_SMARTCARD_H */ diff --git a/plugins/smartcard/smartcard.mate-settings-plugin.in b/plugins/smartcard/smartcard.mate-settings-plugin.in new file mode 100644 index 0000000..dd75784 --- /dev/null +++ b/plugins/smartcard/smartcard.mate-settings-plugin.in @@ -0,0 +1,8 @@ +[MATE Settings Plugin] +Module=smartcard +IAge=0 +_Name=Smartcard +_Description=Smartcard plugin +Authors=Ray Strode +Copyright=Copyright © 2010 Red Hat, Inc. +Website= diff --git a/plugins/sound/Makefile.am b/plugins/sound/Makefile.am new file mode 100644 index 0000000..7caf2ac --- /dev/null +++ b/plugins/sound/Makefile.am @@ -0,0 +1,42 @@ +plugin_LTLIBRARIES = \ + libsound.la + +libsound_la_SOURCES = \ + gsd-sound-plugin.h \ + gsd-sound-plugin.c \ + gsd-sound-manager.h \ + gsd-sound-manager.c + +libsound_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libsound_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(MATE_CFLAGS) \ + $(PULSE_CFLAGS) \ + $(AM_CFLAGS) + +libsound_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) + +libsound_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(PULSE_LIBS) + +plugin_in_files = \ + sound.mate-settings-plugin.in + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) + +EXTRA_DIST = \ + $(plugin_in_files) + +CLEANFILES = \ + $(plugin_DATA) + +DISTCLEANFILES = \ + $(plugin_DATA) + +@GSD_INTLTOOL_PLUGIN_RULE@ diff --git a/plugins/sound/Makefile.in b/plugins/sound/Makefile.in new file mode 100644 index 0000000..1656268 --- /dev/null +++ b/plugins/sound/Makefile.in @@ -0,0 +1,669 @@ +# 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/sound +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)$(plugindir)" +LTLIBRARIES = $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +libsound_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_libsound_la_OBJECTS = libsound_la-gsd-sound-plugin.lo \ + libsound_la-gsd-sound-manager.lo +libsound_la_OBJECTS = $(am_libsound_la_OBJECTS) +libsound_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libsound_la_CFLAGS) \ + $(CFLAGS) $(libsound_la_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 = $(libsound_la_SOURCES) +DIST_SOURCES = $(libsound_la_SOURCES) +DATA = $(plugin_DATA) +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@ +plugin_LTLIBRARIES = \ + libsound.la + +libsound_la_SOURCES = \ + gsd-sound-plugin.h \ + gsd-sound-plugin.c \ + gsd-sound-manager.h \ + gsd-sound-manager.c + +libsound_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libsound_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(MATE_CFLAGS) \ + $(PULSE_CFLAGS) \ + $(AM_CFLAGS) + +libsound_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) + +libsound_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(PULSE_LIBS) + +plugin_in_files = \ + sound.mate-settings-plugin.in + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) +EXTRA_DIST = \ + $(plugin_in_files) + +CLEANFILES = \ + $(plugin_DATA) + +DISTCLEANFILES = \ + $(plugin_DATA) + +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/sound/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plugins/sound/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 +libsound.la: $(libsound_la_OBJECTS) $(libsound_la_DEPENDENCIES) + $(libsound_la_LINK) -rpath $(plugindir) $(libsound_la_OBJECTS) $(libsound_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsound_la-gsd-sound-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsound_la-gsd-sound-plugin.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 $@ $< + +libsound_la-gsd-sound-plugin.lo: gsd-sound-plugin.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsound_la_CPPFLAGS) $(CPPFLAGS) $(libsound_la_CFLAGS) $(CFLAGS) -MT libsound_la-gsd-sound-plugin.lo -MD -MP -MF $(DEPDIR)/libsound_la-gsd-sound-plugin.Tpo -c -o libsound_la-gsd-sound-plugin.lo `test -f 'gsd-sound-plugin.c' || echo '$(srcdir)/'`gsd-sound-plugin.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libsound_la-gsd-sound-plugin.Tpo $(DEPDIR)/libsound_la-gsd-sound-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-sound-plugin.c' object='libsound_la-gsd-sound-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) $(libsound_la_CPPFLAGS) $(CPPFLAGS) $(libsound_la_CFLAGS) $(CFLAGS) -c -o libsound_la-gsd-sound-plugin.lo `test -f 'gsd-sound-plugin.c' || echo '$(srcdir)/'`gsd-sound-plugin.c + +libsound_la-gsd-sound-manager.lo: gsd-sound-manager.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsound_la_CPPFLAGS) $(CPPFLAGS) $(libsound_la_CFLAGS) $(CFLAGS) -MT libsound_la-gsd-sound-manager.lo -MD -MP -MF $(DEPDIR)/libsound_la-gsd-sound-manager.Tpo -c -o libsound_la-gsd-sound-manager.lo `test -f 'gsd-sound-manager.c' || echo '$(srcdir)/'`gsd-sound-manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libsound_la-gsd-sound-manager.Tpo $(DEPDIR)/libsound_la-gsd-sound-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-sound-manager.c' object='libsound_la-gsd-sound-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) $(libsound_la_CPPFLAGS) $(CPPFLAGS) $(libsound_la_CFLAGS) $(CFLAGS) -c -o libsound_la-gsd-sound-manager.lo `test -f 'gsd-sound-manager.c' || echo '$(srcdir)/'`gsd-sound-manager.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +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 + +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) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -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." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ + 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-pluginDATA install-pluginLTLIBRARIES + +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: uninstall-pluginDATA uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-pluginLTLIBRARIES 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-pluginDATA \ + install-pluginLTLIBRARIES 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 \ + uninstall-pluginDATA uninstall-pluginLTLIBRARIES + + +@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/sound/gsd-sound-manager.c b/plugins/sound/gsd-sound-manager.c new file mode 100644 index 0000000..4b32130 --- /dev/null +++ b/plugins/sound/gsd-sound-manager.c @@ -0,0 +1,433 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Lennart Poettering <[email protected]> + * + * 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 <sys/types.h> +#include <sys/wait.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <signal.h> + +#include <locale.h> + +#include <glib.h> +#include <glib/gi18n.h> +#include <mateconf/mateconf-client.h> +#include <gtk/gtk.h> + +#ifdef HAVE_PULSE +#include <pulse/pulseaudio.h> +#endif + +#include "gsd-sound-manager.h" +#include "mate-settings-profile.h" + +#define GSD_SOUND_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_SOUND_MANAGER, GsdSoundManagerPrivate)) + +struct GsdSoundManagerPrivate +{ + guint mateconf_notify; + GList* monitors; + guint timeout; +}; + +#define MATECONF_SOUND_DIR "/desktop/mate/sound" + +static void gsd_sound_manager_class_init (GsdSoundManagerClass *klass); +static void gsd_sound_manager_init (GsdSoundManager *sound_manager); +static void gsd_sound_manager_finalize (GObject *object); + +G_DEFINE_TYPE (GsdSoundManager, gsd_sound_manager, G_TYPE_OBJECT) + +static gpointer manager_object = NULL; + +#ifdef HAVE_PULSE + +static void +sample_info_cb (pa_context *c, const pa_sample_info *i, int eol, void *userdata) +{ + pa_operation *o; + + if (!i) + return; + + g_debug ("Found sample %s", i->name); + + /* We only flush those samples which have an XDG sound name + * attached, because only those originate from themeing */ + if (!(pa_proplist_gets (i->proplist, PA_PROP_EVENT_ID))) + return; + + g_debug ("Dropping sample %s from cache", i->name); + + if (!(o = pa_context_remove_sample (c, i->name, NULL, NULL))) { + g_debug ("pa_context_remove_sample (): %s", pa_strerror (pa_context_errno (c))); + return; + } + + pa_operation_unref (o); + + /* We won't wait until the operation is actually executed to + * speed things up a bit.*/ +} + +static void +flush_cache (void) +{ + pa_mainloop *ml = NULL; + pa_context *c = NULL; + pa_proplist *pl = NULL; + pa_operation *o = NULL; + + g_debug ("Flushing sample cache"); + + if (!(ml = pa_mainloop_new ())) { + g_debug ("Failed to allocate pa_mainloop"); + goto fail; + } + + if (!(pl = pa_proplist_new ())) { + g_debug ("Failed to allocate pa_proplist"); + goto fail; + } + + pa_proplist_sets (pl, PA_PROP_APPLICATION_NAME, PACKAGE_NAME); + pa_proplist_sets (pl, PA_PROP_APPLICATION_VERSION, PACKAGE_VERSION); + pa_proplist_sets (pl, PA_PROP_APPLICATION_ID, "org.mate.SettingsDaemon"); + + if (!(c = pa_context_new_with_proplist (pa_mainloop_get_api (ml), PACKAGE_NAME, pl))) { + g_debug ("Failed to allocate pa_context"); + goto fail; + } + + pa_proplist_free (pl); + pl = NULL; + + if (pa_context_connect (c, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL) < 0) { + g_debug ("pa_context_connect(): %s", pa_strerror (pa_context_errno (c))); + goto fail; + } + + /* Wait until the connection is established */ + while (pa_context_get_state (c) != PA_CONTEXT_READY) { + + if (!PA_CONTEXT_IS_GOOD (pa_context_get_state (c))) { + g_debug ("Connection failed: %s", pa_strerror (pa_context_errno (c))); + goto fail; + } + + if (pa_mainloop_iterate (ml, TRUE, NULL) < 0) { + g_debug ("pa_mainloop_iterate() failed"); + goto fail; + } + } + + /* Enumerate all cached samples */ + if (!(o = pa_context_get_sample_info_list (c, sample_info_cb, NULL))) { + g_debug ("pa_context_get_sample_info_list(): %s", pa_strerror (pa_context_errno (c))); + goto fail; + } + + /* Wait until our operation is finished and there's nothing + * more queued to send to the server */ + while (pa_operation_get_state (o) == PA_OPERATION_RUNNING || pa_context_is_pending (c)) { + + if (!PA_CONTEXT_IS_GOOD (pa_context_get_state (c))) { + g_debug ("Connection failed: %s", pa_strerror (pa_context_errno (c))); + goto fail; + } + + if (pa_mainloop_iterate (ml, TRUE, NULL) < 0) { + g_debug ("pa_mainloop_iterate() failed"); + goto fail; + } + } + + g_debug ("Sample cache flushed"); + +fail: + if (o) { + pa_operation_cancel (o); + pa_operation_unref (o); + } + + if (c) { + pa_context_disconnect (c); + pa_context_unref (c); + } + + if (pl) + pa_proplist_free (pl); + + if (ml) + pa_mainloop_free (ml); +} + +static gboolean +flush_cb (GsdSoundManager *manager) +{ + flush_cache (); + manager->priv->timeout = 0; + return FALSE; +} + +static void +trigger_flush (GsdSoundManager *manager) +{ + + if (manager->priv->timeout) + g_source_remove (manager->priv->timeout); + + /* We delay the flushing a bit so that we can coalesce + * multiple changes into a single cache flush */ + manager->priv->timeout = g_timeout_add (500, (GSourceFunc) flush_cb, manager); +} + +static void +mateconf_client_notify_cb (MateConfClient *client, + guint cnxn_id, + MateConfEntry *entry, + GsdSoundManager *manager) +{ + trigger_flush (manager); +} + +static gboolean +register_config_callback (GsdSoundManager *manager, GError **error) +{ + MateConfClient *client; + gboolean succ; + + client = mateconf_client_get_default (); + + mateconf_client_add_dir (client, MATECONF_SOUND_DIR, MATECONF_CLIENT_PRELOAD_NONE, error); + succ = !error || !*error; + + if (!error) { + manager->priv->mateconf_notify = mateconf_client_notify_add (client, MATECONF_SOUND_DIR, (MateConfClientNotifyFunc) mateconf_client_notify_cb, manager, NULL, error); + succ = !error || !*error; + } + + g_object_unref (client); + + return succ; +} + +static void +file_monitor_changed_cb (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event, + GsdSoundManager *manager) +{ + g_debug ("Theme dir changed"); + trigger_flush (manager); +} + +static gboolean +register_directory_callback (GsdSoundManager *manager, + const char *path, + GError **error) +{ + GFile *f; + GFileMonitor *m; + gboolean succ = FALSE; + + g_debug ("Registering directory monitor for %s", path); + + f = g_file_new_for_path (path); + + m = g_file_monitor_directory (f, 0, NULL, error); + + if (m != NULL) { + g_signal_connect (m, "changed", G_CALLBACK (file_monitor_changed_cb), manager); + + manager->priv->monitors = g_list_prepend (manager->priv->monitors, m); + + succ = TRUE; + } + + g_object_unref (f); + + return succ; +} + +#endif + +gboolean +gsd_sound_manager_start (GsdSoundManager *manager, + GError **error) +{ + +#ifdef HAVE_PULSE + char *p, **ps, **k; + const char *env, *dd; +#endif + + g_debug ("Starting sound manager"); + mate_settings_profile_start (NULL); + +#ifdef HAVE_PULSE + + /* We listen for change of the selected theme ... */ + register_config_callback (manager, NULL); + + /* ... and we listen to changes of the theme base directories + * in $HOME ...*/ + + if ((env = g_getenv ("XDG_DATA_HOME")) && *env == '/') + p = g_build_filename (env, "sounds", NULL); + else if (((env = g_getenv ("HOME")) && *env == '/') || (env = g_get_home_dir ())) + p = g_build_filename (env, ".local", "share", "sounds", NULL); + else + p = NULL; + + if (p) { + register_directory_callback (manager, p, NULL); + g_free (p); + } + + /* ... and globally. */ + if (!(dd = g_getenv ("XDG_DATA_DIRS")) || *dd == 0) + dd = "/usr/local/share:/usr/share"; + + ps = g_strsplit (dd, ":", 0); + + for (k = ps; *k; ++k) + register_directory_callback (manager, *k, NULL); + + g_strfreev (ps); +#endif + + mate_settings_profile_end (NULL); + + return TRUE; +} + +void +gsd_sound_manager_stop (GsdSoundManager *manager) +{ + g_debug ("Stopping sound manager"); + +#ifdef HAVE_PULSE + if (manager->priv->mateconf_notify != 0) { + MateConfClient *client = mateconf_client_get_default (); + + mateconf_client_remove_dir (client, MATECONF_SOUND_DIR, NULL); + + mateconf_client_notify_remove (client, manager->priv->mateconf_notify); + manager->priv->mateconf_notify = 0; + + g_object_unref (client); + } + + if (manager->priv->timeout) { + g_source_remove (manager->priv->timeout); + manager->priv->timeout = 0; + } + + while (manager->priv->monitors) { + g_file_monitor_cancel (G_FILE_MONITOR (manager->priv->monitors->data)); + g_object_unref (manager->priv->monitors->data); + manager->priv->monitors = g_list_delete_link (manager->priv->monitors, manager->priv->monitors); + } +#endif +} + +static GObject * +gsd_sound_manager_constructor ( + GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GsdSoundManager *m; + GsdSoundManagerClass *klass; + + klass = GSD_SOUND_MANAGER_CLASS (g_type_class_peek (GSD_TYPE_SOUND_MANAGER)); + + m = GSD_SOUND_MANAGER (G_OBJECT_CLASS (gsd_sound_manager_parent_class)->constructor ( + type, + n_construct_properties, + construct_properties)); + + return G_OBJECT (m); +} + +static void +gsd_sound_manager_dispose (GObject *object) +{ + GsdSoundManager *manager; + + manager = GSD_SOUND_MANAGER (object); + + gsd_sound_manager_stop (manager); + + G_OBJECT_CLASS (gsd_sound_manager_parent_class)->dispose (object); +} + +static void +gsd_sound_manager_class_init (GsdSoundManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructor = gsd_sound_manager_constructor; + object_class->dispose = gsd_sound_manager_dispose; + object_class->finalize = gsd_sound_manager_finalize; + + g_type_class_add_private (klass, sizeof (GsdSoundManagerPrivate)); +} + +static void +gsd_sound_manager_init (GsdSoundManager *manager) +{ + manager->priv = GSD_SOUND_MANAGER_GET_PRIVATE (manager); +} + +static void +gsd_sound_manager_finalize (GObject *object) +{ + GsdSoundManager *sound_manager; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_SOUND_MANAGER (object)); + + sound_manager = GSD_SOUND_MANAGER (object); + + g_return_if_fail (sound_manager->priv); + + G_OBJECT_CLASS (gsd_sound_manager_parent_class)->finalize (object); +} + +GsdSoundManager * +gsd_sound_manager_new (void) +{ + if (manager_object) { + g_object_ref (manager_object); + } else { + manager_object = g_object_new (GSD_TYPE_SOUND_MANAGER, NULL); + g_object_add_weak_pointer (manager_object, (gpointer *) &manager_object); + } + + return GSD_SOUND_MANAGER (manager_object); +} diff --git a/plugins/sound/gsd-sound-manager.h b/plugins/sound/gsd-sound-manager.h new file mode 100644 index 0000000..e640f09 --- /dev/null +++ b/plugins/sound/gsd-sound-manager.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Lennart Poettering <[email protected]> + * + * 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_SOUND_MANAGER_H +#define __GSD_SOUND_MANAGER_H + +#include <glib.h> +#include <glib-object.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_SOUND_MANAGER (gsd_sound_manager_get_type ()) +#define GSD_SOUND_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_SOUND_MANAGER, GsdSoundManager)) +#define GSD_SOUND_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GSD_TYPE_SOUND_MANAGER, GsdSoundManagerClass)) +#define GSD_IS_SOUND_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_SOUND_MANAGER)) +#define GSD_IS_SOUND_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_SOUND_MANAGER)) +#define GSD_SOUND_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_SOUND_MANAGER, GsdSoundManagerClass)) + +typedef struct GsdSoundManagerPrivate GsdSoundManagerPrivate; + +typedef struct +{ + GObject parent; + GsdSoundManagerPrivate *priv; +} GsdSoundManager; + +typedef struct +{ + GObjectClass parent_class; +} GsdSoundManagerClass; + +GType gsd_sound_manager_get_type (void) G_GNUC_CONST; + +GsdSoundManager *gsd_sound_manager_new (void); +gboolean gsd_sound_manager_start (GsdSoundManager *manager, GError **error); +void gsd_sound_manager_stop (GsdSoundManager *manager); + +#ifdef __cplusplus +} +#endif + +#endif /* __GSD_SOUND_MANAGER_H */ diff --git a/plugins/sound/gsd-sound-plugin.c b/plugins/sound/gsd-sound-plugin.c new file mode 100644 index 0000000..88168bf --- /dev/null +++ b/plugins/sound/gsd-sound-plugin.c @@ -0,0 +1,100 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Lennart Poettering <[email protected]> + * + * 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 <glib/gi18n-lib.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" +#include "gsd-sound-plugin.h" +#include "gsd-sound-manager.h" + +struct GsdSoundPluginPrivate { + GsdSoundManager *manager; +}; + +#define GSD_SOUND_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSD_TYPE_SOUND_PLUGIN, GsdSoundPluginPrivate)) + +MATE_SETTINGS_PLUGIN_REGISTER (GsdSoundPlugin, gsd_sound_plugin) + +static void +gsd_sound_plugin_init (GsdSoundPlugin *plugin) +{ + plugin->priv = GSD_SOUND_PLUGIN_GET_PRIVATE (plugin); + + g_debug ("GsdSoundPlugin initializing"); + + plugin->priv->manager = gsd_sound_manager_new (); +} + +static void +gsd_sound_plugin_finalize (GObject *object) +{ + GsdSoundPlugin *plugin; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_SOUND_PLUGIN (object)); + + g_debug ("GsdSoundPlugin finalizing"); + + plugin = GSD_SOUND_PLUGIN (object); + + g_return_if_fail (plugin->priv != NULL); + + if (plugin->priv->manager != NULL) + g_object_unref (plugin->priv->manager); + + G_OBJECT_CLASS (gsd_sound_plugin_parent_class)->finalize (object); +} + +static void +impl_activate (MateSettingsPlugin *plugin) +{ + GError *error = NULL; + + g_debug ("Activating sound plugin"); + + if (!gsd_sound_manager_start (GSD_SOUND_PLUGIN (plugin)->priv->manager, &error)) { + g_warning ("Unable to start sound manager: %s", error->message); + g_error_free (error); + } +} + +static void +impl_deactivate (MateSettingsPlugin *plugin) +{ + g_debug ("Deactivating sound plugin"); + gsd_sound_manager_stop (GSD_SOUND_PLUGIN (plugin)->priv->manager); +} + +static void +gsd_sound_plugin_class_init (GsdSoundPluginClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MateSettingsPluginClass *plugin_class = MATE_SETTINGS_PLUGIN_CLASS (klass); + + object_class->finalize = gsd_sound_plugin_finalize; + + plugin_class->activate = impl_activate; + plugin_class->deactivate = impl_deactivate; + + g_type_class_add_private (klass, sizeof (GsdSoundPluginPrivate)); +} diff --git a/plugins/sound/gsd-sound-plugin.h b/plugins/sound/gsd-sound-plugin.h new file mode 100644 index 0000000..660e159 --- /dev/null +++ b/plugins/sound/gsd-sound-plugin.h @@ -0,0 +1,63 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2008 Lennart Poettering <[email protected]> + * + * 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_SOUND_PLUGIN_H__ +#define __GSD_SOUND_PLUGIN_H__ + +#include <glib.h> +#include <glib-object.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_SOUND_PLUGIN (gsd_sound_plugin_get_type ()) +#define GSD_SOUND_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_SOUND_PLUGIN, GsdSoundPlugin)) +#define GSD_SOUND_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GSD_TYPE_SOUND_PLUGIN, GsdSoundPluginClass)) +#define GSD_IS_SOUND_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_SOUND_PLUGIN)) +#define GSD_IS_SOUND_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_SOUND_PLUGIN)) +#define GSD_SOUND_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_SOUND_PLUGIN, GsdSoundPluginClass)) + +typedef struct GsdSoundPluginPrivate GsdSoundPluginPrivate; + +typedef struct +{ + MateSettingsPlugin parent; + GsdSoundPluginPrivate *priv; +} GsdSoundPlugin; + +typedef struct +{ + MateSettingsPluginClass parent_class; +} GsdSoundPluginClass; + +GType gsd_sound_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_SOUND_PLUGIN_H__ */ diff --git a/plugins/sound/sound.mate-settings-plugin.in b/plugins/sound/sound.mate-settings-plugin.in new file mode 100644 index 0000000..fb7e57b --- /dev/null +++ b/plugins/sound/sound.mate-settings-plugin.in @@ -0,0 +1,8 @@ +[MATE Settings Plugin] +Module=sound +IAge=0 +_Name=Sound +_Description=Sound Sample Cache plugin +Authors=Lennart Poettering +Copyright=Copyright © 2008 +Website= diff --git a/plugins/typing-break/Makefile.am b/plugins/typing-break/Makefile.am new file mode 100644 index 0000000..0648007 --- /dev/null +++ b/plugins/typing-break/Makefile.am @@ -0,0 +1,49 @@ +NULL = + +plugin_LTLIBRARIES = \ + libtyping-break.la \ + $(NULL) + +libtyping_break_la_SOURCES = \ + gsd-typing-break-plugin.h \ + gsd-typing-break-plugin.c \ + gsd-typing-break-manager.h \ + gsd-typing-break-manager.c \ + $(NULL) + +libtyping_break_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libtyping_break_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libtyping_break_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) \ + $(NULL) + +libtyping_break_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(NULL) + +plugin_in_files = \ + typing-break.mate-settings-plugin.in \ + $(NULL) + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) + +EXTRA_DIST = \ + $(plugin_in_files) \ + $(NULL) + +CLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +DISTCLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +@GSD_INTLTOOL_PLUGIN_RULE@ diff --git a/plugins/typing-break/Makefile.in b/plugins/typing-break/Makefile.in new file mode 100644 index 0000000..8fb38dc --- /dev/null +++ b/plugins/typing-break/Makefile.in @@ -0,0 +1,680 @@ +# 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/typing-break +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)$(plugindir)" +LTLIBRARIES = $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +libtyping_break_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__objects_1 = +am_libtyping_break_la_OBJECTS = \ + libtyping_break_la-gsd-typing-break-plugin.lo \ + libtyping_break_la-gsd-typing-break-manager.lo \ + $(am__objects_1) +libtyping_break_la_OBJECTS = $(am_libtyping_break_la_OBJECTS) +libtyping_break_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libtyping_break_la_CFLAGS) $(CFLAGS) \ + $(libtyping_break_la_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 = $(libtyping_break_la_SOURCES) +DIST_SOURCES = $(libtyping_break_la_SOURCES) +DATA = $(plugin_DATA) +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 = +plugin_LTLIBRARIES = \ + libtyping-break.la \ + $(NULL) + +libtyping_break_la_SOURCES = \ + gsd-typing-break-plugin.h \ + gsd-typing-break-plugin.c \ + gsd-typing-break-manager.h \ + gsd-typing-break-manager.c \ + $(NULL) + +libtyping_break_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libtyping_break_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libtyping_break_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) \ + $(NULL) + +libtyping_break_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(NULL) + +plugin_in_files = \ + typing-break.mate-settings-plugin.in \ + $(NULL) + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) +EXTRA_DIST = \ + $(plugin_in_files) \ + $(NULL) + +CLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +DISTCLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +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/typing-break/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plugins/typing-break/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 +libtyping-break.la: $(libtyping_break_la_OBJECTS) $(libtyping_break_la_DEPENDENCIES) + $(libtyping_break_la_LINK) -rpath $(plugindir) $(libtyping_break_la_OBJECTS) $(libtyping_break_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtyping_break_la-gsd-typing-break-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtyping_break_la-gsd-typing-break-plugin.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 $@ $< + +libtyping_break_la-gsd-typing-break-plugin.lo: gsd-typing-break-plugin.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtyping_break_la_CPPFLAGS) $(CPPFLAGS) $(libtyping_break_la_CFLAGS) $(CFLAGS) -MT libtyping_break_la-gsd-typing-break-plugin.lo -MD -MP -MF $(DEPDIR)/libtyping_break_la-gsd-typing-break-plugin.Tpo -c -o libtyping_break_la-gsd-typing-break-plugin.lo `test -f 'gsd-typing-break-plugin.c' || echo '$(srcdir)/'`gsd-typing-break-plugin.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtyping_break_la-gsd-typing-break-plugin.Tpo $(DEPDIR)/libtyping_break_la-gsd-typing-break-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-typing-break-plugin.c' object='libtyping_break_la-gsd-typing-break-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) $(libtyping_break_la_CPPFLAGS) $(CPPFLAGS) $(libtyping_break_la_CFLAGS) $(CFLAGS) -c -o libtyping_break_la-gsd-typing-break-plugin.lo `test -f 'gsd-typing-break-plugin.c' || echo '$(srcdir)/'`gsd-typing-break-plugin.c + +libtyping_break_la-gsd-typing-break-manager.lo: gsd-typing-break-manager.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libtyping_break_la_CPPFLAGS) $(CPPFLAGS) $(libtyping_break_la_CFLAGS) $(CFLAGS) -MT libtyping_break_la-gsd-typing-break-manager.lo -MD -MP -MF $(DEPDIR)/libtyping_break_la-gsd-typing-break-manager.Tpo -c -o libtyping_break_la-gsd-typing-break-manager.lo `test -f 'gsd-typing-break-manager.c' || echo '$(srcdir)/'`gsd-typing-break-manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libtyping_break_la-gsd-typing-break-manager.Tpo $(DEPDIR)/libtyping_break_la-gsd-typing-break-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-typing-break-manager.c' object='libtyping_break_la-gsd-typing-break-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) $(libtyping_break_la_CPPFLAGS) $(CPPFLAGS) $(libtyping_break_la_CFLAGS) $(CFLAGS) -c -o libtyping_break_la-gsd-typing-break-manager.lo `test -f 'gsd-typing-break-manager.c' || echo '$(srcdir)/'`gsd-typing-break-manager.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +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 + +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) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -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." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ + 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-pluginDATA install-pluginLTLIBRARIES + +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: uninstall-pluginDATA uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-pluginLTLIBRARIES 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-pluginDATA \ + install-pluginLTLIBRARIES 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 \ + uninstall-pluginDATA uninstall-pluginLTLIBRARIES + + +@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/typing-break/gsd-typing-break-manager.c b/plugins/typing-break/gsd-typing-break-manager.c new file mode 100644 index 0000000..d157964 --- /dev/null +++ b/plugins/typing-break/gsd-typing-break-manager.c @@ -0,0 +1,339 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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 <sys/types.h> +#include <sys/wait.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <signal.h> + +#include <locale.h> + +#include <glib.h> +#include <glib/gi18n.h> +#include <gdk/gdk.h> +#include <gdk/gdkx.h> +#include <gtk/gtk.h> +#include <mateconf/mateconf-client.h> + +#include "mate-settings-profile.h" +#include "gsd-typing-break-manager.h" + +#define GSD_TYPING_BREAK_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_TYPING_BREAK_MANAGER, GsdTypingBreakManagerPrivate)) + +#define MATECONF_BREAK_DIR "/desktop/mate/typing_break" + +struct GsdTypingBreakManagerPrivate +{ + GPid typing_monitor_pid; + guint typing_monitor_idle_id; + guint child_watch_id; + guint setup_id; + guint notify; +}; + +static void gsd_typing_break_manager_class_init (GsdTypingBreakManagerClass *klass); +static void gsd_typing_break_manager_init (GsdTypingBreakManager *typing_break_manager); +static void gsd_typing_break_manager_finalize (GObject *object); + +G_DEFINE_TYPE (GsdTypingBreakManager, gsd_typing_break_manager, G_TYPE_OBJECT) + +static gpointer manager_object = NULL; + +static gboolean +typing_break_timeout (GsdTypingBreakManager *manager) +{ + if (manager->priv->typing_monitor_pid > 0) { + kill (manager->priv->typing_monitor_pid, SIGKILL); + } + + manager->priv->typing_monitor_idle_id = 0; + + return FALSE; +} + +static void +child_watch (GPid pid, + int status, + GsdTypingBreakManager *manager) +{ + if (pid == manager->priv->typing_monitor_pid) { + manager->priv->typing_monitor_pid = 0; + g_spawn_close_pid (pid); + } +} + +static void +setup_typing_break (GsdTypingBreakManager *manager, + gboolean enabled) +{ + mate_settings_profile_start (NULL); + + if (! enabled) { + if (manager->priv->typing_monitor_pid != 0) { + manager->priv->typing_monitor_idle_id = g_timeout_add_seconds (3, (GSourceFunc) typing_break_timeout, manager); + } + return; + } + + if (manager->priv->typing_monitor_idle_id != 0) { + g_source_remove (manager->priv->typing_monitor_idle_id); + manager->priv->typing_monitor_idle_id = 0; + } + + if (manager->priv->typing_monitor_pid == 0) { + GError *error; + char *argv[] = { "mate-typing-monitor", "-n", NULL }; + gboolean res; + + error = NULL; + res = g_spawn_async ("/", + argv, + NULL, + G_SPAWN_STDOUT_TO_DEV_NULL + | G_SPAWN_STDERR_TO_DEV_NULL + | G_SPAWN_SEARCH_PATH + | G_SPAWN_DO_NOT_REAP_CHILD, + NULL, + NULL, + &manager->priv->typing_monitor_pid, + &error); + if (! res) { + /* FIXME: put up a warning */ + g_warning ("failed: %s\n", error->message); + g_error_free (error); + manager->priv->typing_monitor_pid = 0; + return; + } + + manager->priv->child_watch_id = g_child_watch_add (manager->priv->typing_monitor_pid, + (GChildWatchFunc)child_watch, + manager); + } + + mate_settings_profile_end (NULL); +} + +static void +typing_break_callback (MateConfClient *client, + guint cnxn_id, + MateConfEntry *entry, + GsdTypingBreakManager *manager) +{ + if (! strcmp (entry->key, "/desktop/mate/typing_break/enabled")) { + if (entry->value->type == MATECONF_VALUE_BOOL) { + setup_typing_break (manager, mateconf_value_get_bool (entry->value)); + } + } +} + +static gboolean +really_setup_typing_break (GsdTypingBreakManager *manager) +{ + setup_typing_break (manager, TRUE); + manager->priv->setup_id = 0; + return FALSE; +} + +gboolean +gsd_typing_break_manager_start (GsdTypingBreakManager *manager, + GError **error) +{ + MateConfClient *client; + gboolean enabled; + + g_debug ("Starting typing_break manager"); + mate_settings_profile_start (NULL); + + client = mateconf_client_get_default (); + + mateconf_client_add_dir (client, MATECONF_BREAK_DIR, MATECONF_CLIENT_PRELOAD_ONELEVEL, NULL); + manager->priv->notify = + mateconf_client_notify_add (client, + MATECONF_BREAK_DIR, + (MateConfClientNotifyFunc) typing_break_callback, manager, + NULL, NULL); + + enabled = mateconf_client_get_bool (client, MATECONF_BREAK_DIR "/enabled", NULL); + g_object_unref (client); + if (enabled) { + manager->priv->setup_id = + g_timeout_add_seconds (3, + (GSourceFunc) really_setup_typing_break, + manager); + } + + mate_settings_profile_end (NULL); + + return TRUE; +} + +void +gsd_typing_break_manager_stop (GsdTypingBreakManager *manager) +{ + GsdTypingBreakManagerPrivate *p = manager->priv; + + g_debug ("Stopping typing_break manager"); + + if (p->setup_id != 0) { + g_source_remove (p->setup_id); + p->setup_id = 0; + } + + if (p->child_watch_id != 0) { + g_source_remove (p->child_watch_id); + p->child_watch_id = 0; + } + + if (p->typing_monitor_idle_id != 0) { + g_source_remove (p->typing_monitor_idle_id); + p->typing_monitor_idle_id = 0; + } + + if (p->typing_monitor_pid > 0) { + kill (p->typing_monitor_pid, SIGKILL); + g_spawn_close_pid (p->typing_monitor_pid); + p->typing_monitor_pid = 0; + } + + if (p->notify != 0) { + MateConfClient *client = mateconf_client_get_default (); + mateconf_client_remove_dir (client, MATECONF_BREAK_DIR, NULL); + mateconf_client_notify_remove (client, p->notify); + g_object_unref (client); + p->notify = 0; + } +} + +static void +gsd_typing_break_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GsdTypingBreakManager *self; + + self = GSD_TYPING_BREAK_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gsd_typing_break_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GsdTypingBreakManager *self; + + self = GSD_TYPING_BREAK_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +gsd_typing_break_manager_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GsdTypingBreakManager *typing_break_manager; + GsdTypingBreakManagerClass *klass; + + klass = GSD_TYPING_BREAK_MANAGER_CLASS (g_type_class_peek (GSD_TYPE_TYPING_BREAK_MANAGER)); + + typing_break_manager = GSD_TYPING_BREAK_MANAGER (G_OBJECT_CLASS (gsd_typing_break_manager_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + + return G_OBJECT (typing_break_manager); +} + +static void +gsd_typing_break_manager_dispose (GObject *object) +{ + GsdTypingBreakManager *typing_break_manager; + + typing_break_manager = GSD_TYPING_BREAK_MANAGER (object); + + G_OBJECT_CLASS (gsd_typing_break_manager_parent_class)->dispose (object); +} + +static void +gsd_typing_break_manager_class_init (GsdTypingBreakManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gsd_typing_break_manager_get_property; + object_class->set_property = gsd_typing_break_manager_set_property; + object_class->constructor = gsd_typing_break_manager_constructor; + object_class->dispose = gsd_typing_break_manager_dispose; + object_class->finalize = gsd_typing_break_manager_finalize; + + g_type_class_add_private (klass, sizeof (GsdTypingBreakManagerPrivate)); +} + +static void +gsd_typing_break_manager_init (GsdTypingBreakManager *manager) +{ + manager->priv = GSD_TYPING_BREAK_MANAGER_GET_PRIVATE (manager); + +} + +static void +gsd_typing_break_manager_finalize (GObject *object) +{ + GsdTypingBreakManager *typing_break_manager; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_TYPING_BREAK_MANAGER (object)); + + typing_break_manager = GSD_TYPING_BREAK_MANAGER (object); + + g_return_if_fail (typing_break_manager->priv != NULL); + + G_OBJECT_CLASS (gsd_typing_break_manager_parent_class)->finalize (object); +} + +GsdTypingBreakManager * +gsd_typing_break_manager_new (void) +{ + if (manager_object != NULL) { + g_object_ref (manager_object); + } else { + manager_object = g_object_new (GSD_TYPE_TYPING_BREAK_MANAGER, NULL); + g_object_add_weak_pointer (manager_object, + (gpointer *) &manager_object); + } + + return GSD_TYPING_BREAK_MANAGER (manager_object); +} diff --git a/plugins/typing-break/gsd-typing-break-manager.h b/plugins/typing-break/gsd-typing-break-manager.h new file mode 100644 index 0000000..e4ac24d --- /dev/null +++ b/plugins/typing-break/gsd-typing-break-manager.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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_TYPING_BREAK_MANAGER_H +#define __GSD_TYPING_BREAK_MANAGER_H + +#include <glib-object.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_TYPING_BREAK_MANAGER (gsd_typing_break_manager_get_type ()) +#define GSD_TYPING_BREAK_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_TYPING_BREAK_MANAGER, GsdTypingBreakManager)) +#define GSD_TYPING_BREAK_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_TYPING_BREAK_MANAGER, GsdTypingBreakManagerClass)) +#define GSD_IS_TYPING_BREAK_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_TYPING_BREAK_MANAGER)) +#define GSD_IS_TYPING_BREAK_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_TYPING_BREAK_MANAGER)) +#define GSD_TYPING_BREAK_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_TYPING_BREAK_MANAGER, GsdTypingBreakManagerClass)) + +typedef struct GsdTypingBreakManagerPrivate GsdTypingBreakManagerPrivate; + +typedef struct +{ + GObject parent; + GsdTypingBreakManagerPrivate *priv; +} GsdTypingBreakManager; + +typedef struct +{ + GObjectClass parent_class; +} GsdTypingBreakManagerClass; + +GType gsd_typing_break_manager_get_type (void); + +GsdTypingBreakManager * gsd_typing_break_manager_new (void); +gboolean gsd_typing_break_manager_start (GsdTypingBreakManager *manager, + GError **error); +void gsd_typing_break_manager_stop (GsdTypingBreakManager *manager); + +#ifdef __cplusplus +} +#endif + +#endif /* __GSD_TYPING_BREAK_MANAGER_H */ diff --git a/plugins/typing-break/gsd-typing-break-plugin.c b/plugins/typing-break/gsd-typing-break-plugin.c new file mode 100644 index 0000000..0f0535d --- /dev/null +++ b/plugins/typing-break/gsd-typing-break-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 <[email protected]> + * + * 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 <glib/gi18n-lib.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" +#include "gsd-typing-break-plugin.h" +#include "gsd-typing-break-manager.h" + +struct GsdTypingBreakPluginPrivate { + GsdTypingBreakManager *manager; +}; + +#define GSD_TYPING_BREAK_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSD_TYPE_TYPING_BREAK_PLUGIN, GsdTypingBreakPluginPrivate)) + +MATE_SETTINGS_PLUGIN_REGISTER (GsdTypingBreakPlugin, gsd_typing_break_plugin) + +static void +gsd_typing_break_plugin_init (GsdTypingBreakPlugin *plugin) +{ + plugin->priv = GSD_TYPING_BREAK_PLUGIN_GET_PRIVATE (plugin); + + g_debug ("GsdTypingBreakPlugin initializing"); + + plugin->priv->manager = gsd_typing_break_manager_new (); +} + +static void +gsd_typing_break_plugin_finalize (GObject *object) +{ + GsdTypingBreakPlugin *plugin; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_TYPING_BREAK_PLUGIN (object)); + + g_debug ("GsdTypingBreakPlugin finalizing"); + + plugin = GSD_TYPING_BREAK_PLUGIN (object); + + g_return_if_fail (plugin->priv != NULL); + + if (plugin->priv->manager != NULL) { + g_object_unref (plugin->priv->manager); + } + + G_OBJECT_CLASS (gsd_typing_break_plugin_parent_class)->finalize (object); +} + +static void +impl_activate (MateSettingsPlugin *plugin) +{ + gboolean res; + GError *error; + + g_debug ("Activating typing_break plugin"); + + error = NULL; + res = gsd_typing_break_manager_start (GSD_TYPING_BREAK_PLUGIN (plugin)->priv->manager, &error); + if (! res) { + g_warning ("Unable to start typing_break manager: %s", error->message); + g_error_free (error); + } +} + +static void +impl_deactivate (MateSettingsPlugin *plugin) +{ + g_debug ("Deactivating typing_break plugin"); + gsd_typing_break_manager_stop (GSD_TYPING_BREAK_PLUGIN (plugin)->priv->manager); +} + +static void +gsd_typing_break_plugin_class_init (GsdTypingBreakPluginClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MateSettingsPluginClass *plugin_class = MATE_SETTINGS_PLUGIN_CLASS (klass); + + object_class->finalize = gsd_typing_break_plugin_finalize; + + plugin_class->activate = impl_activate; + plugin_class->deactivate = impl_deactivate; + + g_type_class_add_private (klass, sizeof (GsdTypingBreakPluginPrivate)); +} diff --git a/plugins/typing-break/gsd-typing-break-plugin.h b/plugins/typing-break/gsd-typing-break-plugin.h new file mode 100644 index 0000000..b7bbf16 --- /dev/null +++ b/plugins/typing-break/gsd-typing-break-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 <[email protected]> + * + * 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_TYPING_BREAK_PLUGIN_H__ +#define __GSD_TYPING_BREAK_PLUGIN_H__ + +#include <glib.h> +#include <glib-object.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_TYPING_BREAK_PLUGIN (gsd_typing_break_plugin_get_type ()) +#define GSD_TYPING_BREAK_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_TYPING_BREAK_PLUGIN, GsdTypingBreakPlugin)) +#define GSD_TYPING_BREAK_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_TYPING_BREAK_PLUGIN, GsdTypingBreakPluginClass)) +#define GSD_IS_TYPING_BREAK_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_TYPING_BREAK_PLUGIN)) +#define GSD_IS_TYPING_BREAK_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_TYPING_BREAK_PLUGIN)) +#define GSD_TYPING_BREAK_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_TYPING_BREAK_PLUGIN, GsdTypingBreakPluginClass)) + +typedef struct GsdTypingBreakPluginPrivate GsdTypingBreakPluginPrivate; + +typedef struct +{ + MateSettingsPlugin parent; + GsdTypingBreakPluginPrivate *priv; +} GsdTypingBreakPlugin; + +typedef struct +{ + MateSettingsPluginClass parent_class; +} GsdTypingBreakPluginClass; + +GType gsd_typing_break_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_TYPING_BREAK_PLUGIN_H__ */ diff --git a/plugins/typing-break/typing-break.mate-settings-plugin.in b/plugins/typing-break/typing-break.mate-settings-plugin.in new file mode 100644 index 0000000..22b722f --- /dev/null +++ b/plugins/typing-break/typing-break.mate-settings-plugin.in @@ -0,0 +1,8 @@ +[MATE Settings Plugin] +Module=typing-break +IAge=0 +_Name=Typing Break +_Description=Typing break plugin +Authors= +Copyright=Copyright © 2007 +Website= diff --git a/plugins/xrandr/Makefile.am b/plugins/xrandr/Makefile.am new file mode 100644 index 0000000..b7d8684 --- /dev/null +++ b/plugins/xrandr/Makefile.am @@ -0,0 +1,76 @@ +icondir = $(datadir)/icons/mate +context = apps + +BUILT_SOURCES = \ + gsd-xrandr-manager-glue.h + +ICON_FILES = \ + gsd-xrandr-16.png \ + gsd-xrandr-22.png \ + gsd-xrandr-24.png \ + gsd-xrandr-32.png \ + gsd-xrandr.svg + +install-data-local: + $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/mate-settings-daemon/xrandr + $(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)/gsd-xrandr-16.png $(DESTDIR)$(icondir)/16x16/$(context)/gsd-xrandr.png + $(INSTALL_DATA) $(srcdir)/gsd-xrandr-22.png $(DESTDIR)$(icondir)/22x22/$(context)/gsd-xrandr.png + $(INSTALL_DATA) $(srcdir)/gsd-xrandr-24.png $(DESTDIR)$(icondir)/24x24/$(context)/gsd-xrandr.png + $(INSTALL_DATA) $(srcdir)/gsd-xrandr-32.png $(DESTDIR)$(icondir)/32x32/$(context)/gsd-xrandr.png + $(INSTALL_DATA) $(srcdir)/gsd-xrandr.svg $(DESTDIR)$(icondir)/scalable/$(context)/gsd-xrandr.svg + +uninstall-local: + rm -f $(DESTDIR)$(icondir)/16x16/$(context)/gsd-xrandr.png + rm -f $(DESTDIR)$(icondir)/22x22/$(context)/gsd-xrandr.png + rm -f $(DESTDIR)$(icondir)/24x24/$(context)/gsd-xrandr.png + rm -f $(DESTDIR)$(icondir)/32x32/$(context)/gsd-xrandr.png + rm -f $(DESTDIR)$(icondir)/scalable/$(context)/gsd-xrandr.svg + +plugin_LTLIBRARIES = \ + libxrandr.la + +gsd-xrandr-manager-glue.h: gsd-xrandr-manager.xml Makefile + dbus-binding-tool --prefix=gsd_xrandr_manager --mode=glib-server $< > xgen-$(@F) \ + && ( cmp -s xgen-$(@F) $@ || cp xgen-$(@F) $@ ) \ + && rm -f xgen-$(@F) + +libxrandr_la_SOURCES = \ + $(BUILT_SOURCES) \ + gsd-xrandr-plugin.h \ + gsd-xrandr-plugin.c \ + gsd-xrandr-manager.h \ + gsd-xrandr-manager.c + +libxrandr_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DBINDIR=\"$(bindir)\" \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libxrandr_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(LIBMATENOTIFY_CFLAGS) \ + $(AM_CFLAGS) + +libxrandr_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) + +libxrandr_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(LIBMATENOTIFY_LIBS) + +plugin_in_files = \ + xrandr.mate-settings-plugin.in + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) + +EXTRA_DIST = $(plugin_in_files) $(ICON_FILES) gsd-xrandr-manager.xml +CLEANFILES = $(plugin_DATA) $(BUILT_SOURCES) +DISTCLEANFILES = $(plugin_DATA) + +@GSD_INTLTOOL_PLUGIN_RULE@ diff --git a/plugins/xrandr/Makefile.in b/plugins/xrandr/Makefile.in new file mode 100644 index 0000000..ba8edc4 --- /dev/null +++ b/plugins/xrandr/Makefile.in @@ -0,0 +1,711 @@ +# 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/xrandr +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)$(plugindir)" +LTLIBRARIES = $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +libxrandr_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__objects_1 = +am_libxrandr_la_OBJECTS = $(am__objects_1) \ + libxrandr_la-gsd-xrandr-plugin.lo \ + libxrandr_la-gsd-xrandr-manager.lo +libxrandr_la_OBJECTS = $(am_libxrandr_la_OBJECTS) +libxrandr_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libxrandr_la_CFLAGS) \ + $(CFLAGS) $(libxrandr_la_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 = $(libxrandr_la_SOURCES) +DIST_SOURCES = $(libxrandr_la_SOURCES) +DATA = $(plugin_DATA) +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@ +icondir = $(datadir)/icons/mate +context = apps +BUILT_SOURCES = \ + gsd-xrandr-manager-glue.h + +ICON_FILES = \ + gsd-xrandr-16.png \ + gsd-xrandr-22.png \ + gsd-xrandr-24.png \ + gsd-xrandr-32.png \ + gsd-xrandr.svg + +plugin_LTLIBRARIES = \ + libxrandr.la + +libxrandr_la_SOURCES = \ + $(BUILT_SOURCES) \ + gsd-xrandr-plugin.h \ + gsd-xrandr-plugin.c \ + gsd-xrandr-manager.h \ + gsd-xrandr-manager.c + +libxrandr_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DBINDIR=\"$(bindir)\" \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libxrandr_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(LIBMATENOTIFY_CFLAGS) \ + $(AM_CFLAGS) + +libxrandr_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) + +libxrandr_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(LIBMATENOTIFY_LIBS) + +plugin_in_files = \ + xrandr.mate-settings-plugin.in + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) +EXTRA_DIST = $(plugin_in_files) $(ICON_FILES) gsd-xrandr-manager.xml +CLEANFILES = $(plugin_DATA) $(BUILT_SOURCES) +DISTCLEANFILES = $(plugin_DATA) +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) 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/xrandr/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plugins/xrandr/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 +libxrandr.la: $(libxrandr_la_OBJECTS) $(libxrandr_la_DEPENDENCIES) + $(libxrandr_la_LINK) -rpath $(plugindir) $(libxrandr_la_OBJECTS) $(libxrandr_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxrandr_la-gsd-xrandr-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxrandr_la-gsd-xrandr-plugin.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 $@ $< + +libxrandr_la-gsd-xrandr-plugin.lo: gsd-xrandr-plugin.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxrandr_la_CPPFLAGS) $(CPPFLAGS) $(libxrandr_la_CFLAGS) $(CFLAGS) -MT libxrandr_la-gsd-xrandr-plugin.lo -MD -MP -MF $(DEPDIR)/libxrandr_la-gsd-xrandr-plugin.Tpo -c -o libxrandr_la-gsd-xrandr-plugin.lo `test -f 'gsd-xrandr-plugin.c' || echo '$(srcdir)/'`gsd-xrandr-plugin.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxrandr_la-gsd-xrandr-plugin.Tpo $(DEPDIR)/libxrandr_la-gsd-xrandr-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-xrandr-plugin.c' object='libxrandr_la-gsd-xrandr-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) $(libxrandr_la_CPPFLAGS) $(CPPFLAGS) $(libxrandr_la_CFLAGS) $(CFLAGS) -c -o libxrandr_la-gsd-xrandr-plugin.lo `test -f 'gsd-xrandr-plugin.c' || echo '$(srcdir)/'`gsd-xrandr-plugin.c + +libxrandr_la-gsd-xrandr-manager.lo: gsd-xrandr-manager.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxrandr_la_CPPFLAGS) $(CPPFLAGS) $(libxrandr_la_CFLAGS) $(CFLAGS) -MT libxrandr_la-gsd-xrandr-manager.lo -MD -MP -MF $(DEPDIR)/libxrandr_la-gsd-xrandr-manager.Tpo -c -o libxrandr_la-gsd-xrandr-manager.lo `test -f 'gsd-xrandr-manager.c' || echo '$(srcdir)/'`gsd-xrandr-manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxrandr_la-gsd-xrandr-manager.Tpo $(DEPDIR)/libxrandr_la-gsd-xrandr-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-xrandr-manager.c' object='libxrandr_la-gsd-xrandr-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) $(libxrandr_la_CPPFLAGS) $(CPPFLAGS) $(libxrandr_la_CFLAGS) $(CFLAGS) -c -o libxrandr_la-gsd-xrandr-manager.lo `test -f 'gsd-xrandr-manager.c' || echo '$(srcdir)/'`gsd-xrandr-manager.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +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 + +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: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LTLIBRARIES) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) 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: + -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-am + +clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ + 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-data-local install-pluginDATA \ + install-pluginLTLIBRARIES + +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: uninstall-local uninstall-pluginDATA \ + uninstall-pluginLTLIBRARIES + +.MAKE: all check install install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-pluginLTLIBRARIES 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-data-local 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-pluginDATA install-pluginLTLIBRARIES 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 uninstall-local uninstall-pluginDATA \ + uninstall-pluginLTLIBRARIES + + +install-data-local: + $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/mate-settings-daemon/xrandr + $(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)/gsd-xrandr-16.png $(DESTDIR)$(icondir)/16x16/$(context)/gsd-xrandr.png + $(INSTALL_DATA) $(srcdir)/gsd-xrandr-22.png $(DESTDIR)$(icondir)/22x22/$(context)/gsd-xrandr.png + $(INSTALL_DATA) $(srcdir)/gsd-xrandr-24.png $(DESTDIR)$(icondir)/24x24/$(context)/gsd-xrandr.png + $(INSTALL_DATA) $(srcdir)/gsd-xrandr-32.png $(DESTDIR)$(icondir)/32x32/$(context)/gsd-xrandr.png + $(INSTALL_DATA) $(srcdir)/gsd-xrandr.svg $(DESTDIR)$(icondir)/scalable/$(context)/gsd-xrandr.svg + +uninstall-local: + rm -f $(DESTDIR)$(icondir)/16x16/$(context)/gsd-xrandr.png + rm -f $(DESTDIR)$(icondir)/22x22/$(context)/gsd-xrandr.png + rm -f $(DESTDIR)$(icondir)/24x24/$(context)/gsd-xrandr.png + rm -f $(DESTDIR)$(icondir)/32x32/$(context)/gsd-xrandr.png + rm -f $(DESTDIR)$(icondir)/scalable/$(context)/gsd-xrandr.svg + +gsd-xrandr-manager-glue.h: gsd-xrandr-manager.xml Makefile + dbus-binding-tool --prefix=gsd_xrandr_manager --mode=glib-server $< > xgen-$(@F) \ + && ( cmp -s xgen-$(@F) $@ || cp xgen-$(@F) $@ ) \ + && rm -f xgen-$(@F) + +@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/xrandr/gsd-xrandr-16.png b/plugins/xrandr/gsd-xrandr-16.png Binary files differnew file mode 100644 index 0000000..f996ddf --- /dev/null +++ b/plugins/xrandr/gsd-xrandr-16.png diff --git a/plugins/xrandr/gsd-xrandr-22.png b/plugins/xrandr/gsd-xrandr-22.png Binary files differnew file mode 100644 index 0000000..cc47eec --- /dev/null +++ b/plugins/xrandr/gsd-xrandr-22.png diff --git a/plugins/xrandr/gsd-xrandr-24.png b/plugins/xrandr/gsd-xrandr-24.png Binary files differnew file mode 100644 index 0000000..49b4e12 --- /dev/null +++ b/plugins/xrandr/gsd-xrandr-24.png diff --git a/plugins/xrandr/gsd-xrandr-32.png b/plugins/xrandr/gsd-xrandr-32.png Binary files differnew file mode 100644 index 0000000..95de3ea --- /dev/null +++ b/plugins/xrandr/gsd-xrandr-32.png diff --git a/plugins/xrandr/gsd-xrandr-manager.c b/plugins/xrandr/gsd-xrandr-manager.c new file mode 100644 index 0000000..b8d9c66 --- /dev/null +++ b/plugins/xrandr/gsd-xrandr-manager.c @@ -0,0 +1,2584 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann <[email protected]> + * Copyright (C) 2007, 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. + * + */ + +#include "config.h" + +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> + +#include <locale.h> + +#include <glib.h> +#include <glib/gi18n.h> +#include <gdk/gdk.h> +#include <gdk/gdkx.h> +#include <gtk/gtk.h> +#include <mateconf/mateconf-client.h> +#include <dbus/dbus-glib.h> + +#define MATE_DESKTOP_USE_UNSTABLE_API + +#include <libmateui/mate-rr-config.h> +#include <libmateui/mate-rr.h> +#include <libmateui/mate-rr-labeler.h> + +#ifdef HAVE_LIBMATENOTIFY +#include <libmatenotify/notify.h> +#endif + +#include "mate-settings-profile.h" +#include "gsd-xrandr-manager.h" + +#ifndef HOST_NAME_MAX +#define HOST_NAME_MAX 255 +#endif + +#define GSD_XRANDR_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_XRANDR_MANAGER, GsdXrandrManagerPrivate)) + +#define CONF_DIR "/apps/mate_settings_daemon/xrandr" +#define CONF_KEY_SHOW_NOTIFICATION_ICON (CONF_DIR "/show_notification_icon") +#define CONF_KEY_TURN_ON_EXTERNAL_MONITORS_AT_STARTUP (CONF_DIR "/turn_on_external_monitors_at_startup") +#define CONF_KEY_TURN_ON_LAPTOP_MONITOR_AT_STARTUP (CONF_DIR "/turn_on_laptop_monitor_at_startup") +#define CONF_KEY_DEFAULT_CONFIGURATION_FILE (CONF_DIR "/default_configuration_file") + +#define VIDEO_KEYSYM "XF86Display" +#define ROTATE_KEYSYM "XF86RotateWindows" + +/* Number of seconds that the confirmation dialog will last before it resets the + * RANDR configuration to its old state. + */ +#define CONFIRMATION_DIALOG_SECONDS 30 + +/* name of the icon files (gsd-xrandr.svg, etc.) */ +#define GSD_XRANDR_ICON_NAME "gsd-xrandr" + +/* executable of the control center's display configuration capplet */ +#define GSD_XRANDR_DISPLAY_CAPPLET "mate-control-center display" + +#define GSD_DBUS_PATH "/org/mate/SettingsDaemon" +#define GSD_DBUS_NAME "org.mate.SettingsDaemon" +#define GSD_XRANDR_DBUS_PATH GSD_DBUS_PATH "/XRANDR" +#define GSD_XRANDR_DBUS_NAME GSD_DBUS_NAME ".XRANDR" + +struct GsdXrandrManagerPrivate +{ + DBusGConnection *dbus_connection; + + /* Key code of the XF86Display key (Fn-F7 on Thinkpads, Fn-F4 on HP machines, etc.) */ + guint switch_video_mode_keycode; + + /* Key code of the XF86RotateWindows key (present on some tablets) */ + guint rotate_windows_keycode; + + MateRRScreen *rw_screen; + gboolean running; + + GtkStatusIcon *status_icon; + GtkWidget *popup_menu; + MateRRConfig *configuration; + MateRRLabeler *labeler; + MateConfClient *client; + int notify_id; + + /* fn-F7 status */ + int current_fn_f7_config; /* -1 if no configs */ + MateRRConfig **fn_f7_configs; /* NULL terminated, NULL if there are no configs */ + + /* Last time at which we got a "screen got reconfigured" event; see on_randr_event() */ + guint32 last_config_timestamp; +}; + +static const MateRRRotation possible_rotations[] = { + MATE_RR_ROTATION_0, + MATE_RR_ROTATION_90, + MATE_RR_ROTATION_180, + MATE_RR_ROTATION_270 + /* We don't allow REFLECT_X or REFLECT_Y for now, as mate-display-properties doesn't allow them, either */ +}; + +static void gsd_xrandr_manager_class_init (GsdXrandrManagerClass *klass); +static void gsd_xrandr_manager_init (GsdXrandrManager *xrandr_manager); +static void gsd_xrandr_manager_finalize (GObject *object); + +static void error_message (GsdXrandrManager *mgr, const char *primary_text, GError *error_to_display, const char *secondary_text); + +static void status_icon_popup_menu (GsdXrandrManager *manager, guint button, guint32 timestamp); +static void run_display_capplet (GtkWidget *widget); +static void get_allowed_rotations_for_output (MateRRConfig *config, + MateRRScreen *rr_screen, + MateOutputInfo *output, + int *out_num_rotations, + MateRRRotation *out_rotations); + +G_DEFINE_TYPE (GsdXrandrManager, gsd_xrandr_manager, G_TYPE_OBJECT) + +static gpointer manager_object = NULL; + +static FILE *log_file; + +static void +log_open (void) +{ + char *toggle_filename; + char *log_filename; + struct stat st; + + if (log_file) + return; + + toggle_filename = g_build_filename (g_get_home_dir (), "gsd-debug-randr", NULL); + log_filename = g_build_filename (g_get_home_dir (), "gsd-debug-randr.log", NULL); + + if (stat (toggle_filename, &st) != 0) + goto out; + + log_file = fopen (log_filename, "a"); + + if (log_file && ftell (log_file) == 0) + fprintf (log_file, "To keep this log from being created, please rm ~/gsd-debug-randr\n"); + +out: + g_free (toggle_filename); + g_free (log_filename); +} + +static void +log_close (void) +{ + if (log_file) { + fclose (log_file); + log_file = NULL; + } +} + +static void +log_msg (const char *format, ...) +{ + if (log_file) { + va_list args; + + va_start (args, format); + vfprintf (log_file, format, args); + va_end (args); + } +} + +static void +log_output (MateOutputInfo *output) +{ + log_msg (" %s: ", output->name ? output->name : "unknown"); + + if (output->connected) { + if (output->on) { + log_msg ("%dx%d@%d +%d+%d", + output->width, + output->height, + output->rate, + output->x, + output->y); + } else + log_msg ("off"); + } else + log_msg ("disconnected"); + + if (output->display_name) + log_msg (" (%s)", output->display_name); + + if (output->primary) + log_msg (" (primary output)"); + + log_msg ("\n"); +} + +static void +log_configuration (MateRRConfig *config) +{ + int i; + + log_msg (" cloned: %s\n", config->clone ? "yes" : "no"); + + for (i = 0; config->outputs[i] != NULL; i++) + log_output (config->outputs[i]); + + if (i == 0) + log_msg (" no outputs!\n"); +} + +static char +timestamp_relationship (guint32 a, guint32 b) +{ + if (a < b) + return '<'; + else if (a > b) + return '>'; + else + return '='; +} + +static void +log_screen (MateRRScreen *screen) +{ + MateRRConfig *config; + int min_w, min_h, max_w, max_h; + guint32 change_timestamp, config_timestamp; + + if (!log_file) + return; + + config = mate_rr_config_new_current (screen); + + mate_rr_screen_get_ranges (screen, &min_w, &max_w, &min_h, &max_h); + mate_rr_screen_get_timestamps (screen, &change_timestamp, &config_timestamp); + + log_msg (" Screen min(%d, %d), max(%d, %d), change=%u %c config=%u\n", + min_w, min_h, + max_w, max_h, + change_timestamp, + timestamp_relationship (change_timestamp, config_timestamp), + config_timestamp); + + log_configuration (config); + mate_rr_config_free (config); +} + +static void +log_configurations (MateRRConfig **configs) +{ + int i; + + if (!configs) { + log_msg (" No configurations\n"); + return; + } + + for (i = 0; configs[i]; i++) { + log_msg (" Configuration %d\n", i); + log_configuration (configs[i]); + } +} + +static void +show_timestamps_dialog (GsdXrandrManager *manager, const char *msg) +{ +#if 1 + return; +#else + struct GsdXrandrManagerPrivate *priv = manager->priv; + GtkWidget *dialog; + guint32 change_timestamp, config_timestamp; + static int serial; + + mate_rr_screen_get_timestamps (priv->rw_screen, &change_timestamp, &config_timestamp); + + dialog = gtk_message_dialog_new (NULL, + 0, + GTK_MESSAGE_INFO, + GTK_BUTTONS_CLOSE, + "RANDR timestamps (%d):\n%s\nchange: %u\nconfig: %u", + serial++, + msg, + change_timestamp, + config_timestamp); + g_signal_connect (dialog, "response", + G_CALLBACK (gtk_widget_destroy), NULL); + gtk_widget_show (dialog); +#endif +} + +/* This function centralizes the use of mate_rr_config_apply_from_filename_with_time(). + * + * Optionally filters out MATE_RR_ERROR_NO_MATCHING_CONFIG from + * mate_rr_config_apply_from_filename_with_time(), since that is not usually an error. + */ +static gboolean +apply_configuration_from_filename (GsdXrandrManager *manager, + const char *filename, + gboolean no_matching_config_is_an_error, + guint32 timestamp, + GError **error) +{ + struct GsdXrandrManagerPrivate *priv = manager->priv; + GError *my_error; + gboolean success; + char *str; + + str = g_strdup_printf ("Applying %s with timestamp %d", filename, timestamp); + show_timestamps_dialog (manager, str); + g_free (str); + + my_error = NULL; + success = mate_rr_config_apply_from_filename_with_time (priv->rw_screen, filename, timestamp, &my_error); + if (success) + return TRUE; + + if (g_error_matches (my_error, MATE_RR_ERROR, MATE_RR_ERROR_NO_MATCHING_CONFIG)) { + if (no_matching_config_is_an_error) + goto fail; + + /* This is not an error; the user probably changed his monitors + * and so they don't match any of the stored configurations. + */ + g_error_free (my_error); + return TRUE; + } + +fail: + g_propagate_error (error, my_error); + return FALSE; +} + +/* This function centralizes the use of mate_rr_config_apply_with_time(). + * + * Applies a configuration and displays an error message if an error happens. + * We just return whether setting the configuration succeeded. + */ +static gboolean +apply_configuration_and_display_error (GsdXrandrManager *manager, MateRRConfig *config, guint32 timestamp) +{ + GsdXrandrManagerPrivate *priv = manager->priv; + GError *error; + gboolean success; + + error = NULL; + success = mate_rr_config_apply_with_time (config, priv->rw_screen, timestamp, &error); + if (!success) { + log_msg ("Could not switch to the following configuration (timestamp %u): %s\n", timestamp, error->message); + log_configuration (config); + error_message (manager, _("Could not switch the monitor configuration"), error, NULL); + g_error_free (error); + } + + return success; +} + +static void +restore_backup_configuration_without_messages (const char *backup_filename, const char *intended_filename) +{ + backup_filename = mate_rr_config_get_backup_filename (); + rename (backup_filename, intended_filename); +} + +static void +restore_backup_configuration (GsdXrandrManager *manager, const char *backup_filename, const char *intended_filename, guint32 timestamp) +{ + int saved_errno; + + if (rename (backup_filename, intended_filename) == 0) { + GError *error; + + error = NULL; + if (!apply_configuration_from_filename (manager, intended_filename, FALSE, timestamp, &error)) { + error_message (manager, _("Could not restore the display's configuration"), error, NULL); + + if (error) + g_error_free (error); + } + + return; + } + + saved_errno = errno; + + /* ENOENT means the original file didn't exist. That is *not* an error; + * the backup was not created because there wasn't even an original + * monitors.xml (such as on a first-time login). Note that *here* there + * is a "didn't work" monitors.xml, so we must delete that one. + */ + if (saved_errno == ENOENT) + unlink (intended_filename); + else { + char *msg; + + msg = g_strdup_printf ("Could not rename %s to %s: %s", + backup_filename, intended_filename, + g_strerror (saved_errno)); + error_message (manager, + _("Could not restore the display's configuration from a backup"), + NULL, + msg); + g_free (msg); + } + + unlink (backup_filename); +} + +typedef struct { + GsdXrandrManager *manager; + GtkWidget *dialog; + + int countdown; + int response_id; +} TimeoutDialog; + +static void +print_countdown_text (TimeoutDialog *timeout) +{ + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (timeout->dialog), + ngettext ("The display will be reset to its previous configuration in %d second", + "The display will be reset to its previous configuration in %d seconds", + timeout->countdown), + timeout->countdown); +} + +static gboolean +timeout_cb (gpointer data) +{ + TimeoutDialog *timeout = data; + + timeout->countdown--; + + if (timeout->countdown == 0) { + timeout->response_id = GTK_RESPONSE_CANCEL; + gtk_main_quit (); + } else { + print_countdown_text (timeout); + } + + return TRUE; +} + +static void +timeout_response_cb (GtkDialog *dialog, int response_id, gpointer data) +{ + TimeoutDialog *timeout = data; + + if (response_id == GTK_RESPONSE_DELETE_EVENT) { + /* The user closed the dialog or pressed ESC, revert */ + timeout->response_id = GTK_RESPONSE_CANCEL; + } else + timeout->response_id = response_id; + + gtk_main_quit (); +} + +static gboolean +user_says_things_are_ok (GsdXrandrManager *manager, GdkWindow *parent_window) +{ + TimeoutDialog timeout; + guint timeout_id; + + timeout.manager = manager; + + timeout.dialog = gtk_message_dialog_new (NULL, + GTK_DIALOG_MODAL, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_NONE, + _("Does the display look OK?")); + + timeout.countdown = CONFIRMATION_DIALOG_SECONDS; + + print_countdown_text (&timeout); + + gtk_dialog_add_button (GTK_DIALOG (timeout.dialog), _("_Restore Previous Configuration"), GTK_RESPONSE_CANCEL); + gtk_dialog_add_button (GTK_DIALOG (timeout.dialog), _("_Keep This Configuration"), GTK_RESPONSE_ACCEPT); + gtk_dialog_set_default_response (GTK_DIALOG (timeout.dialog), GTK_RESPONSE_ACCEPT); /* ah, the optimism */ + + g_signal_connect (timeout.dialog, "response", + G_CALLBACK (timeout_response_cb), + &timeout); + + gtk_widget_realize (timeout.dialog); + + if (parent_window) + gdk_window_set_transient_for (gtk_widget_get_window (timeout.dialog), parent_window); + + gtk_widget_show_all (timeout.dialog); + /* We don't use g_timeout_add_seconds() since we actually care that the user sees "real" second ticks in the dialog */ + timeout_id = g_timeout_add (1000, + timeout_cb, + &timeout); + gtk_main (); + + gtk_widget_destroy (timeout.dialog); + g_source_remove (timeout_id); + + if (timeout.response_id == GTK_RESPONSE_ACCEPT) + return TRUE; + else + return FALSE; +} + +struct confirmation { + GsdXrandrManager *manager; + GdkWindow *parent_window; + guint32 timestamp; +}; + +static gboolean +confirm_with_user_idle_cb (gpointer data) +{ + struct confirmation *confirmation = data; + char *backup_filename; + char *intended_filename; + + backup_filename = mate_rr_config_get_backup_filename (); + intended_filename = mate_rr_config_get_intended_filename (); + + if (user_says_things_are_ok (confirmation->manager, confirmation->parent_window)) + unlink (backup_filename); + else + restore_backup_configuration (confirmation->manager, backup_filename, intended_filename, confirmation->timestamp); + + g_free (confirmation); + + return FALSE; +} + +static void +queue_confirmation_by_user (GsdXrandrManager *manager, GdkWindow *parent_window, guint32 timestamp) +{ + struct confirmation *confirmation; + + confirmation = g_new (struct confirmation, 1); + confirmation->manager = manager; + confirmation->parent_window = parent_window; + confirmation->timestamp = timestamp; + + g_idle_add (confirm_with_user_idle_cb, confirmation); +} + +static gboolean +try_to_apply_intended_configuration (GsdXrandrManager *manager, GdkWindow *parent_window, guint32 timestamp, GError **error) +{ + char *backup_filename; + char *intended_filename; + gboolean result; + + /* Try to apply the intended configuration */ + + backup_filename = mate_rr_config_get_backup_filename (); + intended_filename = mate_rr_config_get_intended_filename (); + + result = apply_configuration_from_filename (manager, intended_filename, FALSE, timestamp, error); + if (!result) { + error_message (manager, _("The selected configuration for displays could not be applied"), error ? *error : NULL, NULL); + restore_backup_configuration_without_messages (backup_filename, intended_filename); + goto out; + } else { + /* We need to return as quickly as possible, so instead of + * confirming with the user right here, we do it in an idle + * handler. The caller only expects a status for "could you + * change the RANDR configuration?", not "is the user OK with it + * as well?". + */ + queue_confirmation_by_user (manager, parent_window, timestamp); + } + +out: + g_free (backup_filename); + g_free (intended_filename); + + return result; +} + +/* DBus method for org.mate.SettingsDaemon.XRANDR ApplyConfiguration; see gsd-xrandr-manager.xml for the interface definition */ +static gboolean +gsd_xrandr_manager_apply_configuration (GsdXrandrManager *manager, + GError **error) +{ + return try_to_apply_intended_configuration (manager, NULL, GDK_CURRENT_TIME, error); +} + +/* DBus method for org.mate.SettingsDaemon.XRANDR_2 ApplyConfiguration; see gsd-xrandr-manager.xml for the interface definition */ +static gboolean +gsd_xrandr_manager_2_apply_configuration (GsdXrandrManager *manager, + gint64 parent_window_id, + gint64 timestamp, + GError **error) +{ + GdkWindow *parent_window; + gboolean result; + + if (parent_window_id != 0) + parent_window = gdk_window_foreign_new_for_display (gdk_display_get_default (), (GdkNativeWindow) parent_window_id); + else + parent_window = NULL; + + result = try_to_apply_intended_configuration (manager, parent_window, (guint32) timestamp, error); + + if (parent_window) + g_object_unref (parent_window); + + return result; +} + +/* We include this after the definition of gsd_xrandr_manager_apply_configuration() so the prototype will already exist */ +#include "gsd-xrandr-manager-glue.h" + +static gboolean +is_laptop (MateRRScreen *screen, MateOutputInfo *output) +{ + MateRROutput *rr_output; + + rr_output = mate_rr_screen_get_output_by_name (screen, output->name); + return mate_rr_output_is_laptop (rr_output); +} + +static gboolean +get_clone_size (MateRRScreen *screen, int *width, int *height) +{ + MateRRMode **modes = mate_rr_screen_list_clone_modes (screen); + int best_w, best_h; + int i; + + best_w = 0; + best_h = 0; + + for (i = 0; modes[i] != NULL; ++i) { + MateRRMode *mode = modes[i]; + int w, h; + + w = mate_rr_mode_get_width (mode); + h = mate_rr_mode_get_height (mode); + + if (w * h > best_w * best_h) { + best_w = w; + best_h = h; + } + } + + if (best_w > 0 && best_h > 0) { + if (width) + *width = best_w; + if (height) + *height = best_h; + + return TRUE; + } + + return FALSE; +} + +static void +print_output (MateOutputInfo *info) +{ + g_print (" Output: %s attached to %s\n", info->display_name, info->name); + g_print (" status: %s\n", info->on ? "on" : "off"); + g_print (" width: %d\n", info->width); + g_print (" height: %d\n", info->height); + g_print (" rate: %d\n", info->rate); + g_print (" position: %d %d\n", info->x, info->y); +} + +static void +print_configuration (MateRRConfig *config, const char *header) +{ + int i; + + g_print ("=== %s Configuration ===\n", header); + if (!config) { + g_print (" none\n"); + return; + } + + for (i = 0; config->outputs[i] != NULL; ++i) + print_output (config->outputs[i]); +} + +static gboolean +config_is_all_off (MateRRConfig *config) +{ + int j; + + for (j = 0; config->outputs[j] != NULL; ++j) { + if (config->outputs[j]->on) { + return FALSE; + } + } + + return TRUE; +} + +static MateRRConfig * +make_clone_setup (MateRRScreen *screen) +{ + MateRRConfig *result; + int width, height; + int i; + + if (!get_clone_size (screen, &width, &height)) + return NULL; + + result = mate_rr_config_new_current (screen); + + for (i = 0; result->outputs[i] != NULL; ++i) { + MateOutputInfo *info = result->outputs[i]; + + info->on = FALSE; + if (info->connected) { + MateRROutput *output = + mate_rr_screen_get_output_by_name (screen, info->name); + MateRRMode **modes = mate_rr_output_list_modes (output); + int j; + int best_rate = 0; + + for (j = 0; modes[j] != NULL; ++j) { + MateRRMode *mode = modes[j]; + int w, h; + + w = mate_rr_mode_get_width (mode); + h = mate_rr_mode_get_height (mode); + + if (w == width && h == height) { + int r = mate_rr_mode_get_freq (mode); + if (r > best_rate) + best_rate = r; + } + } + + if (best_rate > 0) { + info->on = TRUE; + info->width = width; + info->height = height; + info->rate = best_rate; + info->rotation = MATE_RR_ROTATION_0; + info->x = 0; + info->y = 0; + } + } + } + + if (config_is_all_off (result)) { + mate_rr_config_free (result); + result = NULL; + } + + print_configuration (result, "clone setup"); + + return result; +} + +static MateRRMode * +find_best_mode (MateRROutput *output) +{ + MateRRMode *preferred; + MateRRMode **modes; + int best_size; + int best_width, best_height, best_rate; + int i; + MateRRMode *best_mode; + + preferred = mate_rr_output_get_preferred_mode (output); + if (preferred) + return preferred; + + modes = mate_rr_output_list_modes (output); + if (!modes) + return NULL; + + best_size = best_width = best_height = best_rate = 0; + best_mode = NULL; + + for (i = 0; modes[i] != NULL; i++) { + int w, h, r; + int size; + + w = mate_rr_mode_get_width (modes[i]); + h = mate_rr_mode_get_height (modes[i]); + r = mate_rr_mode_get_freq (modes[i]); + + size = w * h; + + if (size > best_size) { + best_size = size; + best_width = w; + best_height = h; + best_rate = r; + best_mode = modes[i]; + } else if (size == best_size) { + if (r > best_rate) { + best_rate = r; + best_mode = modes[i]; + } + } + } + + return best_mode; +} + +static gboolean +turn_on (MateRRScreen *screen, + MateOutputInfo *info, + int x, int y) +{ + MateRROutput *output = mate_rr_screen_get_output_by_name (screen, info->name); + MateRRMode *mode = find_best_mode (output); + + if (mode) { + info->on = TRUE; + info->x = x; + info->y = y; + info->width = mate_rr_mode_get_width (mode); + info->height = mate_rr_mode_get_height (mode); + info->rotation = MATE_RR_ROTATION_0; + info->rate = mate_rr_mode_get_freq (mode); + + return TRUE; + } + + return FALSE; +} + +static MateRRConfig * +make_laptop_setup (MateRRScreen *screen) +{ + /* Turn on the laptop, disable everything else */ + MateRRConfig *result = mate_rr_config_new_current (screen); + int i; + + for (i = 0; result->outputs[i] != NULL; ++i) { + MateOutputInfo *info = result->outputs[i]; + + if (is_laptop (screen, info)) { + if (!turn_on (screen, info, 0, 0)) { + mate_rr_config_free (result); + result = NULL; + break; + } + } + else { + info->on = FALSE; + } + } + + if (config_is_all_off (result)) { + mate_rr_config_free (result); + result = NULL; + } + + print_configuration (result, "Laptop setup"); + + /* FIXME - Maybe we should return NULL if there is more than + * one connected "laptop" screen? + */ + return result; + +} + +static int +turn_on_and_get_rightmost_offset (MateRRScreen *screen, MateOutputInfo *info, int x) +{ + if (turn_on (screen, info, x, 0)) + x += info->width; + + return x; +} + +static MateRRConfig * +make_xinerama_setup (MateRRScreen *screen) +{ + /* Turn on everything that has a preferred mode, and + * position it from left to right + */ + MateRRConfig *result = mate_rr_config_new_current (screen); + int i; + int x; + + x = 0; + for (i = 0; result->outputs[i] != NULL; ++i) { + MateOutputInfo *info = result->outputs[i]; + + if (is_laptop (screen, info)) + x = turn_on_and_get_rightmost_offset (screen, info, x); + } + + for (i = 0; result->outputs[i] != NULL; ++i) { + MateOutputInfo *info = result->outputs[i]; + + if (info->connected && !is_laptop (screen, info)) + x = turn_on_and_get_rightmost_offset (screen, info, x); + } + + if (config_is_all_off (result)) { + mate_rr_config_free (result); + result = NULL; + } + + print_configuration (result, "xinerama setup"); + + return result; +} + +static MateRRConfig * +make_other_setup (MateRRScreen *screen) +{ + /* Turn off all laptops, and make all external monitors clone + * from (0, 0) + */ + + MateRRConfig *result = mate_rr_config_new_current (screen); + int i; + + for (i = 0; result->outputs[i] != NULL; ++i) { + MateOutputInfo *info = result->outputs[i]; + + if (is_laptop (screen, info)) { + info->on = FALSE; + } + else { + if (info->connected) + turn_on (screen, info, 0, 0); + } + } + + if (config_is_all_off (result)) { + mate_rr_config_free (result); + result = NULL; + } + + print_configuration (result, "other setup"); + + return result; +} + +static GPtrArray * +sanitize (GsdXrandrManager *manager, GPtrArray *array) +{ + int i; + GPtrArray *new; + + g_debug ("before sanitizing"); + + for (i = 0; i < array->len; ++i) { + if (array->pdata[i]) { + print_configuration (array->pdata[i], "before"); + } + } + + + /* Remove configurations that are duplicates of + * configurations earlier in the cycle + */ + for (i = 0; i < array->len; i++) { + int j; + + for (j = i + 1; j < array->len; j++) { + MateRRConfig *this = array->pdata[j]; + MateRRConfig *other = array->pdata[i]; + + if (this && other && mate_rr_config_equal (this, other)) { + g_debug ("removing duplicate configuration"); + mate_rr_config_free (this); + array->pdata[j] = NULL; + break; + } + } + } + + for (i = 0; i < array->len; ++i) { + MateRRConfig *config = array->pdata[i]; + + if (config && config_is_all_off (config)) { + g_debug ("removing configuration as all outputs are off"); + mate_rr_config_free (array->pdata[i]); + array->pdata[i] = NULL; + } + } + + /* Do a final sanitization pass. This will remove configurations that + * don't fit in the framebuffer's Virtual size. + */ + + for (i = 0; i < array->len; i++) { + MateRRConfig *config = array->pdata[i]; + + if (config) { + GError *error; + + error = NULL; + if (!mate_rr_config_applicable (config, manager->priv->rw_screen, &error)) { /* NULL-GError */ + g_debug ("removing configuration which is not applicable because %s", error->message); + g_error_free (error); + + mate_rr_config_free (config); + array->pdata[i] = NULL; + } + } + } + + /* Remove NULL configurations */ + new = g_ptr_array_new (); + + for (i = 0; i < array->len; ++i) { + if (array->pdata[i]) { + g_ptr_array_add (new, array->pdata[i]); + print_configuration (array->pdata[i], "Final"); + } + } + + if (new->len > 0) { + g_ptr_array_add (new, NULL); + } else { + g_ptr_array_free (new, TRUE); + new = NULL; + } + + g_ptr_array_free (array, TRUE); + + return new; +} + +static void +generate_fn_f7_configs (GsdXrandrManager *mgr) +{ + GPtrArray *array = g_ptr_array_new (); + MateRRScreen *screen = mgr->priv->rw_screen; + + g_debug ("Generating configurations"); + + /* Free any existing list of configurations */ + if (mgr->priv->fn_f7_configs) { + int i; + + for (i = 0; mgr->priv->fn_f7_configs[i] != NULL; ++i) + mate_rr_config_free (mgr->priv->fn_f7_configs[i]); + g_free (mgr->priv->fn_f7_configs); + + mgr->priv->fn_f7_configs = NULL; + mgr->priv->current_fn_f7_config = -1; + } + + g_ptr_array_add (array, mate_rr_config_new_current (screen)); + g_ptr_array_add (array, make_clone_setup (screen)); + g_ptr_array_add (array, make_xinerama_setup (screen)); + g_ptr_array_add (array, make_laptop_setup (screen)); + g_ptr_array_add (array, make_other_setup (screen)); + + array = sanitize (mgr, array); + + if (array) { + mgr->priv->fn_f7_configs = (MateRRConfig **)g_ptr_array_free (array, FALSE); + mgr->priv->current_fn_f7_config = 0; + } +} + +static void +error_message (GsdXrandrManager *mgr, const char *primary_text, GError *error_to_display, const char *secondary_text) +{ +#ifdef HAVE_LIBMATENOTIFY + GsdXrandrManagerPrivate *priv = mgr->priv; + NotifyNotification *notification; + + g_assert (error_to_display == NULL || secondary_text == NULL); + + if (priv->status_icon) + notification = notify_notification_new_with_status_icon (primary_text, + error_to_display ? error_to_display->message : secondary_text, + GSD_XRANDR_ICON_NAME, + priv->status_icon); + else + notification = notify_notification_new (primary_text, + error_to_display ? error_to_display->message : secondary_text, + GSD_XRANDR_ICON_NAME, + NULL); + + notify_notification_show (notification, NULL); /* NULL-GError */ +#else + GtkWidget *dialog; + + dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, + "%s", primary_text); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", + error_to_display ? error_to_display->message : secondary_text); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); +#endif /* HAVE_LIBMATENOTIFY */ +} + +static void +handle_fn_f7 (GsdXrandrManager *mgr, guint32 timestamp) +{ + GsdXrandrManagerPrivate *priv = mgr->priv; + MateRRScreen *screen = priv->rw_screen; + MateRRConfig *current; + GError *error; + + /* Theory of fn-F7 operation + * + * We maintain a datastructure "fn_f7_status", that contains + * a list of MateRRConfig's. Each of the MateRRConfigs has a + * mode (or "off") for each connected output. + * + * When the user hits fn-F7, we cycle to the next MateRRConfig + * in the data structure. If the data structure does not exist, it + * is generated. If the configs in the data structure do not match + * the current hardware reality, it is regenerated. + * + */ + g_debug ("Handling fn-f7"); + + log_open (); + log_msg ("Handling XF86Display hotkey - timestamp %u\n", timestamp); + + error = NULL; + if (!mate_rr_screen_refresh (screen, &error) && error) { + char *str; + + str = g_strdup_printf (_("Could not refresh the screen information: %s"), error->message); + g_error_free (error); + + log_msg ("%s\n", str); + error_message (mgr, str, NULL, _("Trying to switch the monitor configuration anyway.")); + g_free (str); + } + + if (!priv->fn_f7_configs) { + log_msg ("Generating stock configurations:\n"); + generate_fn_f7_configs (mgr); + log_configurations (priv->fn_f7_configs); + } + + current = mate_rr_config_new_current (screen); + + if (priv->fn_f7_configs && + (!mate_rr_config_match (current, priv->fn_f7_configs[0]) || + !mate_rr_config_equal (current, priv->fn_f7_configs[mgr->priv->current_fn_f7_config]))) { + /* Our view of the world is incorrect, so regenerate the + * configurations + */ + generate_fn_f7_configs (mgr); + log_msg ("Regenerated stock configurations:\n"); + log_configurations (priv->fn_f7_configs); + } + + mate_rr_config_free (current); + + if (priv->fn_f7_configs) { + guint32 server_timestamp; + gboolean success; + + mgr->priv->current_fn_f7_config++; + + if (priv->fn_f7_configs[mgr->priv->current_fn_f7_config] == NULL) + mgr->priv->current_fn_f7_config = 0; + + g_debug ("cycling to next configuration (%d)", mgr->priv->current_fn_f7_config); + + print_configuration (priv->fn_f7_configs[mgr->priv->current_fn_f7_config], "new config"); + + g_debug ("applying"); + + /* See https://bugzilla.gnome.org/show_bug.cgi?id=610482 + * + * Sometimes we'll get two rapid XF86Display keypress events, + * but their timestamps will be out of order with respect to the + * RANDR timestamps. This *may* be due to stupid BIOSes sending + * out display-switch keystrokes "to make Windows work". + * + * The X server will error out if the timestamp provided is + * older than a previous change configuration timestamp. We + * assume here that we do want this event to go through still, + * since kernel timestamps may be skewed wrt the X server. + */ + mate_rr_screen_get_timestamps (screen, NULL, &server_timestamp); + if (timestamp < server_timestamp) + timestamp = server_timestamp; + + success = apply_configuration_and_display_error (mgr, priv->fn_f7_configs[mgr->priv->current_fn_f7_config], timestamp); + + if (success) { + log_msg ("Successfully switched to configuration (timestamp %u):\n", timestamp); + log_configuration (priv->fn_f7_configs[mgr->priv->current_fn_f7_config]); + } + } + else { + g_debug ("no configurations generated"); + } + + log_close (); + + g_debug ("done handling fn-f7"); +} + +static MateOutputInfo * +get_laptop_output_info (MateRRScreen *screen, MateRRConfig *config) +{ + int i; + + for (i = 0; config->outputs[i] != NULL; i++) { + MateOutputInfo *info; + + info = config->outputs[i]; + if (is_laptop (screen, info)) + return info; + } + + return NULL; + +} + +static MateRRRotation +get_next_rotation (MateRRRotation allowed_rotations, MateRRRotation current_rotation) +{ + int i; + int current_index; + + /* First, find the index of the current rotation */ + + current_index = -1; + + for (i = 0; i < G_N_ELEMENTS (possible_rotations); i++) { + MateRRRotation r; + + r = possible_rotations[i]; + if (r == current_rotation) { + current_index = i; + break; + } + } + + if (current_index == -1) { + /* Huh, the current_rotation was not one of the supported rotations. Bail out. */ + return current_rotation; + } + + /* Then, find the next rotation that is allowed */ + + i = (current_index + 1) % G_N_ELEMENTS (possible_rotations); + + while (1) { + MateRRRotation r; + + r = possible_rotations[i]; + if (r == current_rotation) { + /* We wrapped around and no other rotation is suported. Bummer. */ + return current_rotation; + } else if (r & allowed_rotations) + return r; + + i = (i + 1) % G_N_ELEMENTS (possible_rotations); + } +} + +/* We use this when the XF86RotateWindows key is pressed. That key is present + * on some tablet PCs; they use it so that the user can rotate the tablet + * easily. + */ +static void +handle_rotate_windows (GsdXrandrManager *mgr, guint32 timestamp) +{ + GsdXrandrManagerPrivate *priv = mgr->priv; + MateRRScreen *screen = priv->rw_screen; + MateRRConfig *current; + MateOutputInfo *rotatable_output_info; + int num_allowed_rotations; + MateRRRotation allowed_rotations; + MateRRRotation next_rotation; + + g_debug ("Handling XF86RotateWindows"); + + /* Which output? */ + + current = mate_rr_config_new_current (screen); + + rotatable_output_info = get_laptop_output_info (screen, current); + if (rotatable_output_info == NULL) { + g_debug ("No laptop outputs found to rotate; XF86RotateWindows key will do nothing"); + goto out; + } + + /* Which rotation? */ + + get_allowed_rotations_for_output (current, priv->rw_screen, rotatable_output_info, &num_allowed_rotations, &allowed_rotations); + next_rotation = get_next_rotation (allowed_rotations, rotatable_output_info->rotation); + + if (next_rotation == rotatable_output_info->rotation) { + g_debug ("No rotations are supported other than the current one; XF86RotateWindows key will do nothing"); + goto out; + } + + /* Rotate */ + + rotatable_output_info->rotation = next_rotation; + + apply_configuration_and_display_error (mgr, current, timestamp); + +out: + mate_rr_config_free (current); +} + +static GdkFilterReturn +event_filter (GdkXEvent *xevent, + GdkEvent *event, + gpointer data) +{ + GsdXrandrManager *manager = data; + XEvent *xev = (XEvent *) xevent; + + if (!manager->priv->running) + return GDK_FILTER_CONTINUE; + + /* verify we have a key event */ + if (xev->xany.type != KeyPress && xev->xany.type != KeyRelease) + return GDK_FILTER_CONTINUE; + + if (xev->xany.type == KeyPress) { + if (xev->xkey.keycode == manager->priv->switch_video_mode_keycode) + handle_fn_f7 (manager, xev->xkey.time); + else if (xev->xkey.keycode == manager->priv->rotate_windows_keycode) + handle_rotate_windows (manager, xev->xkey.time); + + return GDK_FILTER_CONTINUE; + } + + return GDK_FILTER_CONTINUE; +} + +static void +refresh_tray_icon_menu_if_active (GsdXrandrManager *manager, guint32 timestamp) +{ + GsdXrandrManagerPrivate *priv = manager->priv; + + if (priv->popup_menu) { + gtk_menu_shell_cancel (GTK_MENU_SHELL (priv->popup_menu)); /* status_icon_popup_menu_selection_done_cb() will free everything */ + status_icon_popup_menu (manager, 0, timestamp); + } +} + +static void +auto_configure_outputs (GsdXrandrManager *manager, guint32 timestamp) +{ + GsdXrandrManagerPrivate *priv = manager->priv; + MateRRConfig *config; + int i; + GList *just_turned_on; + GList *l; + int x; + GError *error; + gboolean applicable; + + config = mate_rr_config_new_current (priv->rw_screen); + + /* For outputs that are connected and on (i.e. they have a CRTC assigned + * to them, so they are getting a signal), we leave them as they are + * with their current modes. + * + * For other outputs, we will turn on connected-but-off outputs and turn + * off disconnected-but-on outputs. + * + * FIXME: If an output remained connected+on, it would be nice to ensure + * that the output's CRTCs still has a reasonable mode (think of + * changing one monitor for another with different capabilities). + */ + + just_turned_on = NULL; + + for (i = 0; config->outputs[i] != NULL; i++) { + MateOutputInfo *output = config->outputs[i]; + + if (output->connected && !output->on) { + output->on = TRUE; + output->rotation = MATE_RR_ROTATION_0; + just_turned_on = g_list_prepend (just_turned_on, GINT_TO_POINTER (i)); + } else if (!output->connected && output->on) + output->on = FALSE; + } + + /* Now, lay out the outputs from left to right. Put first the outputs + * which remained on; put last the outputs that were newly turned on. + */ + + x = 0; + + /* First, outputs that remained on */ + + for (i = 0; config->outputs[i] != NULL; i++) { + MateOutputInfo *output = config->outputs[i]; + + if (g_list_find (just_turned_on, GINT_TO_POINTER (i))) + continue; + + if (output->on) { + g_assert (output->connected); + + output->x = x; + output->y = 0; + + x += output->width; + } + } + + /* Second, outputs that were newly-turned on */ + + for (l = just_turned_on; l; l = l->next) { + MateOutputInfo *output; + + i = GPOINTER_TO_INT (l->data); + output = config->outputs[i]; + + g_assert (output->on && output->connected); + + output->x = x; + output->y = 0; + + /* since the output was off, use its preferred width/height (it doesn't have a real width/height yet) */ + output->width = output->pref_width; + output->height = output->pref_height; + + x += output->width; + } + + /* Check if we have a large enough framebuffer size. If not, turn off + * outputs from right to left until we reach a usable size. + */ + + just_turned_on = g_list_reverse (just_turned_on); /* now the outputs here are from right to left */ + + l = just_turned_on; + while (1) { + MateOutputInfo *output; + gboolean is_bounds_error; + + error = NULL; + applicable = mate_rr_config_applicable (config, priv->rw_screen, &error); + + if (applicable) + break; + + is_bounds_error = g_error_matches (error, MATE_RR_ERROR, MATE_RR_ERROR_BOUNDS_ERROR); + g_error_free (error); + + if (!is_bounds_error) + break; + + if (l) { + i = GPOINTER_TO_INT (l->data); + l = l->next; + + output = config->outputs[i]; + output->on = FALSE; + } else + break; + } + + /* Apply the configuration! */ + + if (applicable) + apply_configuration_and_display_error (manager, config, timestamp); + + g_list_free (just_turned_on); + mate_rr_config_free (config); + + /* Finally, even though we did a best-effort job in sanitizing the + * outputs, we don't know the physical layout of the monitors. We'll + * start the display capplet so that the user can tweak things to his + * liking. + */ + +#if 0 + /* FIXME: This is disabled for now. The capplet is not a single-instance application. + * If you do this: + * + * 1. Start the display capplet + * + * 2. Plug an extra monitor + * + * 3. Hit the "Detect displays" button + * + * Then we will get a RANDR event because X re-probes the outputs. We don't want to + * start up a second display capplet right there! + */ + + run_display_capplet (NULL); +#endif +} + +static void +apply_color_profiles (void) +{ + gboolean ret; + GError *error = NULL; + + /* run the mate-color-manager apply program */ + ret = g_spawn_command_line_async (BINDIR "/gcm-apply", &error); + if (!ret) { + /* only print the warning if the binary is installed */ + if (error->code != G_SPAWN_ERROR_NOENT) { + g_warning ("failed to apply color profiles: %s", error->message); + } + g_error_free (error); + } +} + +static void +on_randr_event (MateRRScreen *screen, gpointer data) +{ + GsdXrandrManager *manager = GSD_XRANDR_MANAGER (data); + GsdXrandrManagerPrivate *priv = manager->priv; + guint32 change_timestamp, config_timestamp; + + if (!priv->running) + return; + + mate_rr_screen_get_timestamps (screen, &change_timestamp, &config_timestamp); + + log_open (); + log_msg ("Got RANDR event with timestamps change=%u %c config=%u\n", + change_timestamp, + timestamp_relationship (change_timestamp, config_timestamp), + config_timestamp); + + if (change_timestamp >= config_timestamp) { + /* The event is due to an explicit configuration change. + * + * If the change was performed by us, then we need to do nothing. + * + * If the change was done by some other X client, we don't need + * to do anything, either; the screen is already configured. + */ + show_timestamps_dialog (manager, "ignoring since change > config"); + log_msg (" Ignoring event since change >= config\n"); + } else { + /* Here, config_timestamp > change_timestamp. This means that + * the screen got reconfigured because of hotplug/unplug; the X + * server is just notifying us, and we need to configure the + * outputs in a sane way. + */ + + char *intended_filename; + GError *error; + gboolean success; + + show_timestamps_dialog (manager, "need to deal with reconfiguration, as config > change"); + + intended_filename = mate_rr_config_get_intended_filename (); + + error = NULL; + success = apply_configuration_from_filename (manager, intended_filename, TRUE, config_timestamp, &error); + g_free (intended_filename); + + if (!success) { + /* We don't bother checking the error type. + * + * Both G_FILE_ERROR_NOENT and + * MATE_RR_ERROR_NO_MATCHING_CONFIG would mean, "there + * was no configuration to apply, or none that matched + * the current outputs", and in that case we need to run + * our fallback. + * + * Any other error means "we couldn't do the smart thing + * of using a previously- saved configuration, anyway, + * for some other reason. In that case, we also need to + * run our fallback to avoid leaving the user with a + * bogus configuration. + */ + + if (error) + g_error_free (error); + + if (config_timestamp != priv->last_config_timestamp) { + priv->last_config_timestamp = config_timestamp; + auto_configure_outputs (manager, config_timestamp); + log_msg (" Automatically configured outputs to deal with event\n"); + } else + log_msg (" Ignored event as old and new config timestamps are the same\n"); + } else + log_msg ("Applied stored configuration to deal with event\n"); + } + + /* poke mate-color-manager */ + apply_color_profiles (); + + refresh_tray_icon_menu_if_active (manager, MAX (change_timestamp, config_timestamp)); + + log_close (); +} + +static void +run_display_capplet (GtkWidget *widget) +{ + GdkScreen *screen; + GError *error; + + if (widget) + screen = gtk_widget_get_screen (widget); + else + screen = gdk_screen_get_default (); + + error = NULL; + if (!gdk_spawn_command_line_on_screen (screen, GSD_XRANDR_DISPLAY_CAPPLET, &error)) { + GtkWidget *dialog; + + dialog = gtk_message_dialog_new_with_markup (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, + "<span weight=\"bold\" size=\"larger\">" + "Display configuration could not be run" + "</span>\n\n" + "%s", error->message); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + + g_error_free (error); + } +} + +static void +popup_menu_configure_display_cb (GtkMenuItem *item, gpointer data) +{ + run_display_capplet (GTK_WIDGET (item)); +} + +static void +status_icon_popup_menu_selection_done_cb (GtkMenuShell *menu_shell, gpointer data) +{ + GsdXrandrManager *manager = GSD_XRANDR_MANAGER (data); + struct GsdXrandrManagerPrivate *priv = manager->priv; + + gtk_widget_destroy (priv->popup_menu); + priv->popup_menu = NULL; + + mate_rr_labeler_hide (priv->labeler); + g_object_unref (priv->labeler); + priv->labeler = NULL; + + mate_rr_config_free (priv->configuration); + priv->configuration = NULL; +} + +#define OUTPUT_TITLE_ITEM_BORDER 2 +#define OUTPUT_TITLE_ITEM_PADDING 4 + +/* This is an expose-event hander for the title label for each MateRROutput. + * We want each title to have a colored background, so we paint that background, then + * return FALSE to let GtkLabel expose itself (i.e. paint the label's text), and then + * we have a signal_connect_after handler as well. See the comments below + * to see why that "after" handler is needed. + */ +static gboolean +output_title_label_expose_event_cb (GtkWidget *widget, GdkEventExpose *event, gpointer data) +{ + GsdXrandrManager *manager = GSD_XRANDR_MANAGER (data); + struct GsdXrandrManagerPrivate *priv = manager->priv; + MateOutputInfo *output; + GdkColor color; + cairo_t *cr; + GtkAllocation allocation; + + g_assert (GTK_IS_LABEL (widget)); + + output = g_object_get_data (G_OBJECT (widget), "output"); + g_assert (output != NULL); + + g_assert (priv->labeler != NULL); + + /* Draw a black rectangular border, filled with the color that corresponds to this output */ + + mate_rr_labeler_get_color_for_output (priv->labeler, output, &color); + + cr = gdk_cairo_create (gtk_widget_get_window (widget)); + + cairo_set_source_rgb (cr, 0, 0, 0); + cairo_set_line_width (cr, OUTPUT_TITLE_ITEM_BORDER); + gtk_widget_get_allocation (widget, &allocation); + cairo_rectangle (cr, + allocation.x + OUTPUT_TITLE_ITEM_BORDER / 2.0, + allocation.y + OUTPUT_TITLE_ITEM_BORDER / 2.0, + allocation.width - OUTPUT_TITLE_ITEM_BORDER, + allocation.height - OUTPUT_TITLE_ITEM_BORDER); + cairo_stroke (cr); + + gdk_cairo_set_source_color (cr, &color); + cairo_rectangle (cr, + allocation.x + OUTPUT_TITLE_ITEM_BORDER, + allocation.y + OUTPUT_TITLE_ITEM_BORDER, + allocation.width - 2 * OUTPUT_TITLE_ITEM_BORDER, + allocation.height - 2 * OUTPUT_TITLE_ITEM_BORDER); + + cairo_fill (cr); + + /* We want the label to always show up as if it were sensitive + * ("style->fg[GTK_STATE_NORMAL]"), even though the label is insensitive + * due to being inside an insensitive menu item. So, here we have a + * HACK in which we frob the label's state directly. GtkLabel's expose + * handler will be run after this function, so it will think that the + * label is in GTK_STATE_NORMAL. We reset the label's state back to + * insensitive in output_title_label_after_expose_event_cb(). + * + * Yay for fucking with GTK+'s internals. + */ + + gtk_widget_set_state (widget, GTK_STATE_NORMAL); + + return FALSE; +} + +/* See the comment in output_title_event_box_expose_event_cb() about this funny label widget */ +static gboolean +output_title_label_after_expose_event_cb (GtkWidget *widget, GdkEventExpose *event, gpointer data) +{ + g_assert (GTK_IS_LABEL (widget)); + gtk_widget_set_state (widget, GTK_STATE_INSENSITIVE); + + return FALSE; +} + +static void +title_item_size_allocate_cb (GtkWidget *widget, GtkAllocation *allocation, gpointer data) +{ + /* When GtkMenu does size_request on its items, it asks them for their "toggle size", + * which will be non-zero when there are check/radio items. GtkMenu remembers + * the largest of those sizes. During the size_allocate pass, GtkMenu calls + * gtk_menu_item_toggle_size_allocate() with that value, to tell the menu item + * that it should later paint its child a bit to the right of its edge. + * + * However, we want the "title" menu items for each RANDR output to span the *whole* + * allocation of the menu item, not just the "allocation minus toggle" area. + * + * So, we let the menu item size_allocate itself as usual, but this + * callback gets run afterward. Here we hack a toggle size of 0 into + * the menu item, and size_allocate it by hand *again*. We also need to + * avoid recursing into this function. + */ + + g_assert (GTK_IS_MENU_ITEM (widget)); + + gtk_menu_item_toggle_size_allocate (GTK_MENU_ITEM (widget), 0); + + g_signal_handlers_block_by_func (widget, title_item_size_allocate_cb, NULL); + + /* Sigh. There is no way to turn on GTK_ALLOC_NEEDED outside of GTK+ + * itself; also, since calling size_allocate on a widget with the same + * allcation is a no-op, we need to allocate with a "different" size + * first. + */ + + allocation->width++; + gtk_widget_size_allocate (widget, allocation); + + allocation->width--; + gtk_widget_size_allocate (widget, allocation); + + g_signal_handlers_unblock_by_func (widget, title_item_size_allocate_cb, NULL); +} + +static GtkWidget * +make_menu_item_for_output_title (GsdXrandrManager *manager, MateOutputInfo *output) +{ + GtkWidget *item; + GtkWidget *label; + char *str; + GdkColor black = { 0, 0, 0, 0 }; + + item = gtk_menu_item_new (); + + g_signal_connect (item, "size-allocate", + G_CALLBACK (title_item_size_allocate_cb), NULL); + + str = g_markup_printf_escaped ("<b>%s</b>", output->display_name); + label = gtk_label_new (NULL); + gtk_label_set_markup (GTK_LABEL (label), str); + g_free (str); + + /* Make the label explicitly black. We don't want it to follow the + * theme's colors, since the label is always shown against a light + * pastel background. See bgo#556050 + */ + gtk_widget_modify_fg (label, gtk_widget_get_state (label), &black); + + /* Add padding around the label to fit the box that we'll draw for color-coding */ + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_misc_set_padding (GTK_MISC (label), + OUTPUT_TITLE_ITEM_BORDER + OUTPUT_TITLE_ITEM_PADDING, + OUTPUT_TITLE_ITEM_BORDER + OUTPUT_TITLE_ITEM_PADDING); + + gtk_container_add (GTK_CONTAINER (item), label); + + /* We want to paint a colored box as the background of the label, so we connect + * to its expose-event signal. See the comment in *** to see why need to connect + * to the label both 'before' and 'after'. + */ + g_signal_connect (label, "expose-event", + G_CALLBACK (output_title_label_expose_event_cb), manager); + g_signal_connect_after (label, "expose-event", + G_CALLBACK (output_title_label_after_expose_event_cb), manager); + + g_object_set_data (G_OBJECT (label), "output", output); + + gtk_widget_set_sensitive (item, FALSE); /* the title is not selectable */ + gtk_widget_show_all (item); + + return item; +} + +static void +get_allowed_rotations_for_output (MateRRConfig *config, + MateRRScreen *rr_screen, + MateOutputInfo *output, + int *out_num_rotations, + MateRRRotation *out_rotations) +{ + MateRRRotation current_rotation; + int i; + + *out_num_rotations = 0; + *out_rotations = 0; + + current_rotation = output->rotation; + + /* Yay for brute force */ + + for (i = 0; i < G_N_ELEMENTS (possible_rotations); i++) { + MateRRRotation rotation_to_test; + + rotation_to_test = possible_rotations[i]; + + output->rotation = rotation_to_test; + + if (mate_rr_config_applicable (config, rr_screen, NULL)) { /* NULL-GError */ + (*out_num_rotations)++; + (*out_rotations) |= rotation_to_test; + } + } + + output->rotation = current_rotation; + + if (*out_num_rotations == 0 || *out_rotations == 0) { + g_warning ("Huh, output %p says it doesn't support any rotations, and yet it has a current rotation?", output); + *out_num_rotations = 1; + *out_rotations = output->rotation; + } +} + +static void +add_unsupported_rotation_item (GsdXrandrManager *manager) +{ + struct GsdXrandrManagerPrivate *priv = manager->priv; + GtkWidget *item; + GtkWidget *label; + gchar *markup; + + item = gtk_menu_item_new (); + + label = gtk_label_new (NULL); + markup = g_strdup_printf ("<i>%s</i>", _("Rotation not supported")); + gtk_label_set_markup (GTK_LABEL (label), markup); + g_free (markup); + gtk_container_add (GTK_CONTAINER (item), label); + + gtk_widget_show_all (item); + gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), item); +} + +static void +ensure_current_configuration_is_saved (void) +{ + MateRRScreen *rr_screen; + MateRRConfig *rr_config; + + /* Normally, mate_rr_config_save() creates a backup file based on the + * old monitors.xml. However, if *that* file didn't exist, there is + * nothing from which to create a backup. So, here we'll save the + * current/unchanged configuration and then let our caller call + * mate_rr_config_save() again with the new/changed configuration, so + * that there *will* be a backup file in the end. + */ + + rr_screen = mate_rr_screen_new (gdk_screen_get_default (), NULL, NULL, NULL); /* NULL-GError */ + if (!rr_screen) + return; + + rr_config = mate_rr_config_new_current (rr_screen); + mate_rr_config_save (rr_config, NULL); /* NULL-GError */ + + mate_rr_config_free (rr_config); + mate_rr_screen_destroy (rr_screen); +} + +static void +output_rotation_item_activate_cb (GtkCheckMenuItem *item, gpointer data) +{ + GsdXrandrManager *manager = GSD_XRANDR_MANAGER (data); + struct GsdXrandrManagerPrivate *priv = manager->priv; + MateOutputInfo *output; + MateRRRotation rotation; + GError *error; + + /* Not interested in deselected items */ + if (!gtk_check_menu_item_get_active (item)) + return; + + ensure_current_configuration_is_saved (); + + output = g_object_get_data (G_OBJECT (item), "output"); + rotation = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "rotation")); + + output->rotation = rotation; + + error = NULL; + if (!mate_rr_config_save (priv->configuration, &error)) { + error_message (manager, _("Could not save monitor configuration"), error, NULL); + if (error) + g_error_free (error); + + return; + } + + try_to_apply_intended_configuration (manager, NULL, gtk_get_current_event_time (), NULL); /* NULL-GError */ +} + +static void +add_items_for_rotations (GsdXrandrManager *manager, MateOutputInfo *output, MateRRRotation allowed_rotations) +{ + typedef struct { + MateRRRotation rotation; + const char * name; + } RotationInfo; + static const RotationInfo rotations[] = { + { MATE_RR_ROTATION_0, N_("Normal") }, + { MATE_RR_ROTATION_90, N_("Left") }, + { MATE_RR_ROTATION_270, N_("Right") }, + { MATE_RR_ROTATION_180, N_("Upside Down") }, + /* We don't allow REFLECT_X or REFLECT_Y for now, as mate-display-properties doesn't allow them, either */ + }; + + struct GsdXrandrManagerPrivate *priv = manager->priv; + int i; + GSList *group; + GtkWidget *active_item; + gulong active_item_activate_id; + + group = NULL; + active_item = NULL; + active_item_activate_id = 0; + + for (i = 0; i < G_N_ELEMENTS (rotations); i++) { + MateRRRotation rot; + GtkWidget *item; + gulong activate_id; + + rot = rotations[i].rotation; + + if ((allowed_rotations & rot) == 0) { + /* don't display items for rotations which are + * unavailable. Their availability is not under the + * user's control, anyway. + */ + continue; + } + + item = gtk_radio_menu_item_new_with_label (group, _(rotations[i].name)); + gtk_widget_show_all (item); + gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), item); + + g_object_set_data (G_OBJECT (item), "output", output); + g_object_set_data (G_OBJECT (item), "rotation", GINT_TO_POINTER (rot)); + + activate_id = g_signal_connect (item, "activate", + G_CALLBACK (output_rotation_item_activate_cb), manager); + + group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item)); + + if (rot == output->rotation) { + active_item = item; + active_item_activate_id = activate_id; + } + } + + if (active_item) { + /* Block the signal temporarily so our callback won't be called; + * we are just setting up the UI. + */ + g_signal_handler_block (active_item, active_item_activate_id); + + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (active_item), TRUE); + + g_signal_handler_unblock (active_item, active_item_activate_id); + } + +} + +static void +add_rotation_items_for_output (GsdXrandrManager *manager, MateOutputInfo *output) +{ + struct GsdXrandrManagerPrivate *priv = manager->priv; + int num_rotations; + MateRRRotation rotations; + + get_allowed_rotations_for_output (priv->configuration, priv->rw_screen, output, &num_rotations, &rotations); + + if (num_rotations == 1) + add_unsupported_rotation_item (manager); + else + add_items_for_rotations (manager, output, rotations); +} + +static void +add_menu_items_for_output (GsdXrandrManager *manager, MateOutputInfo *output) +{ + struct GsdXrandrManagerPrivate *priv = manager->priv; + GtkWidget *item; + + item = make_menu_item_for_output_title (manager, output); + gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), item); + + add_rotation_items_for_output (manager, output); +} + +static void +add_menu_items_for_outputs (GsdXrandrManager *manager) +{ + struct GsdXrandrManagerPrivate *priv = manager->priv; + int i; + + for (i = 0; priv->configuration->outputs[i] != NULL; i++) { + if (priv->configuration->outputs[i]->connected) + add_menu_items_for_output (manager, priv->configuration->outputs[i]); + } +} + +static void +status_icon_popup_menu (GsdXrandrManager *manager, guint button, guint32 timestamp) +{ + struct GsdXrandrManagerPrivate *priv = manager->priv; + GtkWidget *item; + + g_assert (priv->configuration == NULL); + priv->configuration = mate_rr_config_new_current (priv->rw_screen); + + g_assert (priv->labeler == NULL); + priv->labeler = mate_rr_labeler_new (priv->configuration); + + g_assert (priv->popup_menu == NULL); + priv->popup_menu = gtk_menu_new (); + + add_menu_items_for_outputs (manager); + + item = gtk_separator_menu_item_new (); + gtk_widget_show (item); + gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), item); + + item = gtk_menu_item_new_with_mnemonic (_("_Configure Display Settings…")); + g_signal_connect (item, "activate", + G_CALLBACK (popup_menu_configure_display_cb), manager); + gtk_widget_show (item); + gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), item); + + g_signal_connect (priv->popup_menu, "selection-done", + G_CALLBACK (status_icon_popup_menu_selection_done_cb), manager); + + gtk_menu_popup (GTK_MENU (priv->popup_menu), NULL, NULL, + gtk_status_icon_position_menu, + priv->status_icon, button, timestamp); +} + +static void +status_icon_activate_cb (GtkStatusIcon *status_icon, gpointer data) +{ + GsdXrandrManager *manager = GSD_XRANDR_MANAGER (data); + + /* Suck; we don't get a proper button/timestamp */ + status_icon_popup_menu (manager, 0, gtk_get_current_event_time ()); +} + +static void +status_icon_popup_menu_cb (GtkStatusIcon *status_icon, guint button, guint32 timestamp, gpointer data) +{ + GsdXrandrManager *manager = GSD_XRANDR_MANAGER (data); + + status_icon_popup_menu (manager, button, timestamp); +} + +static void +status_icon_start (GsdXrandrManager *manager) +{ + struct GsdXrandrManagerPrivate *priv = manager->priv; + + /* Ideally, we should detect if we are on a tablet and only display + * the icon in that case. + */ + if (!priv->status_icon) { + priv->status_icon = gtk_status_icon_new_from_icon_name (GSD_XRANDR_ICON_NAME); + gtk_status_icon_set_tooltip_text (priv->status_icon, _("Configure display settings")); + + g_signal_connect (priv->status_icon, "activate", + G_CALLBACK (status_icon_activate_cb), manager); + g_signal_connect (priv->status_icon, "popup-menu", + G_CALLBACK (status_icon_popup_menu_cb), manager); + } +} + +static void +status_icon_stop (GsdXrandrManager *manager) +{ + struct GsdXrandrManagerPrivate *priv = manager->priv; + + if (priv->status_icon) { + g_signal_handlers_disconnect_by_func ( + priv->status_icon, G_CALLBACK (status_icon_activate_cb), manager); + g_signal_handlers_disconnect_by_func ( + priv->status_icon, G_CALLBACK (status_icon_popup_menu_cb), manager); + + /* hide the icon before unreffing it; otherwise we will leak + whitespace in the notification area due to a bug in there */ + gtk_status_icon_set_visible (priv->status_icon, FALSE); + g_object_unref (priv->status_icon); + priv->status_icon = NULL; + } +} + +static void +start_or_stop_icon (GsdXrandrManager *manager) +{ + if (mateconf_client_get_bool (manager->priv->client, CONF_KEY_SHOW_NOTIFICATION_ICON, NULL)) { + status_icon_start (manager); + } + else { + status_icon_stop (manager); + } +} + +static void +on_config_changed (MateConfClient *client, + guint cnxn_id, + MateConfEntry *entry, + GsdXrandrManager *manager) +{ + if (strcmp (entry->key, CONF_KEY_SHOW_NOTIFICATION_ICON) == 0) + start_or_stop_icon (manager); +} + +static gboolean +apply_intended_configuration (GsdXrandrManager *manager, const char *intended_filename, guint32 timestamp) +{ + GError *my_error; + gboolean result; + + my_error = NULL; + result = apply_configuration_from_filename (manager, intended_filename, FALSE, timestamp, &my_error); + if (!result) { + if (my_error) { + if (!g_error_matches (my_error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) + error_message (manager, _("Could not apply the stored configuration for monitors"), my_error, NULL); + + g_error_free (my_error); + } + } + + return result; +} + +static void +apply_default_boot_configuration (GsdXrandrManager *mgr, guint32 timestamp) +{ + GsdXrandrManagerPrivate *priv = mgr->priv; + MateRRScreen *screen = priv->rw_screen; + MateRRConfig *config; + gboolean turn_on_external, turn_on_laptop; + + turn_on_external = + mateconf_client_get_bool (mgr->priv->client, CONF_KEY_TURN_ON_EXTERNAL_MONITORS_AT_STARTUP, NULL); + turn_on_laptop = + mateconf_client_get_bool (mgr->priv->client, CONF_KEY_TURN_ON_LAPTOP_MONITOR_AT_STARTUP, NULL); + + if (turn_on_external && turn_on_laptop) + config = make_clone_setup (screen); + else if (!turn_on_external && turn_on_laptop) + config = make_laptop_setup (screen); + else if (turn_on_external && !turn_on_laptop) + config = make_other_setup (screen); + else + config = make_laptop_setup (screen); + + if (config) { + apply_configuration_and_display_error (mgr, config, timestamp); + mate_rr_config_free (config); + } +} + +static gboolean +apply_stored_configuration_at_startup (GsdXrandrManager *manager, guint32 timestamp) +{ + GError *my_error; + gboolean success; + char *backup_filename; + char *intended_filename; + + backup_filename = mate_rr_config_get_backup_filename (); + intended_filename = mate_rr_config_get_intended_filename (); + + /* 1. See if there was a "saved" configuration. If there is one, it means + * that the user had selected to change the display configuration, but the + * machine crashed. In that case, we'll apply *that* configuration and save it on top of the + * "intended" one. + */ + + my_error = NULL; + + success = apply_configuration_from_filename (manager, backup_filename, FALSE, timestamp, &my_error); + if (success) { + /* The backup configuration existed, and could be applied + * successfully, so we must restore it on top of the + * failed/intended one. + */ + restore_backup_configuration (manager, backup_filename, intended_filename, timestamp); + goto out; + } + + if (!g_error_matches (my_error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) { + /* Epic fail: there (probably) was a backup configuration, but + * we could not apply it. The only thing we can do is delete + * the backup configuration. Let's hope that the user doesn't + * get left with an unusable display... + */ + + unlink (backup_filename); + goto out; + } + + /* 2. There was no backup configuration! This means we are + * good. Apply the intended configuration instead. + */ + + success = apply_intended_configuration (manager, intended_filename, timestamp); + +out: + + if (my_error) + g_error_free (my_error); + + g_free (backup_filename); + g_free (intended_filename); + + return success; +} + +static gboolean +apply_default_configuration_from_file (GsdXrandrManager *manager, guint32 timestamp) +{ + GsdXrandrManagerPrivate *priv = manager->priv; + char *default_config_filename; + gboolean result; + + default_config_filename = mateconf_client_get_string (priv->client, CONF_KEY_DEFAULT_CONFIGURATION_FILE, NULL); + if (!default_config_filename) + return FALSE; + + result = apply_configuration_from_filename (manager, default_config_filename, TRUE, timestamp, NULL); + + g_free (default_config_filename); + return result; +} + +gboolean +gsd_xrandr_manager_start (GsdXrandrManager *manager, + GError **error) +{ + g_debug ("Starting xrandr manager"); + mate_settings_profile_start (NULL); + + log_open (); + log_msg ("------------------------------------------------------------\nSTARTING XRANDR PLUGIN\n"); + + manager->priv->rw_screen = mate_rr_screen_new ( + gdk_screen_get_default (), on_randr_event, manager, error); + + if (manager->priv->rw_screen == NULL) { + log_msg ("Could not initialize the RANDR plugin%s%s\n", + (error && *error) ? ": " : "", + (error && *error) ? (*error)->message : ""); + log_close (); + return FALSE; + } + + log_msg ("State of screen at startup:\n"); + log_screen (manager->priv->rw_screen); + + manager->priv->running = TRUE; + manager->priv->client = mateconf_client_get_default (); + + g_assert (manager->priv->notify_id == 0); + + mateconf_client_add_dir (manager->priv->client, CONF_DIR, + MATECONF_CLIENT_PRELOAD_ONELEVEL, + NULL); + + manager->priv->notify_id = + mateconf_client_notify_add ( + manager->priv->client, CONF_DIR, + (MateConfClientNotifyFunc)on_config_changed, + manager, NULL, NULL); + + if (manager->priv->switch_video_mode_keycode) { + gdk_error_trap_push (); + + XGrabKey (gdk_x11_get_default_xdisplay(), + manager->priv->switch_video_mode_keycode, AnyModifier, + gdk_x11_get_default_root_xwindow(), + True, GrabModeAsync, GrabModeAsync); + + gdk_flush (); + gdk_error_trap_pop (); + } + + if (manager->priv->rotate_windows_keycode) { + gdk_error_trap_push (); + + XGrabKey (gdk_x11_get_default_xdisplay(), + manager->priv->rotate_windows_keycode, AnyModifier, + gdk_x11_get_default_root_xwindow(), + True, GrabModeAsync, GrabModeAsync); + + gdk_flush (); + gdk_error_trap_pop (); + } + + show_timestamps_dialog (manager, "Startup"); + if (!apply_stored_configuration_at_startup (manager, GDK_CURRENT_TIME)) /* we don't have a real timestamp at startup anyway */ + if (!apply_default_configuration_from_file (manager, GDK_CURRENT_TIME)) + apply_default_boot_configuration (manager, GDK_CURRENT_TIME); + + log_msg ("State of screen after initial configuration:\n"); + log_screen (manager->priv->rw_screen); + + gdk_window_add_filter (gdk_get_default_root_window(), + (GdkFilterFunc)event_filter, + manager); + + start_or_stop_icon (manager); + + log_close (); + + mate_settings_profile_end (NULL); + + return TRUE; +} + +void +gsd_xrandr_manager_stop (GsdXrandrManager *manager) +{ + g_debug ("Stopping xrandr manager"); + + manager->priv->running = FALSE; + + if (manager->priv->switch_video_mode_keycode) { + gdk_error_trap_push (); + + XUngrabKey (gdk_x11_get_default_xdisplay(), + manager->priv->switch_video_mode_keycode, AnyModifier, + gdk_x11_get_default_root_xwindow()); + + gdk_error_trap_pop (); + } + + if (manager->priv->rotate_windows_keycode) { + gdk_error_trap_push (); + + XUngrabKey (gdk_x11_get_default_xdisplay(), + manager->priv->rotate_windows_keycode, AnyModifier, + gdk_x11_get_default_root_xwindow()); + + gdk_error_trap_pop (); + } + + gdk_window_remove_filter (gdk_get_default_root_window (), + (GdkFilterFunc) event_filter, + manager); + + if (manager->priv->notify_id != 0) { + mateconf_client_remove_dir (manager->priv->client, + CONF_DIR, NULL); + mateconf_client_notify_remove (manager->priv->client, + manager->priv->notify_id); + manager->priv->notify_id = 0; + } + + if (manager->priv->client != NULL) { + g_object_unref (manager->priv->client); + manager->priv->client = NULL; + } + + if (manager->priv->rw_screen != NULL) { + mate_rr_screen_destroy (manager->priv->rw_screen); + manager->priv->rw_screen = NULL; + } + + if (manager->priv->dbus_connection != NULL) { + dbus_g_connection_unref (manager->priv->dbus_connection); + manager->priv->dbus_connection = NULL; + } + + status_icon_stop (manager); + + log_open (); + log_msg ("STOPPING XRANDR PLUGIN\n------------------------------------------------------------\n"); + log_close (); +} + +static void +gsd_xrandr_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GsdXrandrManager *self; + + self = GSD_XRANDR_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gsd_xrandr_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GsdXrandrManager *self; + + self = GSD_XRANDR_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +gsd_xrandr_manager_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GsdXrandrManager *xrandr_manager; + GsdXrandrManagerClass *klass; + + klass = GSD_XRANDR_MANAGER_CLASS (g_type_class_peek (GSD_TYPE_XRANDR_MANAGER)); + + xrandr_manager = GSD_XRANDR_MANAGER (G_OBJECT_CLASS (gsd_xrandr_manager_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + + return G_OBJECT (xrandr_manager); +} + +static void +gsd_xrandr_manager_dispose (GObject *object) +{ + GsdXrandrManager *xrandr_manager; + + xrandr_manager = GSD_XRANDR_MANAGER (object); + + G_OBJECT_CLASS (gsd_xrandr_manager_parent_class)->dispose (object); +} + +static void +gsd_xrandr_manager_class_init (GsdXrandrManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gsd_xrandr_manager_get_property; + object_class->set_property = gsd_xrandr_manager_set_property; + object_class->constructor = gsd_xrandr_manager_constructor; + object_class->dispose = gsd_xrandr_manager_dispose; + object_class->finalize = gsd_xrandr_manager_finalize; + + dbus_g_object_type_install_info (GSD_TYPE_XRANDR_MANAGER, &dbus_glib_gsd_xrandr_manager_object_info); + + g_type_class_add_private (klass, sizeof (GsdXrandrManagerPrivate)); +} + +static guint +get_keycode_for_keysym_name (const char *name) +{ + Display *dpy; + guint keyval; + + dpy = gdk_x11_get_default_xdisplay (); + + keyval = gdk_keyval_from_name (name); + return XKeysymToKeycode (dpy, keyval); +} + +static void +gsd_xrandr_manager_init (GsdXrandrManager *manager) +{ + manager->priv = GSD_XRANDR_MANAGER_GET_PRIVATE (manager); + + manager->priv->switch_video_mode_keycode = get_keycode_for_keysym_name (VIDEO_KEYSYM); + manager->priv->rotate_windows_keycode = get_keycode_for_keysym_name (ROTATE_KEYSYM); + + manager->priv->current_fn_f7_config = -1; + manager->priv->fn_f7_configs = NULL; +} + +static void +gsd_xrandr_manager_finalize (GObject *object) +{ + GsdXrandrManager *xrandr_manager; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_XRANDR_MANAGER (object)); + + xrandr_manager = GSD_XRANDR_MANAGER (object); + + g_return_if_fail (xrandr_manager->priv != NULL); + + G_OBJECT_CLASS (gsd_xrandr_manager_parent_class)->finalize (object); +} + +static gboolean +register_manager_dbus (GsdXrandrManager *manager) +{ + GError *error = NULL; + + manager->priv->dbus_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + if (manager->priv->dbus_connection == NULL) { + if (error != NULL) { + g_warning ("Error getting session bus: %s", error->message); + g_error_free (error); + } + return FALSE; + } + + /* Hmm, should we do this in gsd_xrandr_manager_start()? */ + dbus_g_connection_register_g_object (manager->priv->dbus_connection, GSD_XRANDR_DBUS_PATH, G_OBJECT (manager)); + + return TRUE; +} + +GsdXrandrManager * +gsd_xrandr_manager_new (void) +{ + if (manager_object != NULL) { + g_object_ref (manager_object); + } else { + manager_object = g_object_new (GSD_TYPE_XRANDR_MANAGER, NULL); + g_object_add_weak_pointer (manager_object, + (gpointer *) &manager_object); + + if (!register_manager_dbus (manager_object)) { + g_object_unref (manager_object); + return NULL; + } + } + + return GSD_XRANDR_MANAGER (manager_object); +} diff --git a/plugins/xrandr/gsd-xrandr-manager.h b/plugins/xrandr/gsd-xrandr-manager.h new file mode 100644 index 0000000..c404bfe --- /dev/null +++ b/plugins/xrandr/gsd-xrandr-manager.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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_XRANDR_MANAGER_H +#define __GSD_XRANDR_MANAGER_H + +#include <glib-object.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_XRANDR_MANAGER (gsd_xrandr_manager_get_type ()) +#define GSD_XRANDR_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_XRANDR_MANAGER, GsdXrandrManager)) +#define GSD_XRANDR_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_XRANDR_MANAGER, GsdXrandrManagerClass)) +#define GSD_IS_XRANDR_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_XRANDR_MANAGER)) +#define GSD_IS_XRANDR_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_XRANDR_MANAGER)) +#define GSD_XRANDR_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_XRANDR_MANAGER, GsdXrandrManagerClass)) + +typedef struct GsdXrandrManagerPrivate GsdXrandrManagerPrivate; + +typedef struct +{ + GObject parent; + GsdXrandrManagerPrivate *priv; +} GsdXrandrManager; + +typedef struct +{ + GObjectClass parent_class; +} GsdXrandrManagerClass; + +GType gsd_xrandr_manager_get_type (void); + +GsdXrandrManager * gsd_xrandr_manager_new (void); +gboolean gsd_xrandr_manager_start (GsdXrandrManager *manager, + GError **error); +void gsd_xrandr_manager_stop (GsdXrandrManager *manager); + +#ifdef __cplusplus +} +#endif + +#endif /* __GSD_XRANDR_MANAGER_H */ diff --git a/plugins/xrandr/gsd-xrandr-manager.xml b/plugins/xrandr/gsd-xrandr-manager.xml new file mode 100644 index 0000000..e8dde7c --- /dev/null +++ b/plugins/xrandr/gsd-xrandr-manager.xml @@ -0,0 +1,23 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node> + <interface name="org.mate.SettingsDaemon.XRANDR"> + <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="gsd_xrandr_manager"/> + <method name="ApplyConfiguration"> + <!-- This method is implemented, but deprecated in favor of the + same method in the XRANDR-2 interface defined below. --> + </method> + </interface> + + <interface name="org.mate.SettingsDaemon.XRANDR_2"> + <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="gsd_xrandr_manager_2"/> + <method name="ApplyConfiguration"> + <!-- transient-parent window for the confirmation dialog; use 0 + for no parent --> + <arg name="parent_window_id" type="x" direction="in"/> + + <!-- Timestamp used to present the confirmation dialog and (in + the future) for the RANDR calls themselves --> + <arg name="timestamp" type="x" direction="in"/> + </method> + </interface> +</node> diff --git a/plugins/xrandr/gsd-xrandr-plugin.c b/plugins/xrandr/gsd-xrandr-plugin.c new file mode 100644 index 0000000..e765124 --- /dev/null +++ b/plugins/xrandr/gsd-xrandr-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 <[email protected]> + * + * 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 <glib/gi18n-lib.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" +#include "gsd-xrandr-plugin.h" +#include "gsd-xrandr-manager.h" + +struct GsdXrandrPluginPrivate { + GsdXrandrManager *manager; +}; + +#define GSD_XRANDR_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSD_TYPE_XRANDR_PLUGIN, GsdXrandrPluginPrivate)) + +MATE_SETTINGS_PLUGIN_REGISTER (GsdXrandrPlugin, gsd_xrandr_plugin) + +static void +gsd_xrandr_plugin_init (GsdXrandrPlugin *plugin) +{ + plugin->priv = GSD_XRANDR_PLUGIN_GET_PRIVATE (plugin); + + g_debug ("GsdXrandrPlugin initializing"); + + plugin->priv->manager = gsd_xrandr_manager_new (); +} + +static void +gsd_xrandr_plugin_finalize (GObject *object) +{ + GsdXrandrPlugin *plugin; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_XRANDR_PLUGIN (object)); + + g_debug ("GsdXrandrPlugin finalizing"); + + plugin = GSD_XRANDR_PLUGIN (object); + + g_return_if_fail (plugin->priv != NULL); + + if (plugin->priv->manager != NULL) { + g_object_unref (plugin->priv->manager); + } + + G_OBJECT_CLASS (gsd_xrandr_plugin_parent_class)->finalize (object); +} + +static void +impl_activate (MateSettingsPlugin *plugin) +{ + gboolean res; + GError *error; + + g_debug ("Activating xrandr plugin"); + + error = NULL; + res = gsd_xrandr_manager_start (GSD_XRANDR_PLUGIN (plugin)->priv->manager, &error); + if (! res) { + g_warning ("Unable to start xrandr manager: %s", error->message); + g_error_free (error); + } +} + +static void +impl_deactivate (MateSettingsPlugin *plugin) +{ + g_debug ("Deactivating xrandr plugin"); + gsd_xrandr_manager_stop (GSD_XRANDR_PLUGIN (plugin)->priv->manager); +} + +static void +gsd_xrandr_plugin_class_init (GsdXrandrPluginClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MateSettingsPluginClass *plugin_class = MATE_SETTINGS_PLUGIN_CLASS (klass); + + object_class->finalize = gsd_xrandr_plugin_finalize; + + plugin_class->activate = impl_activate; + plugin_class->deactivate = impl_deactivate; + + g_type_class_add_private (klass, sizeof (GsdXrandrPluginPrivate)); +} diff --git a/plugins/xrandr/gsd-xrandr-plugin.h b/plugins/xrandr/gsd-xrandr-plugin.h new file mode 100644 index 0000000..18bb79a --- /dev/null +++ b/plugins/xrandr/gsd-xrandr-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 <[email protected]> + * + * 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_XRANDR_PLUGIN_H__ +#define __GSD_XRANDR_PLUGIN_H__ + +#include <glib.h> +#include <glib-object.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_XRANDR_PLUGIN (gsd_xrandr_plugin_get_type ()) +#define GSD_XRANDR_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_XRANDR_PLUGIN, GsdXrandrPlugin)) +#define GSD_XRANDR_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_XRANDR_PLUGIN, GsdXrandrPluginClass)) +#define GSD_IS_XRANDR_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_XRANDR_PLUGIN)) +#define GSD_IS_XRANDR_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_XRANDR_PLUGIN)) +#define GSD_XRANDR_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_XRANDR_PLUGIN, GsdXrandrPluginClass)) + +typedef struct GsdXrandrPluginPrivate GsdXrandrPluginPrivate; + +typedef struct +{ + MateSettingsPlugin parent; + GsdXrandrPluginPrivate *priv; +} GsdXrandrPlugin; + +typedef struct +{ + MateSettingsPluginClass parent_class; +} GsdXrandrPluginClass; + +GType gsd_xrandr_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_XRANDR_PLUGIN_H__ */ diff --git a/plugins/xrandr/gsd-xrandr.svg b/plugins/xrandr/gsd-xrandr.svg new file mode 100644 index 0000000..0679b6b --- /dev/null +++ b/plugins/xrandr/gsd-xrandr.svg @@ -0,0 +1,470 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="48.000000px" + height="48.000000px" + id="svg3304" + sodipodi:version="0.32" + inkscape:version="0.44+devel" + sodipodi:docbase="/home/jimmac/gfx/ximian/art/icons/control-center/scalable" + sodipodi:docname="change-resolution.svg" + inkscape:output_extension="org.inkscape.output.svg.inkscape" + sodipodi:modified="true"> + <defs + id="defs3306"> + <linearGradient + id="linearGradient2804"> + <stop + style="stop-color:black;stop-opacity:0;" + offset="0" + id="stop2806" /> + <stop + id="stop2812" + offset="0.5" + style="stop-color:black;stop-opacity:1;" /> + <stop + style="stop-color:black;stop-opacity:0;" + offset="1" + id="stop2808" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2804" + id="linearGradient2831" + gradientUnits="userSpaceOnUse" + x1="21.875" + y1="48.000977" + x2="21.875" + y2="40" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient2781" + id="radialGradient2829" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2,0,0,0.8,36,8.8)" + cx="1" + cy="44" + fx="1" + fy="44" + r="5" /> + <linearGradient + inkscape:collect="always" + id="linearGradient2781"> + <stop + style="stop-color:black;stop-opacity:1;" + offset="0" + id="stop2783" /> + <stop + style="stop-color:black;stop-opacity:0;" + offset="1" + id="stop2785" /> + </linearGradient> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient2781" + id="radialGradient2827" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(2,0,0,0.8,-13,-79.2)" + cx="1" + cy="44" + fx="1" + fy="44" + r="5" /> + <linearGradient + id="linearGradient5137"> + <stop + style="stop-color:#eeeeec;stop-opacity:1;" + offset="0" + id="stop5139" /> + <stop + style="stop-color:#e6e6e3;stop-opacity:1;" + offset="1" + id="stop5141" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + id="linearGradient6240"> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="0" + id="stop6242" /> + <stop + style="stop-color:#ffffff;stop-opacity:0;" + offset="1" + id="stop6244" /> + </linearGradient> + <linearGradient + id="linearGradient11400"> + <stop + style="stop-color:#000000;stop-opacity:1;" + offset="0" + id="stop11402" /> + <stop + style="stop-color:#000000;stop-opacity:0;" + offset="1" + id="stop11404" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient11400" + id="linearGradient11406" + x1="23.154902" + y1="34.572548" + x2="23.529411" + y2="40.219608" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(0,0.7954955)" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient5137" + id="linearGradient5147" + gradientUnits="userSpaceOnUse" + x1="17.247635" + y1="6.3760414" + x2="39.904388" + y2="38.876041" + gradientTransform="translate(0,0.7954955)" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient5137" + id="linearGradient5223" + gradientUnits="userSpaceOnUse" + x1="31.743324" + y1="37.842293" + x2="31.86105" + y2="43.82579" + gradientTransform="translate(0,0.7954955)" /> + <linearGradient + id="linearGradient7025" + inkscape:collect="always"> + <stop + id="stop7027" + offset="0" + style="stop-color:#e6ce46;stop-opacity:1" /> + <stop + id="stop7029" + offset="1" + style="stop-color:#d6ba1c;stop-opacity:1" /> + </linearGradient> + <linearGradient + id="linearGradient22122" + inkscape:collect="always"> + <stop + id="stop22124" + offset="0" + style="stop-color:black;stop-opacity:1;" /> + <stop + id="stop22126" + offset="1" + style="stop-color:black;stop-opacity:0;" /> + </linearGradient> + <linearGradient + id="linearGradient22140"> + <stop + id="stop22142" + offset="0" + style="stop-color:black;stop-opacity:0;" /> + <stop + style="stop-color:black;stop-opacity:1;" + offset="0.5" + id="stop22148" /> + <stop + id="stop22144" + offset="1" + style="stop-color:black;stop-opacity:0;" /> + </linearGradient> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient22122" + id="radialGradient4770" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0,-1.000001,1.142856,0,-41.10259,45.50001)" + cx="7" + cy="39.464806" + fx="7" + fy="39.464806" + r="3.5" /> + <radialGradient + inkscape:collect="always" + xlink:href="#linearGradient22122" + id="radialGradient4772" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0,-1.000001,1.142856,0,-89.10259,-31.49999)" + cx="7" + cy="39.464806" + fx="7" + fy="39.464806" + r="3.5" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient22140" + id="linearGradient4774" + gradientUnits="userSpaceOnUse" + x1="18.142136" + y1="35" + x2="18.142136" + y2="42.040661" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient7025" + id="linearGradient4776" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(53,1.428571)" + x1="13.630114" + y1="28.5" + x2="25.208096" + y2="41.180992" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient6240" + id="linearGradient4778" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(7.843e-3,0.7954955)" + x1="20.156862" + y1="5.0996137" + x2="20.156862" + y2="26.039215" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#849193" + borderopacity="1.0000000" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1" + inkscape:cx="39.697787" + inkscape:cy="26.598514" + inkscape:current-layer="layer1" + showgrid="false" + inkscape:grid-bbox="true" + inkscape:document-units="px" + inkscape:showpageshadow="false" + showborder="true" + inkscape:window-width="923" + inkscape:window-height="937" + inkscape:window-x="2004" + inkscape:window-y="169" + showguides="true" + inkscape:guide-bbox="true" + inkscape:grid-points="true" /> + <metadata + id="metadata3309"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title>Change Resolution</dc:title> + <dc:creator> + <cc:Agent> + <dc:title>Jakub Steiner</dc:title> + </cc:Agent> + </dc:creator> + <cc:license + rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" /> + <dc:subject> + <rdf:Bag> + <rdf:li>display</rdf:li> + <rdf:li>resolution</rdf:li> + <rdf:li>video</rdf:li> + </rdf:Bag> + </dc:subject> + <dc:contributor> + <cc:Agent> + <dc:title>Andreas Nilsson +Luca Ferretti <[email protected]></dc:title> + </cc:Agent> + </dc:contributor> + <dc:date></dc:date> + <dc:source>http://www.gnome.org</dc:source> + </cc:Work> + <cc:License + rdf:about="http://creativecommons.org/licenses/GPL/2.0/"> + <cc:permits + rdf:resource="http://web.resource.org/cc/Reproduction" /> + <cc:permits + rdf:resource="http://web.resource.org/cc/Distribution" /> + <cc:requires + rdf:resource="http://web.resource.org/cc/Notice" /> + <cc:permits + rdf:resource="http://web.resource.org/cc/DerivativeWorks" /> + <cc:requires + rdf:resource="http://web.resource.org/cc/ShareAlike" /> + <cc:requires + rdf:resource="http://web.resource.org/cc/SourceCode" /> + </cc:License> + </rdf:RDF> + </metadata> + <g + id="layer1" + inkscape:label="Layer 1" + inkscape:groupmode="layer"> + <g + id="g2822" + style="opacity:0.3" + transform="matrix(0.9308511,0,0,1.037397,1.6941489,-1.795056)"> + <rect + transform="scale(-1,-1)" + y="-48" + x="-11" + height="8" + width="10" + id="rect1892" + style="opacity:1;color:#000000;fill:url(#radialGradient2827);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" /> + <rect + y="40" + x="38" + height="8" + width="10" + id="rect2789" + style="opacity:1;color:#000000;fill:url(#radialGradient2829);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" /> + <rect + y="40" + x="11" + height="8" + width="27" + id="rect2793" + style="opacity:1;color:#000000;fill:url(#linearGradient2831);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" /> + </g> + <rect + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="rect4784" + width="48" + height="48" + x="0" + y="0.79549509" /> + <path + style="opacity:1;color:#000000;fill:url(#linearGradient5223);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" + d="M 14.375479,36.328843 C 14.375479,36.328843 15.592355,41.263443 10.51915,41.309767 C 8.0888743,41.331672 8.5866723,45.344918 8.5866723,45.344918 L 39.433139,45.313545 C 39.433139,45.313545 39.851577,41.418182 37.410922,41.372513 C 32.423455,41.280374 33.600393,36.266098 33.600393,36.266098 L 14.375479,36.328843 z " + id="path9222" + sodipodi:nodetypes="csccscc" /> + <path + style="fill:url(#linearGradient5147);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1" + d="M 4.8886262,4.2739318 L 43.01746,4.2739318 C 45.042579,4.2739318 46.518438,5.7015863 46.518438,7.9000726 L 46.529388,34.103908 C 46.529388,35.795975 46.001041,36.319137 44.494732,36.319137 L 3.5320635,36.300202 C 2.3527922,36.271409 1.513468,35.805541 1.4976345,34.280899 L 1.5128113,7.7123281 C 1.5128113,5.9385022 3.0522187,4.2739318 4.8886262,4.2739318 z " + id="rect5040" + sodipodi:nodetypes="ccccccccc" /> + <rect + style="fill:#555753;fill-opacity:1;fill-rule:evenodd;stroke:#2e3436;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + id="rect9208" + width="37.00032" + height="22.996691" + x="5.5059438" + y="8.2973185" /> + <path + sodipodi:type="inkscape:offset" + inkscape:radius="-0.875" + inkscape:original="M 4.875 4.28125 C 3.0385925 4.28125 1.5 5.9449242 1.5 7.71875 L 1.5 34.28125 C 1.5158335 35.805892 2.3519787 36.283708 3.53125 36.3125 L 44.5 36.3125 C 46.006309 36.3125 46.53125 35.785816 46.53125 34.09375 L 46.53125 7.90625 C 46.53125 5.7077637 45.056369 4.2812498 43.03125 4.28125 L 4.875 4.28125 z " + xlink:href="#rect5040" + style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1" + id="path5145" + inkscape:href="#rect5040" + d="M 4.875,5.0625 C 3.5670573,5.0625 2.375,6.3571498 2.375,7.625 L 2.375,34.1875 C 2.3812657,34.79084 2.515801,34.970853 2.65625,35.09375 C 2.796699,35.216647 3.0858905,35.332113 3.5625,35.34375 L 44.5,35.34375 C 45.151173,35.34375 45.356981,35.24273 45.4375,35.15625 C 45.518019,35.06977 45.65625,34.755549 45.65625,34 L 45.65625,7.8125 C 45.65625,6.0053499 44.645463,5.0624999 43.03125,5.0625 L 4.875,5.0625 z " /> + <path + style="opacity:0.6;fill:url(#linearGradient11406);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 13.992156,36.834708 C 14.075817,39.007257 13.708803,39.746151 12.358532,40.509939 L 35.973934,41.807257 C 35.024915,40.638629 33.644523,38.873923 34.020993,36.819022 L 13.992156,36.834708 z " + id="path10672" + sodipodi:nodetypes="ccccc" /> + <path + style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#8d8d8f;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.43902438" + d="M 9.9921262,42.291555 C 16.698819,42.293524 37.78891,42.291555 37.78891,42.291555" + id="path6575" + sodipodi:nodetypes="cc" /> + <path + sodipodi:nodetypes="cc" + id="path8029" + d="M 9.647928,43.299429 C 16.354621,43.301398 38.367789,43.299429 38.367789,43.299429" + style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /> + <path + style="opacity:0.4;fill:url(#linearGradient4778);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 6.031372,8.8268676 L 6.031372,26.834708 C 22.475817,25.480459 28.630065,16.722289 41.999999,15.807256 L 42,8.7954956 L 6.031372,8.8268676 z " + id="path4073" + sodipodi:nodetypes="ccccc" /> + <g + id="g4754" + transform="translate(-46.77135,-7.3370294)"> + <g + transform="matrix(0.916667,0,0,0.714282,49.771334,11.132681)" + style="opacity:0.3" + id="g22150"> + <rect + style="opacity:1;fill:url(#radialGradient4770);fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1" + id="rect22120" + width="4" + height="7" + x="0" + y="35" /> + <rect + style="opacity:1;fill:url(#radialGradient4772);fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1" + id="rect22134" + width="4" + height="7" + x="-48" + y="-42" + transform="scale(-1,-1)" /> + <rect + style="opacity:1;fill:url(#linearGradient4774);fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:1.20000057;stroke-opacity:1" + id="rect22138" + width="40" + height="7" + x="4" + y="35" /> + </g> + <g + id="g4743"> + <g + id="g10824" + transform="translate(-5.228666,-6.29601)"> + <path + id="path4319" + d="M 57.5,14.928571 L 57.5,44.928571 L 96.5,44.928571 L 57.5,14.928571 z M 63.5,27.928571 L 78.5,38.928571 L 63.5,38.928571 L 63.5,27.928571 z " + style="fill:url(#linearGradient4776);fill-opacity:1;fill-rule:evenodd;stroke:#a38503;stroke-width:1.00000024px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + <path + sodipodi:nodetypes="cc" + id="path4326" + d="M 61.5,44.928571 L 61.5,41.928571" + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a38503;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /> + <path + sodipodi:nodetypes="cc" + id="path4328" + d="M 67.5,44.928571 L 67.5,41.928571" + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a38503;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /> + <path + sodipodi:nodetypes="cc" + id="path4330" + d="M 73.5,44.928571 L 73.5,41.964285" + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a38503;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /> + <path + sodipodi:nodetypes="cc" + id="path4332" + d="M 79.5,44.928571 L 79.5,41.928571" + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a38503;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /> + <path + sodipodi:nodetypes="cc" + id="path4334" + d="M 85.5,44.928571 L 85.5,41.928571" + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#a38503;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /> + <path + id="path6126" + d="M 58.500002,16.928575 L 58.500002,43.928586 L 93.500014,43.928586 L 58.500002,16.928575 z " + style="opacity:0.4;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.0000006px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + </g> + <path + style="opacity:0.4;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 9.5017474,38.542446 L 9.4575532,24.532894 L 28.541592,38.563262 L 9.5017474,38.542446 z " + id="path12221" + sodipodi:nodetypes="cccc" + transform="translate(47.771334,-4.867439)" /> + </g> + </g> + </g> +</svg> diff --git a/plugins/xrandr/xrandr.mate-settings-plugin.in b/plugins/xrandr/xrandr.mate-settings-plugin.in new file mode 100644 index 0000000..a07305c --- /dev/null +++ b/plugins/xrandr/xrandr.mate-settings-plugin.in @@ -0,0 +1,8 @@ +[MATE Settings Plugin] +Module=xrandr +IAge=0 +_Name=XRandR +_Description=Set up screen size and rotation settings +Authors=Various +Copyright=Copyright © 2007 Novell +Website= diff --git a/plugins/xrdb/Makefile.am b/plugins/xrdb/Makefile.am new file mode 100644 index 0000000..1b8e82b --- /dev/null +++ b/plugins/xrdb/Makefile.am @@ -0,0 +1,54 @@ +NULL = + +SUBDIRS = \ + data \ + $(NULL) + +plugin_LTLIBRARIES = \ + libxrdb.la \ + $(NULL) + +libxrdb_la_SOURCES = \ + gsd-xrdb-plugin.h \ + gsd-xrdb-plugin.c \ + gsd-xrdb-manager.h \ + gsd-xrdb-manager.c \ + $(NULL) + +libxrdb_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DDATADIR=\""$(pkgdatadir)"\" \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libxrdb_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libxrdb_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) \ + $(NULL) + +libxrdb_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(NULL) + +plugin_in_files = \ + xrdb.mate-settings-plugin.in \ + $(NULL) + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) + +EXTRA_DIST = \ + $(plugin_in_files) \ + $(NULL) + +CLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +DISTCLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +@GSD_INTLTOOL_PLUGIN_RULE@ diff --git a/plugins/xrdb/Makefile.in b/plugins/xrdb/Makefile.in new file mode 100644 index 0000000..56338b6 --- /dev/null +++ b/plugins/xrdb/Makefile.in @@ -0,0 +1,834 @@ +# 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/xrdb +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)$(plugindir)" +LTLIBRARIES = $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +libxrdb_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am__objects_1 = +am_libxrdb_la_OBJECTS = libxrdb_la-gsd-xrdb-plugin.lo \ + libxrdb_la-gsd-xrdb-manager.lo $(am__objects_1) +libxrdb_la_OBJECTS = $(am_libxrdb_la_OBJECTS) +libxrdb_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libxrdb_la_CFLAGS) \ + $(CFLAGS) $(libxrdb_la_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 = $(libxrdb_la_SOURCES) +DIST_SOURCES = $(libxrdb_la_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 = $(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 +DIST_SUBDIRS = $(SUBDIRS) +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@ +NULL = +SUBDIRS = \ + data \ + $(NULL) + +plugin_LTLIBRARIES = \ + libxrdb.la \ + $(NULL) + +libxrdb_la_SOURCES = \ + gsd-xrdb-plugin.h \ + gsd-xrdb-plugin.c \ + gsd-xrdb-manager.h \ + gsd-xrdb-manager.c \ + $(NULL) + +libxrdb_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DDATADIR=\""$(pkgdatadir)"\" \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libxrdb_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libxrdb_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) \ + $(NULL) + +libxrdb_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(NULL) + +plugin_in_files = \ + xrdb.mate-settings-plugin.in \ + $(NULL) + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) +EXTRA_DIST = \ + $(plugin_in_files) \ + $(NULL) + +CLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +DISTCLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +all: 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/xrdb/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plugins/xrdb/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 +libxrdb.la: $(libxrdb_la_OBJECTS) $(libxrdb_la_DEPENDENCIES) + $(libxrdb_la_LINK) -rpath $(plugindir) $(libxrdb_la_OBJECTS) $(libxrdb_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxrdb_la-gsd-xrdb-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxrdb_la-gsd-xrdb-plugin.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 $@ $< + +libxrdb_la-gsd-xrdb-plugin.lo: gsd-xrdb-plugin.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxrdb_la_CPPFLAGS) $(CPPFLAGS) $(libxrdb_la_CFLAGS) $(CFLAGS) -MT libxrdb_la-gsd-xrdb-plugin.lo -MD -MP -MF $(DEPDIR)/libxrdb_la-gsd-xrdb-plugin.Tpo -c -o libxrdb_la-gsd-xrdb-plugin.lo `test -f 'gsd-xrdb-plugin.c' || echo '$(srcdir)/'`gsd-xrdb-plugin.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxrdb_la-gsd-xrdb-plugin.Tpo $(DEPDIR)/libxrdb_la-gsd-xrdb-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-xrdb-plugin.c' object='libxrdb_la-gsd-xrdb-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) $(libxrdb_la_CPPFLAGS) $(CPPFLAGS) $(libxrdb_la_CFLAGS) $(CFLAGS) -c -o libxrdb_la-gsd-xrdb-plugin.lo `test -f 'gsd-xrdb-plugin.c' || echo '$(srcdir)/'`gsd-xrdb-plugin.c + +libxrdb_la-gsd-xrdb-manager.lo: gsd-xrdb-manager.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxrdb_la_CPPFLAGS) $(CPPFLAGS) $(libxrdb_la_CFLAGS) $(CFLAGS) -MT libxrdb_la-gsd-xrdb-manager.lo -MD -MP -MF $(DEPDIR)/libxrdb_la-gsd-xrdb-manager.Tpo -c -o libxrdb_la-gsd-xrdb-manager.lo `test -f 'gsd-xrdb-manager.c' || echo '$(srcdir)/'`gsd-xrdb-manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxrdb_la-gsd-xrdb-manager.Tpo $(DEPDIR)/libxrdb_la-gsd-xrdb-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-xrdb-manager.c' object='libxrdb_la-gsd-xrdb-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) $(libxrdb_la_CPPFLAGS) $(CPPFLAGS) $(libxrdb_la_CFLAGS) $(CFLAGS) -c -o libxrdb_la-gsd-xrdb-manager.lo `test -f 'gsd-xrdb-manager.c' || echo '$(srcdir)/'`gsd-xrdb-manager.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +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: check-recursive +all-am: Makefile $(LTLIBRARIES) $(DATA) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: 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." +clean: clean-recursive + +clean-am: clean-generic clean-libtool 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-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-pluginDATA uninstall-pluginLTLIBRARIES + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + 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-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-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-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-pluginDATA \ + uninstall-pluginLTLIBRARIES + + +@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/xrdb/data/Editres.ad b/plugins/xrdb/data/Editres.ad new file mode 100644 index 0000000..d33d499 --- /dev/null +++ b/plugins/xrdb/data/Editres.ad @@ -0,0 +1,5 @@ +Editres*Tree.Background: WINDOW_BACKGROUND +Editres*Tree.Foreground: WINDOW_FOREGROUND +Editres*Tree.Toggle.Foreground: FOREGROUND +Editres*Tree.Toggle.Background: BACKGROUND +Editres*Panner.Background: BACKGROUND diff --git a/plugins/xrdb/data/Emacs.ad b/plugins/xrdb/data/Emacs.ad new file mode 100644 index 0000000..d40be72 --- /dev/null +++ b/plugins/xrdb/data/Emacs.ad @@ -0,0 +1,21 @@ +Emacs.default.attributeForeground: WINDOW_FOREGROUND +Emacs.default.attributeBackground: WINDOW_BACKGROUND + +Emacs*Foreground: WINDOW_FOREGROUND +Emacs*Background: WINDOW_BACKGROUND +Emacs*menubar*foreground: FOREGROUND +Emacs*menubar*background: BACKGROUND +Emacs*popup*Foreground: FOREGROUND +Emacs*popup*Background: BACKGROUND +Emacs*Dialog*foreground: FOREGROUND +Emacs*Dialog*background: BACKGROUND +Emacs*XlwScrollBar.Foreground: FOREGROUND +Emacs*XlwScrollBar.Background: BACKGROUND +Emacs*topToolBarShadowColor: BACKGROUND +Emacs*bottomToolBarShadowColor: BACKGROUND +Emacs*backgroundToolBarColor: BACKGROUND +Emacs.scroll-bar.attributeBackground: BACKGROUND +Emacs.scroll-bar.attributeForeground: FOREGROUND +Emacs.mode-line.attributeForeground: FOREGROUND +Emacs.tool-bar.attributeBackground: BACKGROUND +Emacs.tool-bar.attributeForeground: FOREGROUND diff --git a/plugins/xrdb/data/General.ad b/plugins/xrdb/data/General.ad new file mode 100644 index 0000000..d398d41 --- /dev/null +++ b/plugins/xrdb/data/General.ad @@ -0,0 +1,2 @@ +*background: BACKGROUND +*foreground: FOREGROUND diff --git a/plugins/xrdb/data/Makefile.am b/plugins/xrdb/data/Makefile.am new file mode 100644 index 0000000..e133b9b --- /dev/null +++ b/plugins/xrdb/data/Makefile.am @@ -0,0 +1,15 @@ +NULL = + +xrdbdir = $(pkgdatadir)/xrdb +xrdb_DATA = \ + General.ad \ + Editres.ad \ + Emacs.ad \ + Motif.ad \ + Tk.ad \ + Xaw.ad \ + $(NULL) + +EXTRA_DIST = \ + $(xrdb_DATA) \ + $(NULL) diff --git a/plugins/xrdb/data/Makefile.in b/plugins/xrdb/data/Makefile.in new file mode 100644 index 0000000..9ef37f5 --- /dev/null +++ b/plugins/xrdb/data/Makefile.in @@ -0,0 +1,483 @@ +# 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/xrdb/data +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 = +SOURCES = +DIST_SOURCES = +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)$(xrdbdir)" +DATA = $(xrdb_DATA) +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 = +xrdbdir = $(pkgdatadir)/xrdb +xrdb_DATA = \ + General.ad \ + Editres.ad \ + Emacs.ad \ + Motif.ad \ + Tk.ad \ + Xaw.ad \ + $(NULL) + +EXTRA_DIST = \ + $(xrdb_DATA) \ + $(NULL) + +all: all-am + +.SUFFIXES: +$(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/xrdb/data/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plugins/xrdb/data/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): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-xrdbDATA: $(xrdb_DATA) + @$(NORMAL_INSTALL) + test -z "$(xrdbdir)" || $(MKDIR_P) "$(DESTDIR)$(xrdbdir)" + @list='$(xrdb_DATA)'; test -n "$(xrdbdir)" || 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)$(xrdbdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(xrdbdir)" || exit $$?; \ + done + +uninstall-xrdbDATA: + @$(NORMAL_UNINSTALL) + @list='$(xrdb_DATA)'; test -n "$(xrdbdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(xrdbdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(xrdbdir)" && rm -f $$files +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +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 $(DATA) +installdirs: + for dir in "$(DESTDIR)$(xrdbdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-xrdbDATA + +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 -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-xrdbDATA + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool 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 \ + install-xrdbDATA installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + uninstall uninstall-am uninstall-xrdbDATA + + +# 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/xrdb/data/Motif.ad b/plugins/xrdb/data/Motif.ad new file mode 100644 index 0000000..af36763 --- /dev/null +++ b/plugins/xrdb/data/Motif.ad @@ -0,0 +1,74 @@ +*XmScrollBar.background: BACKGROUND +*XmScrollBar.foreground: FOREGROUND + +*XmSash.background: BACKGROUND +*XmSash.foreground: FOREGROUND + +*XmLabel.background: BACKGROUND +*XmLabel.foreground: FOREGROUND +*XmLabelGadget.background: BACKGROUND +*XmLabelGadget.foreground: FOREGROUND + +*XmCascadeButton.background: BACKGROUND +*XmCascadeButton.foreground: FOREGROUND +*XmCascadeButtonGadget.background: BACKGROUND +*XmCascadeButtonGadget.foreground: FOREGROUND + +*XmToggleButton.background: BACKGROUND +*XmToggleButton.foreground: FOREGROUND +*XmToggleButtonGadget.background: BACKGROUND +*XmToggleButtonGadget.foreground: FOREGROUND + +*XmPushButton.background: BACKGROUND +*XmPushButton.foreground: FOREGROUND +*XmPushButtonGadget.background: BACKGROUND +*XmPushButtonGadget.foreground: FOREGROUND + +*XmSeparator.background: BACKGROUND +*XmSeparator.foreground: FOREGROUND +*XmSeparatorGadget.background: BACKGROUND +*XmSeparatorGadget.foreground: FOREGROUND + +*XmTearOffButton.background: BACKGROUND +*XmTearOffButton.foreground: FOREGROUND +*XmTearOffButtonGadget.background: BACKGROUND +*XmTearOffButtonGadget.foreground: FOREGROUND + +*XmMenuShell.background: BACKGROUND +*XmMenuShell.foreground: FOREGROUND + +*XmDialogShell.background: BACKGROUND +*XmDialogShell.foreground: FOREGROUND + +*XmFileSelectionBox.background: BACKGROUND +*XmFileSelectionBox.foreground: FOREGROUND + +*XmSelectionBox.background: BACKGROUND +*XmSelectionBox.foreground: FOREGROUND + +*XmMessageBox.background: BACKGROUND +*XmMessageBox.foreground: FOREGROUND + +*XmRowColumn.background: BACKGROUND +*XmRowColumn.foreground: FOREGROUND + +*XmFrame.background: BACKGROUND +*XmFrame.foreground: FOREGROUND + +*XmForm.background: BACKGROUND +*XmForm.foreground: FOREGROUND + +*XmScrolledWindow.background: BACKGROUND +*XmScrolledWindow.foreground: FOREGROUND + +*XmPanedWindow.background: BACKGROUND +*XmPanedWindow.foreground: FOREGROUND + +*XmText.background: WINDOW_BACKGROUND +*XmText.foreground: WINDOW_FOREGROUND + +*XmTextField.background: WINDOW_BACKGROUND +*XmTextField.foreground: WINDOW_FOREGROUND + +*XmList.background: WINDOW_BACKGROUND +*XmList.foreground: WINDOW_FOREGROUND diff --git a/plugins/xrdb/data/Tk.ad b/plugins/xrdb/data/Tk.ad new file mode 100644 index 0000000..d49ec38 --- /dev/null +++ b/plugins/xrdb/data/Tk.ad @@ -0,0 +1,102 @@ +*Toplevel.background: BACKGROUND +*Toplevel.foreground: FOREGROUND +*Toplevel.highlightBackground: BACKGROUND +*Toplevel.highlightColor: FOREGROUND +*Toplevel.activeBackground: BACKGROUND +*Toplevel.activeForeground: FOREGROUND + +*Button.background: BACKGROUND +*Button.foreground: FOREGROUND +*Button.highlightBackground: BACKGROUND +*Button.highlightColor: FOREGROUND +*Button.activeBackground: HIGHLIGHT +*Button.activeForeground: FOREGROUND + +*Menubutton.background: BACKGROUND +*Menubutton.foreground: FOREGROUND +*Menubutton.highlightBackground: BACKGROUND +*Menubutton.highlightColor: FOREGROUND +*Menubutton.activeBackground: ACTIVE_BACKGROUND +*Menubutton.activeForeground: ACTIVE_FOREGROUND + +*Checkbutton.background: BACKGROUND +*Checkbutton.foreground: FOREGROUND +*Checkbutton.highlightBackground: BACKGROUND +*Checkbutton.highlightColor: FOREGROUND +*Checkbutton.activeBackground: HIGHLIGHT +*Checkbutton.activeForeground: FOREGROUND + +*Radiobutton.background: BACKGROUND +*Radiobutton.foreground: FOREGROUND +*Radiobutton.highlightBackground: BACKGROUND +*Radiobutton.highlightColor: FOREGROUND +*Radiobutton.activeBackground: HIGHLIGHT +*Radiobutton.activeForeground: FOREGROUND + +*Label.background: BACKGROUND +*Label.foreground: FOREGROUND +*Label.highlightBackground: BACKGROUND +*Label.highlightColor: FOREGROUND + +*Menu.background: BACKGROUND +*Menu.foreground: FOREGROUND +*Menu.activeBackground: ACTIVE_BACKGROUND +*Menu.activeForeground: ACTIVE_FOREGROUND + +*Frame.background: BACKGROUND +*Frame.foreground: FOREGROUND + +*Labelframe.background: BACKGROUND +*Labelframe.foreground: FOREGROUND +*Labelframe.highlightColor: FOREGROUND + +*Scrollbar.background: BACKGROUND +*Scrollbar.highlightBackground: BACKGROUND +*Scrollbar.highlightColor: FOREGROUND +*Scrollbar.activeBackground: HIGHLIGHT +!*Scrollbar.troughColor: LOWLIGHT +!*Scrollbar.troughColor: BACKGROUND + +*Scale.background: BACKGROUND +*Scale.foreground: FOREGROUND +*Scale.highlightBackground: BACKGROUND +*Scale.highlightColor: FOREGROUND +*Scale.activeBackground: BACKGROUND +*Scale.activeForeground: FOREGROUND +!*Scale.troughColor: LOWLIGHT + +*Entry.background: WINDOW_BACKGROUND +*Entry.foreground: WINDOW_FOREGROUND +*Entry.highlightBackground: WINDOW_BACKGROUND +*Entry.highlightColor: WINDOW_FOREGROUND +*Entry.activeBackground: WINDOW_BACKGROUND +*Entry.activeForeground: WINDOW_FOREGROUND +*Entry.selectBackground: SELECT_BACKGROUND +*Entry.selectForeground: SELECT_FOREGROUND + +*Text.background: WINDOW_BACKGROUND +*Text.foreground: WINDOW_FOREGROUND +*Text.highlightBackground: WINDOW_BACKGROUND +*Text.highlightColor: WINDOW_FOREGROUND +*Text.activeBackground: WINDOW_BACKGROUND +*Text.activeForeground: WINDOW_FOREGROUND +*Text.selectBackground: SELECT_BACKGROUND +*Text.selectForeground: SELECT_FOREGROUND + +*Listbox.background: WINDOW_BACKGROUND +*Listbox.foreground: WINDOW_FOREGROUND +*Listbox.highlightBackground: WINDOW_BACKGROUND +*Listbox.highlightColor: WINDOW_FOREGROUND +*Listbox.activeBackground: WINDOW_BACKGROUND +*Listbox.activeForeground: WINDOW_FOREGROUND +*Listbox.selectBackground: SELECT_BACKGROUND +*Listbox.selectForeground: SELECT_FOREGROUND + +*Canvas.background: WINDOW_BACKGROUND +*Canvas.foreground: WINDOW_FOREGROUND +*Canvas.highlightBackground: WINDOW_BACKGROUND +*Canvas.highlightColor: WINDOW_FOREGROUND +*Canvas.activeBackground: WINDOW_BACKGROUND +*Canvas.activeForeground: WINDOW_FOREGROUND +*Canvas.selectbackground: SELECT_BACKGROUND +*Canvas.selectforeground: SELECT_FOREGROUND diff --git a/plugins/xrdb/data/Xaw.ad b/plugins/xrdb/data/Xaw.ad new file mode 100644 index 0000000..d44dc51 --- /dev/null +++ b/plugins/xrdb/data/Xaw.ad @@ -0,0 +1,25 @@ +*MenuButton.background: BACKGROUND +*Command.background: BACKGROUND +*Toggle.background: BACKGROUND +*Label.background: BACKGROUND +*Scrollbar*background: BACKGROUND +*SimpleMenu*background: BACKGROUND +*Box.background: BACKGROUND +*Form.background: BACKGROUND +*Dialog.background: BACKGROUND +*Text.background: WINDOW_BACKGROUND +*List.background: WINDOW_BACKGROUND + +*MenuButton.foreground: FOREGROUND +*Command.foreground: FOREGROUND +*Toggle.foreground: FOREGROUND +*Label.foreground: FOREGROUND +*Scrollbar.foreground: FOREGROUND +*SimpleMenu*foreground: FOREGROUND +*Box.foreground: FOREGROUND +*Form.foreground: FOREGROUND +*Dialog.foreground: FOREGROUND +*Text.foreground: WINDOW_FOREGROUND +*List.foreground: WINDOW_FOREGROUND + +*ScrollbarBackground: BACKGROUND diff --git a/plugins/xrdb/gsd-xrdb-manager.c b/plugins/xrdb/gsd-xrdb-manager.c new file mode 100644 index 0000000..47eed1d --- /dev/null +++ b/plugins/xrdb/gsd-xrdb-manager.c @@ -0,0 +1,638 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2003 Ross Burton <[email protected]> + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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 <sys/types.h> +#include <sys/wait.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> + +#include <locale.h> + +#include <glib.h> +#include <glib/gi18n.h> +#include <gdk/gdk.h> +#include <gdk/gdkx.h> +#include <gtk/gtk.h> + +#include "mate-settings-profile.h" +#include "gsd-xrdb-manager.h" + +#define GSD_XRDB_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_XRDB_MANAGER, GsdXrdbManagerPrivate)) + +#define SYSTEM_AD_DIR DATADIR "/xrdb" +#define GENERAL_AD SYSTEM_AD_DIR "/General.ad" +#define USER_AD_DIR ".mate2/xrdb" +#define USER_X_RESOURCES ".Xresources" +#define USER_X_DEFAULTS ".Xdefaults" + +#define GTK_THEME_KEY "/desktop/mate/interface/gtk_theme" + +struct GsdXrdbManagerPrivate +{ + GtkWidget *widget; +}; + +static void gsd_xrdb_manager_class_init (GsdXrdbManagerClass *klass); +static void gsd_xrdb_manager_init (GsdXrdbManager *xrdb_manager); +static void gsd_xrdb_manager_finalize (GObject *object); + +G_DEFINE_TYPE (GsdXrdbManager, gsd_xrdb_manager, G_TYPE_OBJECT) + +static gpointer manager_object = NULL; +static void + +append_color_define (GString *string, + const char *name, + const GdkColor *color) +{ + g_return_if_fail (string != NULL); + g_return_if_fail (name != NULL); + g_return_if_fail (color != NULL); + + g_string_append_printf (string, + "#define %s #%2.2hx%2.2hx%2.2hx\n", + name, + color->red>>8, + color->green>>8, + color->blue>>8); +} + +static GdkColor* +color_shade (GdkColor *a, + gdouble shade, + GdkColor *b) +{ + guint16 red, green, blue; + + red = CLAMP ((a->red) * shade, 0, 0xFFFF); + green = CLAMP ((a->green) * shade, 0, 0xFFFF); + blue = CLAMP ((a->blue) * shade, 0, 0xFFFF); + + b->red = red; + b->green = green; + b->blue = blue; + + return b; +} + +static void +append_theme_colors (GtkStyle *style, + GString *string) +{ + GdkColor tmp; + + g_return_if_fail (style != NULL); + g_return_if_fail (string != NULL); + + append_color_define (string, + "BACKGROUND", + &style->bg[GTK_STATE_NORMAL]); + append_color_define (string, + "FOREGROUND", + &style->fg[GTK_STATE_NORMAL]); + append_color_define (string, + "SELECT_BACKGROUND", + &style->bg[GTK_STATE_SELECTED]); + append_color_define (string, + "SELECT_FOREGROUND", + &style->text[GTK_STATE_SELECTED]); + append_color_define (string, + "WINDOW_BACKGROUND", + &style->base[GTK_STATE_NORMAL]); + append_color_define (string, + "WINDOW_FOREGROUND", + &style->text[GTK_STATE_NORMAL]); + append_color_define (string, + "INACTIVE_BACKGROUND", + &style->bg[GTK_STATE_INSENSITIVE]); + append_color_define (string, + "INACTIVE_FOREGROUND", + &style->text[GTK_STATE_INSENSITIVE]); + append_color_define (string, + "ACTIVE_BACKGROUND", + &style->bg[GTK_STATE_SELECTED]); + append_color_define (string, + "ACTIVE_FOREGROUND", + &style->text[GTK_STATE_SELECTED]); + + append_color_define (string, + "HIGHLIGHT", + color_shade (&style->bg[GTK_STATE_NORMAL], 1.2, &tmp)); + append_color_define (string, + "LOWLIGHT", + color_shade (&style->bg[GTK_STATE_NORMAL], 2.0/3.0, &tmp)); + return; +} + +/** + * Scan a single directory for .ad files, and return them all in a + * GSList* + */ +static GSList* +scan_ad_directory (const char *path, + GError **error) +{ + GSList *list; + GDir *dir; + const char *entry; + GError *local_error; + + list = NULL; + + g_return_val_if_fail (path != NULL, NULL); + + local_error = NULL; + dir = g_dir_open (path, 0, &local_error); + if (local_error != NULL) { + g_propagate_error (error, local_error); + return NULL; + } + + while ((entry = g_dir_read_name (dir)) != NULL) { + if (g_str_has_suffix (entry, ".ad")) { + list = g_slist_prepend (list, g_strdup_printf ("%s/%s", path, entry)); + } + } + + g_dir_close (dir); + + /* TODO: sort still? */ + return g_slist_sort (list, (GCompareFunc)strcmp); +} + +/** + * Compare two file names on their base names. + */ +static gint +compare_basenames (gconstpointer a, + gconstpointer b) +{ + char *base_a; + char *base_b; + int res; + + base_a = g_path_get_basename (a); + base_b = g_path_get_basename (b); + res = strcmp (base_a, base_b); + g_free (base_a); + g_free (base_b); + + return res; +} + +/** + * Scan the user and system paths, and return a list of strings in the + * right order for processing. + */ +static GSList* +scan_for_files (GsdXrdbManager *manager, + GError **error) +{ + const char *home_dir; + GSList *user_list; + GSList *system_list; + GSList *list; + GSList *p; + GError *local_error; + + list = NULL; + user_list = NULL; + system_list = NULL; + + local_error = NULL; + system_list = scan_ad_directory (SYSTEM_AD_DIR, &local_error); + if (local_error != NULL) { + g_propagate_error (error, local_error); + return NULL; + } + + home_dir = g_get_home_dir (); + if (home_dir != NULL) { + char *user_ad; + + user_ad = g_build_filename (home_dir, USER_AD_DIR, NULL); + + if (g_file_test (user_ad, G_FILE_TEST_IS_DIR)) { + + local_error = NULL; + user_list = scan_ad_directory (user_ad, &local_error); + if (local_error != NULL) { + g_propagate_error (error, local_error); + + g_slist_foreach (system_list, (GFunc)g_free, NULL); + g_slist_free (system_list); + g_free (user_ad); + return NULL; + } + } + + g_free (user_ad); + + } else { + g_warning (_("Cannot determine user's home directory")); + } + + /* An alternative approach would be to strdup() the strings + and free the entire contents of these lists, but that is a + little inefficient for my liking - RB */ + for (p = system_list; p != NULL; p = g_slist_next (p)) { + if (strcmp (p->data, GENERAL_AD) == 0) { + /* We ignore this, free the data now */ + g_free (p->data); + continue; + } + if (g_slist_find_custom (user_list, p->data, compare_basenames)) { + /* Ditto */ + g_free (p->data); + continue; + } + list = g_slist_prepend (list, p->data); + } + g_slist_free (system_list); + + for (p = user_list; p != NULL; p = g_slist_next (p)) { + list = g_slist_prepend (list, p->data); + } + g_slist_free (user_list); + + /* Reverse the order so it is the correct way */ + list = g_slist_reverse (list); + + /* Add the initial file */ + list = g_slist_prepend (list, g_strdup (GENERAL_AD)); + + return list; +} + +/** + * Append the contents of a file onto the end of a GString + */ +static void +append_file (const char *file, + GString *string, + GError **error) +{ + char *contents; + + g_return_if_fail (string != NULL); + g_return_if_fail (file != NULL); + + if (g_file_get_contents (file, &contents, NULL, error)) { + g_string_append (string, contents); + g_free (contents); + } +} + +/** + * Append an X resources file, such as .Xresources, or .Xdefaults + */ +static void +append_xresource_file (const char *filename, + GString *string, + GError **error) +{ + const char *home_path; + char *xresources; + + g_return_if_fail (string != NULL); + + home_path = g_get_home_dir (); + if (home_path == NULL) { + g_warning (_("Cannot determine user's home directory")); + return; + } + + xresources = g_build_filename (home_path, filename, NULL); + if (g_file_test (xresources, G_FILE_TEST_EXISTS)) { + GError *local_error; + + local_error = NULL; + + append_file (xresources, string, &local_error); + if (local_error != NULL) { + g_warning ("%s", local_error->message); + g_propagate_error (error, local_error); + } + } + g_free (xresources); +} + +static gboolean +write_all (int fd, + const char *buf, + gsize to_write) +{ + while (to_write > 0) { + gssize count = write (fd, buf, to_write); + if (count < 0) { + if (errno != EINTR) + return FALSE; + } else { + to_write -= count; + buf += count; + } + } + + return TRUE; +} + +static void +child_watch_cb (GPid pid, + int status, + gpointer user_data) +{ + char *command = user_data; + + if (!WIFEXITED (status) || WEXITSTATUS (status)) { + g_warning ("Command %s failed", command); + } +} + +static void +spawn_with_input (const char *command, + const char *input) +{ + char **argv; + int child_pid; + int inpipe; + GError *error; + gboolean res; + + argv = NULL; + res = g_shell_parse_argv (command, NULL, &argv, NULL); + if (! res) { + g_warning ("Unable to parse command: %s", command); + return; + } + + error = NULL; + res = g_spawn_async_with_pipes (NULL, + argv, + NULL, + G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, + NULL, + NULL, + &child_pid, + &inpipe, + NULL, + NULL, + &error); + g_strfreev (argv); + + if (! res) { + g_warning ("Could not execute %s: %s", command, error->message); + g_error_free (error); + + return; + } + + if (input != NULL) { + if (! write_all (inpipe, input, strlen (input))) { + g_warning ("Could not write input to %s", command); + } + + close (inpipe); + } + + g_child_watch_add (child_pid, (GChildWatchFunc) child_watch_cb, (gpointer)command); +} + +static void +apply_settings (GsdXrdbManager *manager, + GtkStyle *style) +{ + const char *command; + GString *string; + GSList *list; + GSList *p; + GError *error; + + mate_settings_profile_start (NULL); + + command = "xrdb -merge -quiet"; + + string = g_string_sized_new (256); + append_theme_colors (style, string); + + error = NULL; + list = scan_for_files (manager, &error); + if (error != NULL) { + g_warning ("%s", error->message); + g_error_free (error); + } + + for (p = list; p != NULL; p = p->next) { + error = NULL; + append_file (p->data, string, &error); + if (error != NULL) { + g_warning ("%s", error->message); + g_error_free (error); + } + } + + g_slist_foreach (list, (GFunc)g_free, NULL); + g_slist_free (list); + + error = NULL; + append_xresource_file (USER_X_RESOURCES, string, &error); + if (error != NULL) { + g_warning ("%s", error->message); + g_error_free (error); + } + + error = NULL; + append_xresource_file (USER_X_DEFAULTS, string, &error); + if (error != NULL) { + g_warning ("%s", error->message); + g_error_free (error); + } + + spawn_with_input (command, string->str); + g_string_free (string, TRUE); + + mate_settings_profile_end (NULL); + + return; +} + +static void +theme_changed (GtkSettings *settings, + GParamSpec *pspec, + GsdXrdbManager *manager) +{ + apply_settings (manager, gtk_widget_get_style (manager->priv->widget)); +} + +gboolean +gsd_xrdb_manager_start (GsdXrdbManager *manager, + GError **error) +{ + mate_settings_profile_start (NULL); + + /* the initialization is done here otherwise + mate_settings_xsettings_load would generate + false hit as gtk-theme-name is set to Default in + mate_settings_xsettings_init */ + g_signal_connect (gtk_settings_get_default (), + "notify::gtk-theme-name", + G_CALLBACK (theme_changed), + manager); + + manager->priv->widget = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_ensure_style (manager->priv->widget); + + mate_settings_profile_end (NULL); + + return TRUE; +} + +void +gsd_xrdb_manager_stop (GsdXrdbManager *manager) +{ + GsdXrdbManagerPrivate *p = manager->priv; + + g_debug ("Stopping xrdb manager"); + + g_signal_handlers_disconnect_by_func (gtk_settings_get_default (), + theme_changed, + manager); + + if (p->widget != NULL) { + gtk_widget_destroy (p->widget); + p->widget = NULL; + } +} + +static void +gsd_xrdb_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GsdXrdbManager *self; + + self = GSD_XRDB_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gsd_xrdb_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GsdXrdbManager *self; + + self = GSD_XRDB_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +gsd_xrdb_manager_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GsdXrdbManager *xrdb_manager; + GsdXrdbManagerClass *klass; + + klass = GSD_XRDB_MANAGER_CLASS (g_type_class_peek (GSD_TYPE_XRDB_MANAGER)); + + xrdb_manager = GSD_XRDB_MANAGER (G_OBJECT_CLASS (gsd_xrdb_manager_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + + return G_OBJECT (xrdb_manager); +} + +static void +gsd_xrdb_manager_dispose (GObject *object) +{ + GsdXrdbManager *xrdb_manager; + + xrdb_manager = GSD_XRDB_MANAGER (object); + + G_OBJECT_CLASS (gsd_xrdb_manager_parent_class)->dispose (object); +} + +static void +gsd_xrdb_manager_class_init (GsdXrdbManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gsd_xrdb_manager_get_property; + object_class->set_property = gsd_xrdb_manager_set_property; + object_class->constructor = gsd_xrdb_manager_constructor; + object_class->dispose = gsd_xrdb_manager_dispose; + object_class->finalize = gsd_xrdb_manager_finalize; + + g_type_class_add_private (klass, sizeof (GsdXrdbManagerPrivate)); +} + +static void +gsd_xrdb_manager_init (GsdXrdbManager *manager) +{ + manager->priv = GSD_XRDB_MANAGER_GET_PRIVATE (manager); + +} + +static void +gsd_xrdb_manager_finalize (GObject *object) +{ + GsdXrdbManager *xrdb_manager; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_XRDB_MANAGER (object)); + + xrdb_manager = GSD_XRDB_MANAGER (object); + + g_return_if_fail (xrdb_manager->priv != NULL); + + G_OBJECT_CLASS (gsd_xrdb_manager_parent_class)->finalize (object); +} + +GsdXrdbManager * +gsd_xrdb_manager_new (void) +{ + if (manager_object != NULL) { + g_object_ref (manager_object); + } else { + manager_object = g_object_new (GSD_TYPE_XRDB_MANAGER, NULL); + g_object_add_weak_pointer (manager_object, + (gpointer *) &manager_object); + } + + return GSD_XRDB_MANAGER (manager_object); +} diff --git a/plugins/xrdb/gsd-xrdb-manager.h b/plugins/xrdb/gsd-xrdb-manager.h new file mode 100644 index 0000000..4588e69 --- /dev/null +++ b/plugins/xrdb/gsd-xrdb-manager.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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_XRDB_MANAGER_H +#define __GSD_XRDB_MANAGER_H + +#include <glib-object.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_XRDB_MANAGER (gsd_xrdb_manager_get_type ()) +#define GSD_XRDB_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_XRDB_MANAGER, GsdXrdbManager)) +#define GSD_XRDB_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_XRDB_MANAGER, GsdXrdbManagerClass)) +#define GSD_IS_XRDB_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_XRDB_MANAGER)) +#define GSD_IS_XRDB_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_XRDB_MANAGER)) +#define GSD_XRDB_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_XRDB_MANAGER, GsdXrdbManagerClass)) + +typedef struct GsdXrdbManagerPrivate GsdXrdbManagerPrivate; + +typedef struct +{ + GObject parent; + GsdXrdbManagerPrivate *priv; +} GsdXrdbManager; + +typedef struct +{ + GObjectClass parent_class; +} GsdXrdbManagerClass; + +GType gsd_xrdb_manager_get_type (void); + +GsdXrdbManager * gsd_xrdb_manager_new (void); +gboolean gsd_xrdb_manager_start (GsdXrdbManager *manager, + GError **error); +void gsd_xrdb_manager_stop (GsdXrdbManager *manager); + +#ifdef __cplusplus +} +#endif + +#endif /* __GSD_XRDB_MANAGER_H */ diff --git a/plugins/xrdb/gsd-xrdb-plugin.c b/plugins/xrdb/gsd-xrdb-plugin.c new file mode 100644 index 0000000..870eb56 --- /dev/null +++ b/plugins/xrdb/gsd-xrdb-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 <[email protected]> + * + * 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 <glib/gi18n-lib.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" +#include "gsd-xrdb-plugin.h" +#include "gsd-xrdb-manager.h" + +struct GsdXrdbPluginPrivate { + GsdXrdbManager *manager; +}; + +#define GSD_XRDB_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), GSD_TYPE_XRDB_PLUGIN, GsdXrdbPluginPrivate)) + +MATE_SETTINGS_PLUGIN_REGISTER (GsdXrdbPlugin, gsd_xrdb_plugin) + +static void +gsd_xrdb_plugin_init (GsdXrdbPlugin *plugin) +{ + plugin->priv = GSD_XRDB_PLUGIN_GET_PRIVATE (plugin); + + g_debug ("GsdXrdbPlugin initializing"); + + plugin->priv->manager = gsd_xrdb_manager_new (); +} + +static void +gsd_xrdb_plugin_finalize (GObject *object) +{ + GsdXrdbPlugin *plugin; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_XRDB_PLUGIN (object)); + + g_debug ("GsdXrdbPlugin finalizing"); + + plugin = GSD_XRDB_PLUGIN (object); + + g_return_if_fail (plugin->priv != NULL); + + if (plugin->priv->manager != NULL) { + g_object_unref (plugin->priv->manager); + } + + G_OBJECT_CLASS (gsd_xrdb_plugin_parent_class)->finalize (object); +} + +static void +impl_activate (MateSettingsPlugin *plugin) +{ + gboolean res; + GError *error; + + g_debug ("Activating xrdb plugin"); + + error = NULL; + res = gsd_xrdb_manager_start (GSD_XRDB_PLUGIN (plugin)->priv->manager, &error); + if (! res) { + g_warning ("Unable to start xrdb manager: %s", error->message); + g_error_free (error); + } +} + +static void +impl_deactivate (MateSettingsPlugin *plugin) +{ + g_debug ("Deactivating xrdb plugin"); + gsd_xrdb_manager_stop (GSD_XRDB_PLUGIN (plugin)->priv->manager); +} + +static void +gsd_xrdb_plugin_class_init (GsdXrdbPluginClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MateSettingsPluginClass *plugin_class = MATE_SETTINGS_PLUGIN_CLASS (klass); + + object_class->finalize = gsd_xrdb_plugin_finalize; + + plugin_class->activate = impl_activate; + plugin_class->deactivate = impl_deactivate; + + g_type_class_add_private (klass, sizeof (GsdXrdbPluginPrivate)); +} diff --git a/plugins/xrdb/gsd-xrdb-plugin.h b/plugins/xrdb/gsd-xrdb-plugin.h new file mode 100644 index 0000000..9baa26a --- /dev/null +++ b/plugins/xrdb/gsd-xrdb-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 <[email protected]> + * + * 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_XRDB_PLUGIN_H__ +#define __GSD_XRDB_PLUGIN_H__ + +#include <glib.h> +#include <glib-object.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GSD_TYPE_XRDB_PLUGIN (gsd_xrdb_plugin_get_type ()) +#define GSD_XRDB_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_XRDB_PLUGIN, GsdXrdbPlugin)) +#define GSD_XRDB_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_XRDB_PLUGIN, GsdXrdbPluginClass)) +#define GSD_IS_XRDB_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_XRDB_PLUGIN)) +#define GSD_IS_XRDB_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_XRDB_PLUGIN)) +#define GSD_XRDB_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_XRDB_PLUGIN, GsdXrdbPluginClass)) + +typedef struct GsdXrdbPluginPrivate GsdXrdbPluginPrivate; + +typedef struct +{ + MateSettingsPlugin parent; + GsdXrdbPluginPrivate *priv; +} GsdXrdbPlugin; + +typedef struct +{ + MateSettingsPluginClass parent_class; +} GsdXrdbPluginClass; + +GType gsd_xrdb_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_XRDB_PLUGIN_H__ */ diff --git a/plugins/xrdb/xrdb.mate-settings-plugin.in b/plugins/xrdb/xrdb.mate-settings-plugin.in new file mode 100644 index 0000000..e21a4c2 --- /dev/null +++ b/plugins/xrdb/xrdb.mate-settings-plugin.in @@ -0,0 +1,8 @@ +[MATE Settings Plugin] +Module=xrdb +IAge=0 +_Name=X Resource Database +_Description=Manage the X resource database +Authors=Ross Burton +Copyright=Copyright © 2007 Ross Burton +Website= diff --git a/plugins/xsettings/Makefile.am b/plugins/xsettings/Makefile.am new file mode 100644 index 0000000..8b861b9 --- /dev/null +++ b/plugins/xsettings/Makefile.am @@ -0,0 +1,65 @@ +NULL = + +plugin_LTLIBRARIES = \ + libxsettings.la \ + $(NULL) + +libxsettings_la_SOURCES = \ + gsd-xsettings-plugin.h \ + gsd-xsettings-plugin.c \ + gsd-xsettings-manager.h \ + gsd-xsettings-manager.c \ + xsettings-common.h \ + xsettings-common.c \ + xsettings-manager.h \ + xsettings-manager.c \ + $(NULL) + +libxsettings_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libxsettings_la_CFLAGS = \ + $(SETTINGS_PLUGIN_CFLAGS) \ + $(AM_CFLAGS) + +libxsettings_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) \ + $(NULL) + +libxsettings_la_LIBADD = \ + $(SETTINGS_PLUGIN_LIBS) \ + $(NULL) + +if HAVE_FONTCONFIG +libxsettings_la_SOURCES += \ + fontconfig-monitor.h \ + fontconfig-monitor.c \ + $(NULL) +libxsettings_la_CFLAGS += \ + $(FONTCONFIG_CFLAGS) +libxsettings_la_LIBADD += \ + $(FONTCONFIG_LIBS) +endif + + +plugin_in_files = \ + xsettings.mate-settings-plugin.in \ + $(NULL) + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) + +EXTRA_DIST = \ + $(plugin_in_files) \ + $(NULL) + +CLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +DISTCLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +@GSD_INTLTOOL_PLUGIN_RULE@ diff --git a/plugins/xsettings/Makefile.in b/plugins/xsettings/Makefile.in new file mode 100644 index 0000000..4f5f8ed --- /dev/null +++ b/plugins/xsettings/Makefile.in @@ -0,0 +1,718 @@ +# 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_FONTCONFIG_TRUE@am__append_1 = \ +@HAVE_FONTCONFIG_TRUE@ fontconfig-monitor.h \ +@HAVE_FONTCONFIG_TRUE@ fontconfig-monitor.c \ +@HAVE_FONTCONFIG_TRUE@ $(NULL) + +@HAVE_FONTCONFIG_TRUE@am__append_2 = \ +@HAVE_FONTCONFIG_TRUE@ $(FONTCONFIG_CFLAGS) + +@HAVE_FONTCONFIG_TRUE@am__append_3 = \ +@HAVE_FONTCONFIG_TRUE@ $(FONTCONFIG_LIBS) + +subdir = plugins/xsettings +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)$(plugindir)" +LTLIBRARIES = $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +@HAVE_FONTCONFIG_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) +libxsettings_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) +am__libxsettings_la_SOURCES_DIST = gsd-xsettings-plugin.h \ + gsd-xsettings-plugin.c gsd-xsettings-manager.h \ + gsd-xsettings-manager.c xsettings-common.h xsettings-common.c \ + xsettings-manager.h xsettings-manager.c fontconfig-monitor.h \ + fontconfig-monitor.c +am__objects_1 = +@HAVE_FONTCONFIG_TRUE@am__objects_2 = \ +@HAVE_FONTCONFIG_TRUE@ libxsettings_la-fontconfig-monitor.lo \ +@HAVE_FONTCONFIG_TRUE@ $(am__objects_1) +am_libxsettings_la_OBJECTS = libxsettings_la-gsd-xsettings-plugin.lo \ + libxsettings_la-gsd-xsettings-manager.lo \ + libxsettings_la-xsettings-common.lo \ + libxsettings_la-xsettings-manager.lo $(am__objects_1) \ + $(am__objects_2) +libxsettings_la_OBJECTS = $(am_libxsettings_la_OBJECTS) +libxsettings_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libxsettings_la_CFLAGS) \ + $(CFLAGS) $(libxsettings_la_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 = $(libxsettings_la_SOURCES) +DIST_SOURCES = $(am__libxsettings_la_SOURCES_DIST) +DATA = $(plugin_DATA) +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 = +plugin_LTLIBRARIES = \ + libxsettings.la \ + $(NULL) + +libxsettings_la_SOURCES = gsd-xsettings-plugin.h \ + gsd-xsettings-plugin.c gsd-xsettings-manager.h \ + gsd-xsettings-manager.c xsettings-common.h xsettings-common.c \ + xsettings-manager.h xsettings-manager.c $(NULL) \ + $(am__append_1) +libxsettings_la_CPPFLAGS = \ + -I$(top_srcdir)/mate-settings-daemon \ + -DMATE_SETTINGS_LOCALEDIR=\""$(datadir)/locale"\" \ + $(AM_CPPFLAGS) + +libxsettings_la_CFLAGS = $(SETTINGS_PLUGIN_CFLAGS) $(AM_CFLAGS) \ + $(am__append_2) +libxsettings_la_LDFLAGS = \ + $(GSD_PLUGIN_LDFLAGS) \ + $(NULL) + +libxsettings_la_LIBADD = $(SETTINGS_PLUGIN_LIBS) $(NULL) \ + $(am__append_3) +plugin_in_files = \ + xsettings.mate-settings-plugin.in \ + $(NULL) + +plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin) +EXTRA_DIST = \ + $(plugin_in_files) \ + $(NULL) + +CLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +DISTCLEANFILES = \ + $(plugin_DATA) \ + $(NULL) + +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/xsettings/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu plugins/xsettings/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 +libxsettings.la: $(libxsettings_la_OBJECTS) $(libxsettings_la_DEPENDENCIES) + $(libxsettings_la_LINK) -rpath $(plugindir) $(libxsettings_la_OBJECTS) $(libxsettings_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxsettings_la-fontconfig-monitor.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxsettings_la-gsd-xsettings-manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxsettings_la-gsd-xsettings-plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxsettings_la-xsettings-common.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libxsettings_la-xsettings-manager.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 $@ $< + +libxsettings_la-gsd-xsettings-plugin.lo: gsd-xsettings-plugin.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxsettings_la_CPPFLAGS) $(CPPFLAGS) $(libxsettings_la_CFLAGS) $(CFLAGS) -MT libxsettings_la-gsd-xsettings-plugin.lo -MD -MP -MF $(DEPDIR)/libxsettings_la-gsd-xsettings-plugin.Tpo -c -o libxsettings_la-gsd-xsettings-plugin.lo `test -f 'gsd-xsettings-plugin.c' || echo '$(srcdir)/'`gsd-xsettings-plugin.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxsettings_la-gsd-xsettings-plugin.Tpo $(DEPDIR)/libxsettings_la-gsd-xsettings-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-xsettings-plugin.c' object='libxsettings_la-gsd-xsettings-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) $(libxsettings_la_CPPFLAGS) $(CPPFLAGS) $(libxsettings_la_CFLAGS) $(CFLAGS) -c -o libxsettings_la-gsd-xsettings-plugin.lo `test -f 'gsd-xsettings-plugin.c' || echo '$(srcdir)/'`gsd-xsettings-plugin.c + +libxsettings_la-gsd-xsettings-manager.lo: gsd-xsettings-manager.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxsettings_la_CPPFLAGS) $(CPPFLAGS) $(libxsettings_la_CFLAGS) $(CFLAGS) -MT libxsettings_la-gsd-xsettings-manager.lo -MD -MP -MF $(DEPDIR)/libxsettings_la-gsd-xsettings-manager.Tpo -c -o libxsettings_la-gsd-xsettings-manager.lo `test -f 'gsd-xsettings-manager.c' || echo '$(srcdir)/'`gsd-xsettings-manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxsettings_la-gsd-xsettings-manager.Tpo $(DEPDIR)/libxsettings_la-gsd-xsettings-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gsd-xsettings-manager.c' object='libxsettings_la-gsd-xsettings-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) $(libxsettings_la_CPPFLAGS) $(CPPFLAGS) $(libxsettings_la_CFLAGS) $(CFLAGS) -c -o libxsettings_la-gsd-xsettings-manager.lo `test -f 'gsd-xsettings-manager.c' || echo '$(srcdir)/'`gsd-xsettings-manager.c + +libxsettings_la-xsettings-common.lo: xsettings-common.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxsettings_la_CPPFLAGS) $(CPPFLAGS) $(libxsettings_la_CFLAGS) $(CFLAGS) -MT libxsettings_la-xsettings-common.lo -MD -MP -MF $(DEPDIR)/libxsettings_la-xsettings-common.Tpo -c -o libxsettings_la-xsettings-common.lo `test -f 'xsettings-common.c' || echo '$(srcdir)/'`xsettings-common.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxsettings_la-xsettings-common.Tpo $(DEPDIR)/libxsettings_la-xsettings-common.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='xsettings-common.c' object='libxsettings_la-xsettings-common.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) $(libxsettings_la_CPPFLAGS) $(CPPFLAGS) $(libxsettings_la_CFLAGS) $(CFLAGS) -c -o libxsettings_la-xsettings-common.lo `test -f 'xsettings-common.c' || echo '$(srcdir)/'`xsettings-common.c + +libxsettings_la-xsettings-manager.lo: xsettings-manager.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxsettings_la_CPPFLAGS) $(CPPFLAGS) $(libxsettings_la_CFLAGS) $(CFLAGS) -MT libxsettings_la-xsettings-manager.lo -MD -MP -MF $(DEPDIR)/libxsettings_la-xsettings-manager.Tpo -c -o libxsettings_la-xsettings-manager.lo `test -f 'xsettings-manager.c' || echo '$(srcdir)/'`xsettings-manager.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxsettings_la-xsettings-manager.Tpo $(DEPDIR)/libxsettings_la-xsettings-manager.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='xsettings-manager.c' object='libxsettings_la-xsettings-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) $(libxsettings_la_CPPFLAGS) $(CPPFLAGS) $(libxsettings_la_CFLAGS) $(CFLAGS) -c -o libxsettings_la-xsettings-manager.lo `test -f 'xsettings-manager.c' || echo '$(srcdir)/'`xsettings-manager.c + +libxsettings_la-fontconfig-monitor.lo: fontconfig-monitor.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libxsettings_la_CPPFLAGS) $(CPPFLAGS) $(libxsettings_la_CFLAGS) $(CFLAGS) -MT libxsettings_la-fontconfig-monitor.lo -MD -MP -MF $(DEPDIR)/libxsettings_la-fontconfig-monitor.Tpo -c -o libxsettings_la-fontconfig-monitor.lo `test -f 'fontconfig-monitor.c' || echo '$(srcdir)/'`fontconfig-monitor.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libxsettings_la-fontconfig-monitor.Tpo $(DEPDIR)/libxsettings_la-fontconfig-monitor.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fontconfig-monitor.c' object='libxsettings_la-fontconfig-monitor.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) $(libxsettings_la_CPPFLAGS) $(CPPFLAGS) $(libxsettings_la_CFLAGS) $(CFLAGS) -c -o libxsettings_la-fontconfig-monitor.lo `test -f 'fontconfig-monitor.c' || echo '$(srcdir)/'`fontconfig-monitor.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +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 + +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) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -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." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ + 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-pluginDATA install-pluginLTLIBRARIES + +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: uninstall-pluginDATA uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-pluginLTLIBRARIES 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-pluginDATA \ + install-pluginLTLIBRARIES 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 \ + uninstall-pluginDATA uninstall-pluginLTLIBRARIES + + +@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/xsettings/fontconfig-monitor.c b/plugins/xsettings/fontconfig-monitor.c new file mode 100644 index 0000000..bfb15ed --- /dev/null +++ b/plugins/xsettings/fontconfig-monitor.c @@ -0,0 +1,192 @@ +/* -*- 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. + * + * Author: Behdad Esfahbod, Red Hat, Inc. + */ + +#include "fontconfig-monitor.h" + +#include <gio/gio.h> +#include <fontconfig/fontconfig.h> + +#define TIMEOUT_SECONDS 2 + +static void +stuff_changed (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + gpointer handle); + +void +fontconfig_cache_init (void) +{ + FcInit (); +} + +gboolean +fontconfig_cache_update (void) +{ + return !FcConfigUptoDate (NULL) && FcInitReinitialize (); +} + +static void +monitor_files (GPtrArray *monitors, + FcStrList *list, + gpointer data) +{ + const char *str; + + while ((str = (const char *) FcStrListNext (list))) { + GFile *file; + GFileMonitor *monitor; + + file = g_file_new_for_path (str); + + monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, NULL); + + g_object_unref (file); + + if (!monitor) + continue; + + g_signal_connect (monitor, "changed", G_CALLBACK (stuff_changed), data); + + g_ptr_array_add (monitors, monitor); + } + + FcStrListDone (list); +} + + +struct _fontconfig_monitor_handle { + GPtrArray *monitors; + + guint timeout; + + GFunc notify_callback; + gpointer notify_data; +}; + +static GPtrArray * +monitors_create (gpointer data) +{ + GPtrArray *monitors = g_ptr_array_new (); + + monitor_files (monitors, FcConfigGetConfigFiles (NULL), data); + monitor_files (monitors, FcConfigGetFontDirs (NULL) , data); + + return monitors; +} + +static void +monitors_free (GPtrArray *monitors) +{ + if (!monitors) + return; + + g_ptr_array_foreach (monitors, (GFunc) g_object_unref, NULL); + g_ptr_array_free (monitors, TRUE); +} + +static gboolean +update (gpointer data) +{ + fontconfig_monitor_handle_t *handle = data; + gboolean notify = FALSE; + + handle->timeout = 0; + + if (fontconfig_cache_update ()) { + notify = TRUE; + monitors_free (handle->monitors); + handle->monitors = monitors_create (data); + } + + /* we finish modifying handle before calling the notify callback, + * allowing the callback to free the monitor if it decides to. */ + + if (notify && handle->notify_callback) + handle->notify_callback (data, handle->notify_data); + + return FALSE; +} + +static void +stuff_changed (GFileMonitor *monitor G_GNUC_UNUSED, + GFile *file G_GNUC_UNUSED, + GFile *other_file G_GNUC_UNUSED, + GFileMonitorEvent event_type G_GNUC_UNUSED, + gpointer data) +{ + fontconfig_monitor_handle_t *handle = data; + + /* wait for quiescence */ + if (handle->timeout) + g_source_remove (handle->timeout); + + handle->timeout = g_timeout_add_seconds (TIMEOUT_SECONDS, update, data); +} + + +fontconfig_monitor_handle_t * +fontconfig_monitor_start (GFunc notify_callback, + gpointer notify_data) +{ + fontconfig_monitor_handle_t *handle = g_slice_new0 (fontconfig_monitor_handle_t); + + handle->notify_callback = notify_callback; + handle->notify_data = notify_data; + handle->monitors = monitors_create (handle); + + return handle; +} + +void +fontconfig_monitor_stop (fontconfig_monitor_handle_t *handle) +{ + if (handle->timeout) + g_source_remove (handle->timeout); + handle->timeout = 0; + + monitors_free (handle->monitors); + handle->monitors = NULL; +} + +#ifdef FONTCONFIG_MONITOR_TEST +static void +yay (void) +{ + g_message ("yay"); +} + +int +main (void) +{ + GMainLoop *loop; + + g_type_init (); + + fontconfig_monitor_start ((GFunc) yay, NULL); + + loop = g_main_loop_new (NULL, TRUE); + g_main_loop_run (loop); + + return 0; +} +#endif diff --git a/plugins/xsettings/fontconfig-monitor.h b/plugins/xsettings/fontconfig-monitor.h new file mode 100644 index 0000000..71256e4 --- /dev/null +++ b/plugins/xsettings/fontconfig-monitor.h @@ -0,0 +1,44 @@ +/* -*- 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. + * + * Author: Behdad Esfahbod, Red Hat, Inc. + */ +#ifndef __FONTCONFIG_MONITOR_H +#define __FONTCONFIG_MONITOR_H + +#include <glib.h> + +#ifdef __cplusplus +extern "C" { +#endif + +void fontconfig_cache_init (void); +gboolean fontconfig_cache_update (void); + +typedef struct _fontconfig_monitor_handle fontconfig_monitor_handle_t; + +fontconfig_monitor_handle_t * +fontconfig_monitor_start (GFunc notify_callback, + gpointer notify_data); +void fontconfig_monitor_stop (fontconfig_monitor_handle_t *handle); + +#ifdef __cplusplus +} +#endif + +#endif /* __FONTCONFIG_MONITOR_H */ diff --git a/plugins/xsettings/gsd-xsettings-manager.c b/plugins/xsettings/gsd-xsettings-manager.c new file mode 100644 index 0000000..e7b4f9a --- /dev/null +++ b/plugins/xsettings/gsd-xsettings-manager.c @@ -0,0 +1,1040 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 Rodrigo Moya + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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 <sys/types.h> +#include <sys/wait.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <time.h> + +#include <X11/Xatom.h> + +#include <glib.h> +#include <glib/gi18n.h> +#include <gdk/gdk.h> +#include <gdk/gdkx.h> +#include <gtk/gtk.h> +#include <mateconf/mateconf.h> +#include <mateconf/mateconf-client.h> + +#include "mate-settings-profile.h" +#include "gsd-xsettings-manager.h" +#include "xsettings-manager.h" +#ifdef HAVE_FONTCONFIG +#include "fontconfig-monitor.h" +#endif /* HAVE_FONTCONFIG */ + +#define MATE_XSETTINGS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MATE_TYPE_XSETTINGS_MANAGER, MateXSettingsManagerPrivate)) + +#define MOUSE_SETTINGS_DIR "/desktop/mate/peripherals/mouse" +#define GTK_SETTINGS_DIR "/desktop/gtk" +#define INTERFACE_SETTINGS_DIR "/desktop/mate/interface" +#define SOUND_SETTINGS_DIR "/desktop/mate/sound" +#define GTK_MODULES_DIR "/apps/mate_settings_daemon/gtk-modules" + +#ifdef HAVE_FONTCONFIG +#define FONT_RENDER_DIR "/desktop/mate/font_rendering" +#define FONT_ANTIALIASING_KEY FONT_RENDER_DIR "/antialiasing" +#define FONT_HINTING_KEY FONT_RENDER_DIR "/hinting" +#define FONT_RGBA_ORDER_KEY FONT_RENDER_DIR "/rgba_order" +#define FONT_DPI_KEY FONT_RENDER_DIR "/dpi" + +/* X servers sometimes lie about the screen's physical dimensions, so we cannot + * compute an accurate DPI value. When this happens, the user gets fonts that + * are too huge or too tiny. So, we see what the server returns: if it reports + * something outside of the range [DPI_LOW_REASONABLE_VALUE, + * DPI_HIGH_REASONABLE_VALUE], then we assume that it is lying and we use + * DPI_FALLBACK instead. + * + * See get_dpi_from_mateconf_or_server() below, and also + * https://bugzilla.novell.com/show_bug.cgi?id=217790 + */ +#define DPI_FALLBACK 96 +#define DPI_LOW_REASONABLE_VALUE 50 +#define DPI_HIGH_REASONABLE_VALUE 500 + +#endif /* HAVE_FONTCONFIG */ + +typedef struct _TranslationEntry TranslationEntry; +typedef void (* TranslationFunc) (MateXSettingsManager *manager, + TranslationEntry *trans, + MateConfValue *value); + +struct _TranslationEntry { + const char *mateconf_key; + const char *xsetting_name; + + MateConfValueType mateconf_type; + TranslationFunc translate; +}; + +struct MateXSettingsManagerPrivate +{ + XSettingsManager **managers; + guint notify[6]; +#ifdef HAVE_FONTCONFIG + fontconfig_monitor_handle_t *fontconfig_handle; +#endif /* HAVE_FONTCONFIG */ +}; + +#define GSD_XSETTINGS_ERROR gsd_xsettings_error_quark () + +enum { + GSD_XSETTINGS_ERROR_INIT +}; + +static void mate_xsettings_manager_class_init (MateXSettingsManagerClass *klass); +static void mate_xsettings_manager_init (MateXSettingsManager *xsettings_manager); +static void mate_xsettings_manager_finalize (GObject *object); + +G_DEFINE_TYPE (MateXSettingsManager, mate_xsettings_manager, G_TYPE_OBJECT) + +static gpointer manager_object = NULL; + +static GQuark +gsd_xsettings_error_quark (void) +{ + return g_quark_from_static_string ("gsd-xsettings-error-quark"); +} + +static void +translate_bool_int (MateXSettingsManager *manager, + TranslationEntry *trans, + MateConfValue *value) +{ + int i; + + g_assert (value->type == trans->mateconf_type); + + for (i = 0; manager->priv->managers [i]; i++) { + xsettings_manager_set_int (manager->priv->managers [i], trans->xsetting_name, + mateconf_value_get_bool (value)); + } +} + +static void +translate_int_int (MateXSettingsManager *manager, + TranslationEntry *trans, + MateConfValue *value) +{ + int i; + + g_assert (value->type == trans->mateconf_type); + + for (i = 0; manager->priv->managers [i]; i++) { + xsettings_manager_set_int (manager->priv->managers [i], trans->xsetting_name, + mateconf_value_get_int (value)); + } +} + +static void +translate_string_string (MateXSettingsManager *manager, + TranslationEntry *trans, + MateConfValue *value) +{ + int i; + + g_assert (value->type == trans->mateconf_type); + + for (i = 0; manager->priv->managers [i]; i++) { + xsettings_manager_set_string (manager->priv->managers [i], + trans->xsetting_name, + mateconf_value_get_string (value)); + } +} + +static void +translate_string_string_toolbar (MateXSettingsManager *manager, + TranslationEntry *trans, + MateConfValue *value) +{ + int i; + const char *tmp; + + g_assert (value->type == trans->mateconf_type); + + /* This is kind of a workaround since MATE expects the key value to be + * "both_horiz" and gtk+ wants the XSetting to be "both-horiz". + */ + tmp = mateconf_value_get_string (value); + if (tmp && strcmp (tmp, "both_horiz") == 0) { + tmp = "both-horiz"; + } + + for (i = 0; manager->priv->managers [i]; i++) { + xsettings_manager_set_string (manager->priv->managers [i], + trans->xsetting_name, + tmp); + } +} + +static TranslationEntry translations [] = { + { "/desktop/mate/peripherals/mouse/double_click", "Net/DoubleClickTime", MATECONF_VALUE_INT, translate_int_int }, + { "/desktop/mate/peripherals/mouse/drag_threshold", "Net/DndDragThreshold", MATECONF_VALUE_INT, translate_int_int }, + { "/desktop/mate/gtk-color-palette", "Gtk/ColorPalette", MATECONF_VALUE_STRING, translate_string_string }, + { "/desktop/mate/interface/font_name", "Gtk/FontName", MATECONF_VALUE_STRING, translate_string_string }, + { "/desktop/mate/interface/gtk_key_theme", "Gtk/KeyThemeName", MATECONF_VALUE_STRING, translate_string_string }, + { "/desktop/mate/interface/toolbar_style", "Gtk/ToolbarStyle", MATECONF_VALUE_STRING, translate_string_string_toolbar }, + { "/desktop/mate/interface/toolbar_icons_size", "Gtk/ToolbarIconSize", MATECONF_VALUE_STRING, translate_string_string }, + { "/desktop/mate/interface/can_change_accels", "Gtk/CanChangeAccels", MATECONF_VALUE_BOOL, translate_bool_int }, + { "/desktop/mate/interface/cursor_blink", "Net/CursorBlink", MATECONF_VALUE_BOOL, translate_bool_int }, + { "/desktop/mate/interface/cursor_blink_time", "Net/CursorBlinkTime", MATECONF_VALUE_INT, translate_int_int }, + { "/desktop/mate/interface/gtk_theme", "Net/ThemeName", MATECONF_VALUE_STRING, translate_string_string }, + { "/desktop/mate/interface/gtk_color_scheme", "Gtk/ColorScheme", MATECONF_VALUE_STRING, translate_string_string }, + { "/desktop/mate/interface/gtk-im-preedit-style", "Gtk/IMPreeditStyle", MATECONF_VALUE_STRING, translate_string_string }, + { "/desktop/mate/interface/gtk-im-status-style", "Gtk/IMStatusStyle", MATECONF_VALUE_STRING, translate_string_string }, + { "/desktop/mate/interface/gtk-im-module", "Gtk/IMModule", MATECONF_VALUE_STRING, translate_string_string }, + { "/desktop/mate/interface/icon_theme", "Net/IconThemeName", MATECONF_VALUE_STRING, translate_string_string }, + { "/desktop/mate/interface/file_chooser_backend", "Gtk/FileChooserBackend", MATECONF_VALUE_STRING, translate_string_string }, + { "/desktop/mate/interface/menus_have_icons", "Gtk/MenuImages", MATECONF_VALUE_BOOL, translate_bool_int }, + { "/desktop/mate/interface/buttons_have_icons", "Gtk/ButtonImages", MATECONF_VALUE_BOOL, translate_bool_int }, + { "/desktop/mate/interface/menubar_accel", "Gtk/MenuBarAccel", MATECONF_VALUE_STRING, translate_string_string }, + { "/desktop/mate/peripherals/mouse/cursor_theme", "Gtk/CursorThemeName", MATECONF_VALUE_STRING, translate_string_string }, + { "/desktop/mate/peripherals/mouse/cursor_size", "Gtk/CursorThemeSize", MATECONF_VALUE_INT, translate_int_int }, + { "/desktop/mate/interface/show_input_method_menu", "Gtk/ShowInputMethodMenu", MATECONF_VALUE_BOOL, translate_bool_int }, + { "/desktop/mate/interface/show_unicode_menu", "Gtk/ShowUnicodeMenu", MATECONF_VALUE_BOOL, translate_bool_int }, + { "/desktop/mate/sound/theme_name", "Net/SoundThemeName", MATECONF_VALUE_STRING, translate_string_string }, + { "/desktop/mate/sound/event_sounds", "Net/EnableEventSounds" , MATECONF_VALUE_BOOL, translate_bool_int }, + { "/desktop/mate/sound/input_feedback_sounds", "Net/EnableInputFeedbackSounds", MATECONF_VALUE_BOOL, translate_bool_int } +}; + +#ifdef HAVE_FONTCONFIG +static double +dpi_from_pixels_and_mm (int pixels, + int mm) +{ + double dpi; + + if (mm >= 1) + dpi = pixels / (mm / 25.4); + else + dpi = 0; + + return dpi; +} + +static double +get_dpi_from_x_server (void) +{ + GdkScreen *screen; + double dpi; + + screen = gdk_screen_get_default (); + if (screen != NULL) { + double width_dpi, height_dpi; + + width_dpi = dpi_from_pixels_and_mm (gdk_screen_get_width (screen), gdk_screen_get_width_mm (screen)); + height_dpi = dpi_from_pixels_and_mm (gdk_screen_get_height (screen), gdk_screen_get_height_mm (screen)); + + if (width_dpi < DPI_LOW_REASONABLE_VALUE || width_dpi > DPI_HIGH_REASONABLE_VALUE + || height_dpi < DPI_LOW_REASONABLE_VALUE || height_dpi > DPI_HIGH_REASONABLE_VALUE) { + dpi = DPI_FALLBACK; + } else { + dpi = (width_dpi + height_dpi) / 2.0; + } + } else { + /* Huh!? No screen? */ + + dpi = DPI_FALLBACK; + } + + return dpi; +} + +static double +get_dpi_from_mateconf_or_x_server (MateConfClient *client) +{ + MateConfValue *value; + double dpi; + + value = mateconf_client_get_without_default (client, FONT_DPI_KEY, NULL); + + /* If the user has ever set the DPI preference in MateConf, we use that. + * Otherwise, we see if the X server reports a reasonable DPI value: some X + * servers report completely bogus values, and the user gets huge or tiny + * fonts which are unusable. + */ + + if (value != NULL) { + dpi = mateconf_value_get_float (value); + mateconf_value_free (value); + } else { + dpi = get_dpi_from_x_server (); + } + + return dpi; +} + +typedef struct +{ + gboolean antialias; + gboolean hinting; + int dpi; + const char *rgba; + const char *hintstyle; +} MateXftSettings; + +static const char *rgba_types[] = { "rgb", "bgr", "vbgr", "vrgb" }; + +/* Read MateConf settings and determine the appropriate Xft settings based on them + * This probably could be done a bit more cleanly with mateconf_string_to_enum + */ +static void +xft_settings_get (MateConfClient *client, + MateXftSettings *settings) +{ + char *antialiasing; + char *hinting; + char *rgba_order; + double dpi; + + antialiasing = mateconf_client_get_string (client, FONT_ANTIALIASING_KEY, NULL); + hinting = mateconf_client_get_string (client, FONT_HINTING_KEY, NULL); + rgba_order = mateconf_client_get_string (client, FONT_RGBA_ORDER_KEY, NULL); + dpi = get_dpi_from_mateconf_or_x_server (client); + + settings->antialias = TRUE; + settings->hinting = TRUE; + settings->hintstyle = "hintfull"; + settings->dpi = dpi * 1024; /* Xft wants 1/1024ths of an inch */ + settings->rgba = "rgb"; + + if (rgba_order) { + int i; + gboolean found = FALSE; + + for (i = 0; i < G_N_ELEMENTS (rgba_types) && !found; i++) { + if (strcmp (rgba_order, rgba_types[i]) == 0) { + settings->rgba = rgba_types[i]; + found = TRUE; + } + } + + if (!found) { + g_warning ("Invalid value for " FONT_RGBA_ORDER_KEY ": '%s'", + rgba_order); + } + } + + if (hinting) { + if (strcmp (hinting, "none") == 0) { + settings->hinting = 0; + settings->hintstyle = "hintnone"; + } else if (strcmp (hinting, "slight") == 0) { + settings->hinting = 1; + settings->hintstyle = "hintslight"; + } else if (strcmp (hinting, "medium") == 0) { + settings->hinting = 1; + settings->hintstyle = "hintmedium"; + } else if (strcmp (hinting, "full") == 0) { + settings->hinting = 1; + settings->hintstyle = "hintfull"; + } else { + g_warning ("Invalid value for " FONT_HINTING_KEY ": '%s'", + hinting); + } + } + + if (antialiasing) { + gboolean use_rgba = FALSE; + + if (strcmp (antialiasing, "none") == 0) { + settings->antialias = 0; + } else if (strcmp (antialiasing, "grayscale") == 0) { + settings->antialias = 1; + } else if (strcmp (antialiasing, "rgba") == 0) { + settings->antialias = 1; + use_rgba = TRUE; + } else { + g_warning ("Invalid value for " FONT_ANTIALIASING_KEY " : '%s'", + antialiasing); + } + + if (!use_rgba) { + settings->rgba = "none"; + } + } + + g_free (rgba_order); + g_free (hinting); + g_free (antialiasing); +} + +static void +xft_settings_set_xsettings (MateXSettingsManager *manager, + MateXftSettings *settings) +{ + int i; + + mate_settings_profile_start (NULL); + + for (i = 0; manager->priv->managers [i]; i++) { + xsettings_manager_set_int (manager->priv->managers [i], "Xft/Antialias", settings->antialias); + xsettings_manager_set_int (manager->priv->managers [i], "Xft/Hinting", settings->hinting); + xsettings_manager_set_string (manager->priv->managers [i], "Xft/HintStyle", settings->hintstyle); + xsettings_manager_set_int (manager->priv->managers [i], "Xft/DPI", settings->dpi); + xsettings_manager_set_string (manager->priv->managers [i], "Xft/RGBA", settings->rgba); + } + mate_settings_profile_end (NULL); +} + +static void +update_property (GString *props, const gchar* key, const gchar* value) +{ + gchar* needle; + size_t needle_len; + gchar* found = NULL; + + /* update an existing property */ + needle = g_strconcat (key, ":", NULL); + needle_len = strlen (needle); + if (g_str_has_prefix (props->str, needle)) + found = props->str; + else + found = strstr (props->str, needle); + + if (found) { + size_t value_index; + gchar* end; + + end = strchr (found, '\n'); + value_index = (found - props->str) + needle_len + 1; + g_string_erase (props, value_index, end ? (end - found - needle_len) : -1); + g_string_insert (props, value_index, "\n"); + g_string_insert (props, value_index, value); + } else { + g_string_append_printf (props, "%s:\t%s\n", key, value); + } +} + +static void +xft_settings_set_xresources (MateXftSettings *settings) +{ + GString *add_string; + char dpibuf[G_ASCII_DTOSTR_BUF_SIZE]; + Display *dpy; + + mate_settings_profile_start (NULL); + + /* get existing properties */ + dpy = XOpenDisplay (NULL); + g_return_if_fail (dpy != NULL); + add_string = g_string_new (XResourceManagerString (dpy)); + + g_debug("xft_settings_set_xresources: orig res '%s'", add_string->str); + + update_property (add_string, "Xft.dpi", + g_ascii_dtostr (dpibuf, sizeof (dpibuf), (double) settings->dpi / 1024.0)); + update_property (add_string, "Xft.antialias", + settings->antialias ? "1" : "0"); + update_property (add_string, "Xft.hinting", + settings->hinting ? "1" : "0"); + update_property (add_string, "Xft.hintstyle", + settings->hintstyle); + update_property (add_string, "Xft.rgba", + settings->rgba); + + g_debug("xft_settings_set_xresources: new res '%s'", add_string->str); + + /* Set the new X property */ + XChangeProperty(dpy, RootWindow (dpy, 0), + XA_RESOURCE_MANAGER, XA_STRING, 8, PropModeReplace, add_string->str, add_string->len); + XCloseDisplay (dpy); + + g_string_free (add_string, TRUE); + + mate_settings_profile_end (NULL); +} + +/* We mirror the Xft properties both through XSETTINGS and through + * X resources + */ +static void +update_xft_settings (MateXSettingsManager *manager, + MateConfClient *client) +{ + MateXftSettings settings; + + mate_settings_profile_start (NULL); + + xft_settings_get (client, &settings); + xft_settings_set_xsettings (manager, &settings); + xft_settings_set_xresources (&settings); + + mate_settings_profile_end (NULL); +} + +static void +xft_callback (MateConfClient *client, + guint cnxn_id, + MateConfEntry *entry, + MateXSettingsManager *manager) +{ + int i; + + update_xft_settings (manager, client); + + for (i = 0; manager->priv->managers [i]; i++) { + xsettings_manager_notify (manager->priv->managers [i]); + } +} + +static void +fontconfig_callback (fontconfig_monitor_handle_t *handle, + MateXSettingsManager *manager) +{ + int i; + int timestamp = time (NULL); + + mate_settings_profile_start (NULL); + + for (i = 0; manager->priv->managers [i]; i++) { + xsettings_manager_set_int (manager->priv->managers [i], "Fontconfig/Timestamp", timestamp); + xsettings_manager_notify (manager->priv->managers [i]); + } + mate_settings_profile_end (NULL); +} + +static gboolean +start_fontconfig_monitor_idle_cb (MateXSettingsManager *manager) +{ + mate_settings_profile_start (NULL); + + manager->priv->fontconfig_handle = fontconfig_monitor_start ((GFunc) fontconfig_callback, manager); + + mate_settings_profile_end (NULL); + + return FALSE; +} + +static void +start_fontconfig_monitor (MateXSettingsManager *manager) +{ + mate_settings_profile_start (NULL); + + fontconfig_cache_init (); + + g_idle_add ((GSourceFunc) start_fontconfig_monitor_idle_cb, manager); + + mate_settings_profile_end (NULL); +} + +static void +stop_fontconfig_monitor (MateXSettingsManager *manager) +{ + if (manager->priv->fontconfig_handle) { + fontconfig_monitor_stop (manager->priv->fontconfig_handle); + manager->priv->fontconfig_handle = NULL; + } +} +#endif /* HAVE_FONTCONFIG */ + +static const char * +type_to_string (MateConfValueType type) +{ + switch (type) { + case MATECONF_VALUE_INT: + return "int"; + case MATECONF_VALUE_STRING: + return "string"; + case MATECONF_VALUE_FLOAT: + return "float"; + case MATECONF_VALUE_BOOL: + return "bool"; + case MATECONF_VALUE_SCHEMA: + return "schema"; + case MATECONF_VALUE_LIST: + return "list"; + case MATECONF_VALUE_PAIR: + return "pair"; + case MATECONF_VALUE_INVALID: + return "*invalid*"; + default: + g_assert_not_reached(); + return NULL; /* for warnings */ + } +} + +static void +process_value (MateXSettingsManager *manager, + TranslationEntry *trans, + MateConfValue *val) +{ + if (val == NULL) { + int i; + + for (i = 0; manager->priv->managers [i]; i++) { + xsettings_manager_delete_setting (manager->priv->managers [i], trans->xsetting_name); + } + } else { + if (val->type == trans->mateconf_type) { + (* trans->translate) (manager, trans, val); + } else { + g_warning (_("MateConf key %s set to type %s but its expected type was %s\n"), + trans->mateconf_key, + type_to_string (val->type), + type_to_string (trans->mateconf_type)); + } + } +} + +static TranslationEntry * +find_translation_entry (const char *mateconf_key) +{ + int i; + + for (i = 0; i < G_N_ELEMENTS (translations); ++i) { + if (strcmp (translations[i].mateconf_key, mateconf_key) == 0) { + return &translations[i]; + } + } + + return NULL; +} + +static void +xsettings_callback (MateConfClient *client, + guint cnxn_id, + MateConfEntry *entry, + MateXSettingsManager *manager) +{ + TranslationEntry *trans; + int i; + + trans = find_translation_entry (entry->key); + if (trans == NULL) { + return; + } + + process_value (manager, trans, entry->value); + + for (i = 0; manager->priv->managers [i]; i++) { + xsettings_manager_set_string (manager->priv->managers [i], + "Net/FallbackIconTheme", + "mate"); + } + + for (i = 0; manager->priv->managers [i]; i++) { + xsettings_manager_notify (manager->priv->managers [i]); + } +} + +static gchar * +get_gtk_modules (MateConfClient *client) +{ + GSList *entries, *l; + GString *mods = g_string_new (NULL); + + entries = mateconf_client_all_entries (client, GTK_MODULES_DIR, NULL); + + for (l = entries; l != NULL; l = g_slist_next (l)) { + MateConfEntry *e = l->data; + MateConfValue *v = mateconf_entry_get_value (e); + + if (v != NULL) { + gboolean enabled = FALSE; + const gchar *key; + + switch (v->type) { + case MATECONF_VALUE_BOOL: + /* simple enabled/disabled */ + enabled = mateconf_value_get_bool (v); + break; + + /* due to limitations in MateConf (or the client libraries, + * anyway), it is currently impossible to monitor + * arbitrary keys for changes, so these won't update at + * runtime */ + case MATECONF_VALUE_STRING: + /* linked to another MateConf key of type bool */ + key = mateconf_value_get_string (v); + if (key != NULL && mateconf_valid_key (key, NULL)) { + enabled = mateconf_client_get_bool (client, key, NULL); + } + break; + + default: + g_warning ("MateConf entry %s has invalid type %s", + mateconf_entry_get_key (e), type_to_string (v->type)); + } + + if (enabled) { + const gchar *name; + name = strrchr (mateconf_entry_get_key (e), '/') + 1; + + if (mods->len > 0) { + g_string_append_c (mods, ':'); + } + g_string_append (mods, name); + } + } + + mateconf_entry_free (e); + } + + g_slist_free (entries); + + return g_string_free (mods, mods->len == 0); +} + +static void +gtk_modules_callback (MateConfClient *client, + guint cnxn_id, + MateConfEntry *entry, + MateXSettingsManager *manager) +{ + gchar *modules = get_gtk_modules (client); + int i; + + if (modules == NULL) { + for (i = 0; manager->priv->managers [i]; ++i) { + xsettings_manager_delete_setting (manager->priv->managers [i], "Gtk/Modules"); + } + } else { + g_debug ("Setting GTK modules '%s'", modules); + for (i = 0; manager->priv->managers [i]; ++i) { + xsettings_manager_set_string (manager->priv->managers [i], + "Gtk/Modules", + modules); + } + g_free (modules); + } + + for (i = 0; manager->priv->managers [i]; ++i) { + xsettings_manager_notify (manager->priv->managers [i]); + } +} + +static guint +register_config_callback (MateXSettingsManager *manager, + MateConfClient *client, + const char *path, + MateConfClientNotifyFunc func) +{ + return mateconf_client_notify_add (client, path, func, manager, NULL, NULL); +} + +static void +terminate_cb (void *data) +{ + gboolean *terminated = data; + + if (*terminated) { + return; + } + + *terminated = TRUE; + + gtk_main_quit (); +} + +static gboolean +setup_xsettings_managers (MateXSettingsManager *manager) +{ + GdkDisplay *display; + int i; + int n_screens; + gboolean res; + gboolean terminated; + + display = gdk_display_get_default (); + n_screens = gdk_display_get_n_screens (display); + + res = xsettings_manager_check_running (gdk_x11_display_get_xdisplay (display), + gdk_screen_get_number (gdk_screen_get_default ())); + if (res) { + g_warning ("You can only run one xsettings manager at a time; exiting"); + return FALSE; + } + + manager->priv->managers = g_new0 (XSettingsManager *, n_screens + 1); + + terminated = FALSE; + for (i = 0; i < n_screens; i++) { + GdkScreen *screen; + + screen = gdk_display_get_screen (display, i); + + manager->priv->managers [i] = xsettings_manager_new (gdk_x11_display_get_xdisplay (display), + gdk_screen_get_number (screen), + terminate_cb, + &terminated); + if (! manager->priv->managers [i]) { + g_warning ("Could not create xsettings manager for screen %d!", i); + return FALSE; + } + } + + return TRUE; +} + +gboolean +mate_xsettings_manager_start (MateXSettingsManager *manager, + GError **error) +{ + MateConfClient *client; + int i; + + g_debug ("Starting xsettings manager"); + mate_settings_profile_start (NULL); + + if (!setup_xsettings_managers (manager)) { + g_set_error (error, GSD_XSETTINGS_ERROR, + GSD_XSETTINGS_ERROR_INIT, + "Could not initialize xsettings manager."); + return FALSE; + } + + client = mateconf_client_get_default (); + + mateconf_client_add_dir (client, MOUSE_SETTINGS_DIR, MATECONF_CLIENT_PRELOAD_ONELEVEL, NULL); + mateconf_client_add_dir (client, GTK_SETTINGS_DIR, MATECONF_CLIENT_PRELOAD_ONELEVEL, NULL); + mateconf_client_add_dir (client, INTERFACE_SETTINGS_DIR, MATECONF_CLIENT_PRELOAD_ONELEVEL, NULL); + mateconf_client_add_dir (client, SOUND_SETTINGS_DIR, MATECONF_CLIENT_PRELOAD_ONELEVEL, NULL); + mateconf_client_add_dir (client, GTK_MODULES_DIR, MATECONF_CLIENT_PRELOAD_ONELEVEL, NULL); + mateconf_client_add_dir (client, FONT_RENDER_DIR, MATECONF_CLIENT_PRELOAD_ONELEVEL, NULL); + + for (i = 0; i < G_N_ELEMENTS (translations); i++) { + MateConfValue *val; + GError *err; + + err = NULL; + val = mateconf_client_get (client, + translations[i].mateconf_key, + &err); + + if (err != NULL) { + g_warning ("Error getting value for %s: %s", + translations[i].mateconf_key, + err->message); + g_error_free (err); + } else { + process_value (manager, &translations[i], val); + if (val != NULL) { + mateconf_value_free (val); + } + } + } + + manager->priv->notify[0] = + register_config_callback (manager, client, + MOUSE_SETTINGS_DIR, + (MateConfClientNotifyFunc) xsettings_callback); + manager->priv->notify[1] = + register_config_callback (manager, client, + GTK_SETTINGS_DIR, + (MateConfClientNotifyFunc) xsettings_callback); + manager->priv->notify[2] = + register_config_callback (manager, client, + INTERFACE_SETTINGS_DIR, + (MateConfClientNotifyFunc) xsettings_callback); + manager->priv->notify[3] = + register_config_callback (manager, client, + SOUND_SETTINGS_DIR, + (MateConfClientNotifyFunc) xsettings_callback); + + manager->priv->notify[4] = + register_config_callback (manager, client, + GTK_MODULES_DIR, + (MateConfClientNotifyFunc) gtk_modules_callback); + gtk_modules_callback (client, 0, NULL, manager); + +#ifdef HAVE_FONTCONFIG + manager->priv->notify[5] = + register_config_callback (manager, client, + FONT_RENDER_DIR, + (MateConfClientNotifyFunc) xft_callback); + update_xft_settings (manager, client); + + start_fontconfig_monitor (manager); +#endif /* HAVE_FONTCONFIG */ + + g_object_unref (client); + + for (i = 0; manager->priv->managers [i]; i++) + xsettings_manager_set_string (manager->priv->managers [i], + "Net/FallbackIconTheme", + "mate"); + + for (i = 0; manager->priv->managers [i]; i++) { + xsettings_manager_notify (manager->priv->managers [i]); + } + + + mate_settings_profile_end (NULL); + + return TRUE; +} + +void +mate_xsettings_manager_stop (MateXSettingsManager *manager) +{ + MateXSettingsManagerPrivate *p = manager->priv; + MateConfClient *client; + int i; + + g_debug ("Stopping xsettings manager"); + + if (p->managers != NULL) { + for (i = 0; p->managers [i]; ++i) + xsettings_manager_destroy (p->managers [i]); + + g_free (p->managers); + p->managers = NULL; + } + + client = mateconf_client_get_default (); + + mateconf_client_remove_dir (client, MOUSE_SETTINGS_DIR, NULL); + mateconf_client_remove_dir (client, GTK_SETTINGS_DIR, NULL); + mateconf_client_remove_dir (client, INTERFACE_SETTINGS_DIR, NULL); + mateconf_client_remove_dir (client, SOUND_SETTINGS_DIR, NULL); + mateconf_client_remove_dir (client, GTK_MODULES_DIR, NULL); +#ifdef HAVE_FONTCONFIG + mateconf_client_remove_dir (client, FONT_RENDER_DIR, NULL); + + stop_fontconfig_monitor (manager); +#endif /* HAVE_FONTCONFIG */ + + for (i = 0; i < G_N_ELEMENTS (p->notify); ++i) { + if (p->notify[i] != 0) { + mateconf_client_notify_remove (client, p->notify[i]); + p->notify[i] = 0; + } + } + + g_object_unref (client); +} + +static void +mate_xsettings_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MateXSettingsManager *self; + + self = MATE_XSETTINGS_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +mate_xsettings_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MateXSettingsManager *self; + + self = MATE_XSETTINGS_MANAGER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +mate_xsettings_manager_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + MateXSettingsManager *xsettings_manager; + MateXSettingsManagerClass *klass; + + klass = MATE_XSETTINGS_MANAGER_CLASS (g_type_class_peek (MATE_TYPE_XSETTINGS_MANAGER)); + + xsettings_manager = MATE_XSETTINGS_MANAGER (G_OBJECT_CLASS (mate_xsettings_manager_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + + return G_OBJECT (xsettings_manager); +} + +static void +mate_xsettings_manager_dispose (GObject *object) +{ + MateXSettingsManager *xsettings_manager; + + xsettings_manager = MATE_XSETTINGS_MANAGER (object); + + G_OBJECT_CLASS (mate_xsettings_manager_parent_class)->dispose (object); +} + +static void +mate_xsettings_manager_class_init (MateXSettingsManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = mate_xsettings_manager_get_property; + object_class->set_property = mate_xsettings_manager_set_property; + object_class->constructor = mate_xsettings_manager_constructor; + object_class->dispose = mate_xsettings_manager_dispose; + object_class->finalize = mate_xsettings_manager_finalize; + + g_type_class_add_private (klass, sizeof (MateXSettingsManagerPrivate)); +} + +static void +mate_xsettings_manager_init (MateXSettingsManager *manager) +{ + manager->priv = MATE_XSETTINGS_MANAGER_GET_PRIVATE (manager); +} + +static void +mate_xsettings_manager_finalize (GObject *object) +{ + MateXSettingsManager *xsettings_manager; + + g_return_if_fail (object != NULL); + g_return_if_fail (MATE_IS_XSETTINGS_MANAGER (object)); + + xsettings_manager = MATE_XSETTINGS_MANAGER (object); + + g_return_if_fail (xsettings_manager->priv != NULL); + + G_OBJECT_CLASS (mate_xsettings_manager_parent_class)->finalize (object); +} + +MateXSettingsManager * +mate_xsettings_manager_new (void) +{ + if (manager_object != NULL) { + g_object_ref (manager_object); + } else { + manager_object = g_object_new (MATE_TYPE_XSETTINGS_MANAGER, NULL); + g_object_add_weak_pointer (manager_object, + (gpointer *) &manager_object); + } + + return MATE_XSETTINGS_MANAGER (manager_object); +} diff --git a/plugins/xsettings/gsd-xsettings-manager.h b/plugins/xsettings/gsd-xsettings-manager.h new file mode 100644 index 0000000..b97afbf --- /dev/null +++ b/plugins/xsettings/gsd-xsettings-manager.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann <[email protected]> + * + * 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 __MATE_XSETTINGS_MANAGER_H +#define __MATE_XSETTINGS_MANAGER_H + +#include <glib-object.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define MATE_TYPE_XSETTINGS_MANAGER (mate_xsettings_manager_get_type ()) +#define MATE_XSETTINGS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_TYPE_XSETTINGS_MANAGER, MateXSettingsManager)) +#define MATE_XSETTINGS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), MATE_TYPE_XSETTINGS_MANAGER, MateXSettingsManagerClass)) +#define MATE_IS_XSETTINGS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_TYPE_XSETTINGS_MANAGER)) +#define MATE_IS_XSETTINGS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), MATE_TYPE_XSETTINGS_MANAGER)) +#define MATE_XSETTINGS_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_TYPE_XSETTINGS_MANAGER, MateXSettingsManagerClass)) + +typedef struct MateXSettingsManagerPrivate MateXSettingsManagerPrivate; + +typedef struct +{ + GObject parent; + MateXSettingsManagerPrivate *priv; +} MateXSettingsManager; + +typedef struct +{ + GObjectClass parent_class; +} MateXSettingsManagerClass; + +GType mate_xsettings_manager_get_type (void); + +MateXSettingsManager * mate_xsettings_manager_new (void); +gboolean mate_xsettings_manager_start (MateXSettingsManager *manager, + GError **error); +void mate_xsettings_manager_stop (MateXSettingsManager *manager); + +#ifdef __cplusplus +} +#endif + +#endif /* __MATE_XSETTINGS_MANAGER_H */ diff --git a/plugins/xsettings/gsd-xsettings-plugin.c b/plugins/xsettings/gsd-xsettings-plugin.c new file mode 100644 index 0000000..2280589 --- /dev/null +++ b/plugins/xsettings/gsd-xsettings-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 <[email protected]> + * + * 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 <glib/gi18n-lib.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" +#include "gsd-xsettings-plugin.h" +#include "gsd-xsettings-manager.h" + +struct MateXSettingsPluginPrivate { + MateXSettingsManager *manager; +}; + +#define MATE_XSETTINGS_PLUGIN_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), MATE_TYPE_XSETTINGS_PLUGIN, MateXSettingsPluginPrivate)) + +MATE_SETTINGS_PLUGIN_REGISTER (MateXSettingsPlugin, mate_xsettings_plugin) + +static void +mate_xsettings_plugin_init (MateXSettingsPlugin *plugin) +{ + plugin->priv = MATE_XSETTINGS_PLUGIN_GET_PRIVATE (plugin); + + g_debug ("MateXSettingsPlugin initializing"); + + plugin->priv->manager = mate_xsettings_manager_new (); +} + +static void +mate_xsettings_plugin_finalize (GObject *object) +{ + MateXSettingsPlugin *plugin; + + g_return_if_fail (object != NULL); + g_return_if_fail (MATE_IS_XSETTINGS_PLUGIN (object)); + + g_debug ("MateXSettingsPlugin finalizing"); + + plugin = MATE_XSETTINGS_PLUGIN (object); + + g_return_if_fail (plugin->priv != NULL); + + if (plugin->priv->manager != NULL) { + g_object_unref (plugin->priv->manager); + } + + G_OBJECT_CLASS (mate_xsettings_plugin_parent_class)->finalize (object); +} + +static void +impl_activate (MateSettingsPlugin *plugin) +{ + gboolean res; + GError *error; + + g_debug ("Activating xsettings plugin"); + + error = NULL; + res = mate_xsettings_manager_start (MATE_XSETTINGS_PLUGIN (plugin)->priv->manager, &error); + if (! res) { + g_warning ("Unable to start xsettings manager: %s", error->message); + g_error_free (error); + } +} + +static void +impl_deactivate (MateSettingsPlugin *plugin) +{ + g_debug ("Deactivating xsettings plugin"); + mate_xsettings_manager_stop (MATE_XSETTINGS_PLUGIN (plugin)->priv->manager); +} + +static void +mate_xsettings_plugin_class_init (MateXSettingsPluginClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MateSettingsPluginClass *plugin_class = MATE_SETTINGS_PLUGIN_CLASS (klass); + + object_class->finalize = mate_xsettings_plugin_finalize; + + plugin_class->activate = impl_activate; + plugin_class->deactivate = impl_deactivate; + + g_type_class_add_private (klass, sizeof (MateXSettingsPluginPrivate)); +} diff --git a/plugins/xsettings/gsd-xsettings-plugin.h b/plugins/xsettings/gsd-xsettings-plugin.h new file mode 100644 index 0000000..88c8331 --- /dev/null +++ b/plugins/xsettings/gsd-xsettings-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 <[email protected]> + * + * 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 __MATE_XSETTINGS_PLUGIN_H__ +#define __MATE_XSETTINGS_PLUGIN_H__ + +#include <glib.h> +#include <glib-object.h> +#include <gmodule.h> + +#include "mate-settings-plugin.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MATE_TYPE_XSETTINGS_PLUGIN (mate_xsettings_plugin_get_type ()) +#define MATE_XSETTINGS_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_TYPE_XSETTINGS_PLUGIN, MateXSettingsPlugin)) +#define MATE_XSETTINGS_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), MATE_TYPE_XSETTINGS_PLUGIN, MateXSettingsPluginClass)) +#define MATE_IS_XSETTINGS_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_TYPE_XSETTINGS_PLUGIN)) +#define MATE_IS_XSETTINGS_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), MATE_TYPE_XSETTINGS_PLUGIN)) +#define MATE_XSETTINGS_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_TYPE_XSETTINGS_PLUGIN, MateXSettingsPluginClass)) + +typedef struct MateXSettingsPluginPrivate MateXSettingsPluginPrivate; + +typedef struct +{ + MateSettingsPlugin parent; + MateXSettingsPluginPrivate *priv; +} MateXSettingsPlugin; + +typedef struct +{ + MateSettingsPluginClass parent_class; +} MateXSettingsPluginClass; + +GType mate_xsettings_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 /* __MATE_XSETTINGS_PLUGIN_H__ */ diff --git a/plugins/xsettings/xsettings-common.c b/plugins/xsettings/xsettings-common.c new file mode 100644 index 0000000..992175a --- /dev/null +++ b/plugins/xsettings/xsettings-common.c @@ -0,0 +1,264 @@ +/* + * Copyright © 2001 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Owen Taylor, Red Hat, Inc. + */ +#include "string.h" +#include "stdlib.h" + +#include <X11/Xlib.h> +#include <X11/Xmd.h> /* For CARD32 */ + +#include "xsettings-common.h" + +XSettingsSetting * +xsettings_setting_copy (XSettingsSetting *setting) +{ + XSettingsSetting *result; + size_t str_len; + + result = malloc (sizeof *result); + if (!result) + return NULL; + + str_len = strlen (setting->name); + result->name = malloc (str_len + 1); + if (!result->name) + goto err; + + memcpy (result->name, setting->name, str_len + 1); + + result->type = setting->type; + + switch (setting->type) + { + case XSETTINGS_TYPE_INT: + result->data.v_int = setting->data.v_int; + break; + case XSETTINGS_TYPE_COLOR: + result->data.v_color = setting->data.v_color; + break; + case XSETTINGS_TYPE_STRING: + str_len = strlen (setting->data.v_string); + result->data.v_string = malloc (str_len + 1); + if (!result->data.v_string) + goto err; + + memcpy (result->data.v_string, setting->data.v_string, str_len + 1); + break; + } + + result->last_change_serial = setting->last_change_serial; + + return result; + + err: + if (result->name) + free (result->name); + free (result); + + return NULL; +} + +XSettingsList * +xsettings_list_copy (XSettingsList *list) +{ + XSettingsList *new = NULL; + XSettingsList *old_iter = list; + XSettingsList *new_iter = NULL; + + while (old_iter) + { + XSettingsList *new_node; + + new_node = malloc (sizeof *new_node); + if (!new_node) + goto error; + + new_node->setting = xsettings_setting_copy (old_iter->setting); + if (!new_node->setting) + { + free (new_node); + goto error; + } + + if (new_iter) + new_iter->next = new_node; + else + new = new_node; + + new_iter = new_node; + + old_iter = old_iter->next; + } + + return new; + + error: + xsettings_list_free (new); + return NULL; +} + +int +xsettings_setting_equal (XSettingsSetting *setting_a, + XSettingsSetting *setting_b) +{ + if (setting_a->type != setting_b->type) + return 0; + + if (strcmp (setting_a->name, setting_b->name) != 0) + return 0; + + switch (setting_a->type) + { + case XSETTINGS_TYPE_INT: + return setting_a->data.v_int == setting_b->data.v_int; + case XSETTINGS_TYPE_COLOR: + return (setting_a->data.v_color.red == setting_b->data.v_color.red && + setting_a->data.v_color.green == setting_b->data.v_color.green && + setting_a->data.v_color.blue == setting_b->data.v_color.blue && + setting_a->data.v_color.alpha == setting_b->data.v_color.alpha); + case XSETTINGS_TYPE_STRING: + return strcmp (setting_a->data.v_string, setting_b->data.v_string) == 0; + } + + return 0; +} + +void +xsettings_setting_free (XSettingsSetting *setting) +{ + if (setting->type == XSETTINGS_TYPE_STRING) + free (setting->data.v_string); + + if (setting->name) + free (setting->name); + + free (setting); +} + +void +xsettings_list_free (XSettingsList *list) +{ + while (list) + { + XSettingsList *next = list->next; + + xsettings_setting_free (list->setting); + free (list); + + list = next; + } +} + +XSettingsResult +xsettings_list_insert (XSettingsList **list, + XSettingsSetting *setting) +{ + XSettingsList *node; + XSettingsList *iter; + XSettingsList *last = NULL; + + node = malloc (sizeof *node); + if (!node) + return XSETTINGS_NO_MEM; + node->setting = setting; + + iter = *list; + while (iter) + { + int cmp = strcmp (setting->name, iter->setting->name); + + if (cmp < 0) + break; + else if (cmp == 0) + { + free (node); + return XSETTINGS_DUPLICATE_ENTRY; + } + + last = iter; + iter = iter->next; + } + + if (last) + last->next = node; + else + *list = node; + + node->next = iter; + + return XSETTINGS_SUCCESS; +} + +XSettingsResult +xsettings_list_delete (XSettingsList **list, + const char *name) +{ + XSettingsList *iter; + XSettingsList *last = NULL; + + iter = *list; + while (iter) + { + if (strcmp (name, iter->setting->name) == 0) + { + if (last) + last->next = iter->next; + else + *list = iter->next; + + xsettings_setting_free (iter->setting); + free (iter); + + return XSETTINGS_SUCCESS; + } + + last = iter; + iter = iter->next; + } + + return XSETTINGS_FAILED; +} + +XSettingsSetting * +xsettings_list_lookup (XSettingsList *list, + const char *name) +{ + XSettingsList *iter; + + iter = list; + while (iter) + { + if (strcmp (name, iter->setting->name) == 0) + return iter->setting; + + iter = iter->next; + } + + return NULL; +} + +char +xsettings_byte_order (void) +{ + CARD32 myint = 0x01020304; + return (*(char *)&myint == 1) ? MSBFirst : LSBFirst; +} diff --git a/plugins/xsettings/xsettings-common.h b/plugins/xsettings/xsettings-common.h new file mode 100644 index 0000000..e3af4a6 --- /dev/null +++ b/plugins/xsettings/xsettings-common.h @@ -0,0 +1,110 @@ +/* + * Copyright © 2001 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Owen Taylor, Red Hat, Inc. + */ +#ifndef XSETTINGS_COMMON_H +#define XSETTINGS_COMMON_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct _XSettingsBuffer XSettingsBuffer; +typedef struct _XSettingsColor XSettingsColor; +typedef struct _XSettingsList XSettingsList; +typedef struct _XSettingsSetting XSettingsSetting; + +/* Types of settings possible. Enum values correspond to + * protocol values. + */ +typedef enum +{ + XSETTINGS_TYPE_INT = 0, + XSETTINGS_TYPE_STRING = 1, + XSETTINGS_TYPE_COLOR = 2 +} XSettingsType; + +typedef enum +{ + XSETTINGS_SUCCESS, + XSETTINGS_NO_MEM, + XSETTINGS_ACCESS, + XSETTINGS_FAILED, + XSETTINGS_NO_ENTRY, + XSETTINGS_DUPLICATE_ENTRY +} XSettingsResult; + +struct _XSettingsBuffer +{ + char byte_order; + size_t len; + unsigned char *data; + unsigned char *pos; +}; + +struct _XSettingsColor +{ + unsigned short red, green, blue, alpha; +}; + +struct _XSettingsList +{ + XSettingsSetting *setting; + XSettingsList *next; +}; + +struct _XSettingsSetting +{ + char *name; + XSettingsType type; + + union { + int v_int; + char *v_string; + XSettingsColor v_color; + } data; + + unsigned long last_change_serial; +}; + +XSettingsSetting *xsettings_setting_copy (XSettingsSetting *setting); +void xsettings_setting_free (XSettingsSetting *setting); +int xsettings_setting_equal (XSettingsSetting *setting_a, + XSettingsSetting *setting_b); + +void xsettings_list_free (XSettingsList *list); +XSettingsList *xsettings_list_copy (XSettingsList *list); +XSettingsResult xsettings_list_insert (XSettingsList **list, + XSettingsSetting *setting); +XSettingsSetting *xsettings_list_lookup (XSettingsList *list, + const char *name); +XSettingsResult xsettings_list_delete (XSettingsList **list, + const char *name); + +char xsettings_byte_order (void); + +#define XSETTINGS_PAD(n,m) ((n + m - 1) & (~(m-1))) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XSETTINGS_COMMON_H */ diff --git a/plugins/xsettings/xsettings-manager.c b/plugins/xsettings/xsettings-manager.c new file mode 100644 index 0000000..6578ce1 --- /dev/null +++ b/plugins/xsettings/xsettings-manager.c @@ -0,0 +1,424 @@ +/* + * Copyright © 2001 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Owen Taylor, Red Hat, Inc. + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <X11/Xmd.h> /* For CARD16 */ + +#include "xsettings-manager.h" + +struct _XSettingsManager +{ + Display *display; + int screen; + + Window window; + Atom manager_atom; + Atom selection_atom; + Atom xsettings_atom; + + XSettingsTerminateFunc terminate; + void *cb_data; + + XSettingsList *settings; + unsigned long serial; +}; + +static XSettingsList *settings; + +typedef struct +{ + Window window; + Atom timestamp_prop_atom; +} TimeStampInfo; + +static Bool +timestamp_predicate (Display *display, + XEvent *xevent, + XPointer arg) +{ + TimeStampInfo *info = (TimeStampInfo *)arg; + + if (xevent->type == PropertyNotify && + xevent->xproperty.window == info->window && + xevent->xproperty.atom == info->timestamp_prop_atom) + return True; + + return False; +} + +/** + * get_server_time: + * @display: display from which to get the time + * @window: a #Window, used for communication with the server. + * The window must have PropertyChangeMask in its + * events mask or a hang will result. + * + * Routine to get the current X server time stamp. + * + * Return value: the time stamp. + **/ +static Time +get_server_time (Display *display, + Window window) +{ + unsigned char c = 'a'; + XEvent xevent; + TimeStampInfo info; + + info.timestamp_prop_atom = XInternAtom (display, "_TIMESTAMP_PROP", False); + info.window = window; + + XChangeProperty (display, window, + info.timestamp_prop_atom, info.timestamp_prop_atom, + 8, PropModeReplace, &c, 1); + + XIfEvent (display, &xevent, + timestamp_predicate, (XPointer)&info); + + return xevent.xproperty.time; +} + +Bool +xsettings_manager_check_running (Display *display, + int screen) +{ + char buffer[256]; + Atom selection_atom; + + sprintf(buffer, "_XSETTINGS_S%d", screen); + selection_atom = XInternAtom (display, buffer, False); + + if (XGetSelectionOwner (display, selection_atom)) + return True; + else + return False; +} + +XSettingsManager * +xsettings_manager_new (Display *display, + int screen, + XSettingsTerminateFunc terminate, + void *cb_data) +{ + XSettingsManager *manager; + Time timestamp; + XClientMessageEvent xev; + + char buffer[256]; + + manager = malloc (sizeof *manager); + if (!manager) + return NULL; + + manager->display = display; + manager->screen = screen; + + sprintf(buffer, "_XSETTINGS_S%d", screen); + manager->selection_atom = XInternAtom (display, buffer, False); + manager->xsettings_atom = XInternAtom (display, "_XSETTINGS_SETTINGS", False); + manager->manager_atom = XInternAtom (display, "MANAGER", False); + + manager->terminate = terminate; + manager->cb_data = cb_data; + + manager->settings = NULL; + manager->serial = 0; + + manager->window = XCreateSimpleWindow (display, + RootWindow (display, screen), + 0, 0, 10, 10, 0, + WhitePixel (display, screen), + WhitePixel (display, screen)); + + XSelectInput (display, manager->window, PropertyChangeMask); + timestamp = get_server_time (display, manager->window); + + XSetSelectionOwner (display, manager->selection_atom, + manager->window, timestamp); + + /* Check to see if we managed to claim the selection. If not, + * we treat it as if we got it then immediately lost it + */ + + if (XGetSelectionOwner (display, manager->selection_atom) == + manager->window) + { + xev.type = ClientMessage; + xev.window = RootWindow (display, screen); + xev.message_type = manager->manager_atom; + xev.format = 32; + xev.data.l[0] = timestamp; + xev.data.l[1] = manager->selection_atom; + xev.data.l[2] = manager->window; + xev.data.l[3] = 0; /* manager specific data */ + xev.data.l[4] = 0; /* manager specific data */ + + XSendEvent (display, RootWindow (display, screen), + False, StructureNotifyMask, (XEvent *)&xev); + } + else + { + manager->terminate (manager->cb_data); + } + + return manager; +} + +void +xsettings_manager_destroy (XSettingsManager *manager) +{ + XDestroyWindow (manager->display, manager->window); + + xsettings_list_free (manager->settings); + free (manager); +} + +Window +xsettings_manager_get_window (XSettingsManager *manager) +{ + return manager->window; +} + +Bool +xsettings_manager_process_event (XSettingsManager *manager, + XEvent *xev) +{ + if (xev->xany.window == manager->window && + xev->xany.type == SelectionClear && + xev->xselectionclear.selection == manager->selection_atom) + { + manager->terminate (manager->cb_data); + return True; + } + + return False; +} + +XSettingsResult +xsettings_manager_delete_setting (XSettingsManager *manager, + const char *name) +{ + return xsettings_list_delete (&settings, name); +} + +XSettingsResult +xsettings_manager_set_setting (XSettingsManager *manager, + XSettingsSetting *setting) +{ + XSettingsSetting *old_setting = xsettings_list_lookup (settings, setting->name); + XSettingsSetting *new_setting; + XSettingsResult result; + + if (old_setting) + { + if (xsettings_setting_equal (old_setting, setting)) + return XSETTINGS_SUCCESS; + + xsettings_list_delete (&settings, setting->name); + } + + new_setting = xsettings_setting_copy (setting); + if (!new_setting) + return XSETTINGS_NO_MEM; + + new_setting->last_change_serial = manager->serial; + + result = xsettings_list_insert (&settings, new_setting); + + if (result != XSETTINGS_SUCCESS) + xsettings_setting_free (new_setting); + + return result; +} + +XSettingsResult +xsettings_manager_set_int (XSettingsManager *manager, + const char *name, + int value) +{ + XSettingsSetting setting; + + setting.name = (char *)name; + setting.type = XSETTINGS_TYPE_INT; + setting.data.v_int = value; + + return xsettings_manager_set_setting (manager, &setting); +} + +XSettingsResult +xsettings_manager_set_string (XSettingsManager *manager, + const char *name, + const char *value) +{ + XSettingsSetting setting; + + setting.name = (char *)name; + setting.type = XSETTINGS_TYPE_STRING; + setting.data.v_string = (char *)value; + + return xsettings_manager_set_setting (manager, &setting); +} + +XSettingsResult +xsettings_manager_set_color (XSettingsManager *manager, + const char *name, + XSettingsColor *value) +{ + XSettingsSetting setting; + + setting.name = (char *)name; + setting.type = XSETTINGS_TYPE_COLOR; + setting.data.v_color = *value; + + return xsettings_manager_set_setting (manager, &setting); +} + +static size_t +setting_length (XSettingsSetting *setting) +{ + size_t length = 8; /* type + pad + name-len + last-change-serial */ + length += XSETTINGS_PAD (strlen (setting->name), 4); + + switch (setting->type) + { + case XSETTINGS_TYPE_INT: + length += 4; + break; + case XSETTINGS_TYPE_STRING: + length += 4 + XSETTINGS_PAD (strlen (setting->data.v_string), 4); + break; + case XSETTINGS_TYPE_COLOR: + length += 8; + break; + } + + return length; +} + +static void +setting_store (XSettingsSetting *setting, + XSettingsBuffer *buffer) +{ + size_t string_len; + size_t length; + + *(buffer->pos++) = setting->type; + *(buffer->pos++) = 0; + + string_len = strlen (setting->name); + *(CARD16 *)(buffer->pos) = string_len; + buffer->pos += 2; + + length = XSETTINGS_PAD (string_len, 4); + memcpy (buffer->pos, setting->name, string_len); + length -= string_len; + buffer->pos += string_len; + + while (length > 0) + { + *(buffer->pos++) = 0; + length--; + } + + *(CARD32 *)(buffer->pos) = setting->last_change_serial; + buffer->pos += 4; + + switch (setting->type) + { + case XSETTINGS_TYPE_INT: + *(CARD32 *)(buffer->pos) = setting->data.v_int; + buffer->pos += 4; + break; + case XSETTINGS_TYPE_STRING: + string_len = strlen (setting->data.v_string); + *(CARD32 *)(buffer->pos) = string_len; + buffer->pos += 4; + + length = XSETTINGS_PAD (string_len, 4); + memcpy (buffer->pos, setting->data.v_string, string_len); + length -= string_len; + buffer->pos += string_len; + + while (length > 0) + { + *(buffer->pos++) = 0; + length--; + } + break; + case XSETTINGS_TYPE_COLOR: + *(CARD16 *)(buffer->pos) = setting->data.v_color.red; + *(CARD16 *)(buffer->pos + 2) = setting->data.v_color.green; + *(CARD16 *)(buffer->pos + 4) = setting->data.v_color.blue; + *(CARD16 *)(buffer->pos + 6) = setting->data.v_color.alpha; + buffer->pos += 8; + break; + } +} + +XSettingsResult +xsettings_manager_notify (XSettingsManager *manager) +{ + XSettingsBuffer buffer; + XSettingsList *iter; + int n_settings = 0; + + buffer.len = 12; /* byte-order + pad + SERIAL + N_SETTINGS */ + + iter = settings; + while (iter) + { + buffer.len += setting_length (iter->setting); + n_settings++; + iter = iter->next; + } + + buffer.data = buffer.pos = malloc (buffer.len); + if (!buffer.data) + return XSETTINGS_NO_MEM; + + *buffer.pos = xsettings_byte_order (); + + buffer.pos += 4; + *(CARD32 *)buffer.pos = manager->serial++; + buffer.pos += 4; + *(CARD32 *)buffer.pos = n_settings; + buffer.pos += 4; + + iter = settings; + while (iter) + { + setting_store (iter->setting, &buffer); + iter = iter->next; + } + + XChangeProperty (manager->display, manager->window, + manager->xsettings_atom, manager->xsettings_atom, + 8, PropModeReplace, buffer.data, buffer.len); + + free (buffer.data); + + return XSETTINGS_SUCCESS; +} + diff --git a/plugins/xsettings/xsettings-manager.h b/plugins/xsettings/xsettings-manager.h new file mode 100644 index 0000000..f309768 --- /dev/null +++ b/plugins/xsettings/xsettings-manager.h @@ -0,0 +1,71 @@ +/* + * Copyright © 2001 Red Hat, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Owen Taylor, Red Hat, Inc. + */ +#ifndef XSETTINGS_MANAGER_H +#define XSETTINGS_MANAGER_H + +#include <X11/Xlib.h> +#include "xsettings-common.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct _XSettingsManager XSettingsManager; + +typedef void (*XSettingsTerminateFunc) (void *cb_data); + +Bool xsettings_manager_check_running (Display *display, + int screen); + +XSettingsManager *xsettings_manager_new (Display *display, + int screen, + XSettingsTerminateFunc terminate, + void *cb_data); + +void xsettings_manager_destroy (XSettingsManager *manager); +Window xsettings_manager_get_window (XSettingsManager *manager); +Bool xsettings_manager_process_event (XSettingsManager *manager, + XEvent *xev); + +XSettingsResult xsettings_manager_delete_setting (XSettingsManager *manager, + const char *name); +XSettingsResult xsettings_manager_set_setting (XSettingsManager *manager, + XSettingsSetting *setting); +XSettingsResult xsettings_manager_set_int (XSettingsManager *manager, + const char *name, + int value); +XSettingsResult xsettings_manager_set_string (XSettingsManager *manager, + const char *name, + const char *value); +XSettingsResult xsettings_manager_set_color (XSettingsManager *manager, + const char *name, + XSettingsColor *value); +XSettingsResult xsettings_manager_notify (XSettingsManager *manager); + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* XSETTINGS_MANAGER_H */ diff --git a/plugins/xsettings/xsettings.mate-settings-plugin.in b/plugins/xsettings/xsettings.mate-settings-plugin.in new file mode 100644 index 0000000..6747dc1 --- /dev/null +++ b/plugins/xsettings/xsettings.mate-settings-plugin.in @@ -0,0 +1,8 @@ +[MATE Settings Plugin] +Module=xsettings +IAge=0 +_Name=X Settings +_Description=Manage X Settings +Authors=William Jon McCann +Copyright=Copyright © 2007 William Jon McCann +Website= |