summaryrefslogtreecommitdiff
path: root/xfce4-session
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2015-03-22 06:18:07 -0700
committerYves-Alexis Perez <corsac@debian.org>2015-03-22 06:18:07 -0700
commit8ea49fdb7ecf5b14d99fca09c57f6d988ff90739 (patch)
treeb9bd6ff1471b3c3fcd73562c9825e5570a027de3 /xfce4-session
downloadxfce4-session-8ea49fdb7ecf5b14d99fca09c57f6d988ff90739.tar.gz
Import xfce4-session_4.12.1.orig.tar.bz2
[dgit import orig xfce4-session_4.12.1.orig.tar.bz2]
Diffstat (limited to 'xfce4-session')
-rw-r--r--xfce4-session/Makefile.am158
-rw-r--r--xfce4-session/Makefile.in1325
-rw-r--r--xfce4-session/ice-layer.c384
-rw-r--r--xfce4-session/ice-layer.h37
-rw-r--r--xfce4-session/main.c334
-rw-r--r--xfce4-session/org.xfce.session.policy.in234
-rw-r--r--xfce4-session/sm-layer.c431
-rw-r--r--xfce4-session/sm-layer.h34
-rw-r--r--xfce4-session/xfce4-session.184
-rw-r--r--xfce4-session/xfsm-chooser-icon.h327
-rw-r--r--xfce4-session/xfsm-chooser-icon.pngbin0 -> 8957 bytes
-rw-r--r--xfce4-session/xfsm-chooser.c239
-rw-r--r--xfce4-session/xfsm-chooser.h64
-rw-r--r--xfce4-session/xfsm-client-dbus.h268
-rw-r--r--xfce4-session/xfsm-client-dbus.xml163
-rw-r--r--xfce4-session/xfsm-client.c601
-rw-r--r--xfce4-session/xfsm-client.h82
-rw-r--r--xfce4-session/xfsm-compat-gnome.c275
-rw-r--r--xfce4-session/xfsm-compat-gnome.h32
-rw-r--r--xfce4-session/xfsm-compat-kde.c157
-rw-r--r--xfce4-session/xfsm-compat-kde.h31
-rw-r--r--xfce4-session/xfsm-consolekit.c491
-rw-r--r--xfce4-session/xfsm-consolekit.h71
-rw-r--r--xfce4-session/xfsm-dns.c176
-rw-r--r--xfce4-session/xfsm-dns.h28
-rw-r--r--xfce4-session/xfsm-error.c65
-rw-r--r--xfce4-session/xfsm-error.h44
-rw-r--r--xfce4-session/xfsm-fadeout.c139
-rw-r--r--xfce4-session/xfsm-fadeout.h39
-rw-r--r--xfce4-session/xfsm-global.c204
-rw-r--r--xfce4-session/xfsm-global.h75
-rw-r--r--xfce4-session/xfsm-legacy.c672
-rw-r--r--xfce4-session/xfsm-legacy.h37
-rw-r--r--xfce4-session/xfsm-logout-dialog.c787
-rw-r--r--xfce4-session/xfsm-logout-dialog.h43
-rw-r--r--xfce4-session/xfsm-manager-dbus.h372
-rw-r--r--xfce4-session/xfsm-manager-dbus.xml186
-rw-r--r--xfce4-session/xfsm-manager.c2178
-rw-r--r--xfce4-session/xfsm-manager.h161
-rw-r--r--xfce4-session/xfsm-marshal.c126
-rw-r--r--xfce4-session/xfsm-marshal.h28
-rw-r--r--xfce4-session/xfsm-marshal.list2
-rw-r--r--xfce4-session/xfsm-properties.c726
-rw-r--r--xfce4-session/xfsm-properties.h110
-rw-r--r--xfce4-session/xfsm-shutdown-fallback.c371
-rw-r--r--xfce4-session/xfsm-shutdown-fallback.h39
-rw-r--r--xfce4-session/xfsm-shutdown.c509
-rw-r--r--xfce4-session/xfsm-shutdown.h101
-rw-r--r--xfce4-session/xfsm-splash-screen.c305
-rw-r--r--xfce4-session/xfsm-splash-screen.h58
-rw-r--r--xfce4-session/xfsm-startup.c1187
-rw-r--r--xfce4-session/xfsm-startup.h38
-rw-r--r--xfce4-session/xfsm-systemd.c325
-rw-r--r--xfce4-session/xfsm-systemd.h73
-rw-r--r--xfce4-session/xfsm-upower.c423
-rw-r--r--xfce4-session/xfsm-upower.h58
56 files changed, 15307 insertions, 0 deletions
diff --git a/xfce4-session/Makefile.am b/xfce4-session/Makefile.am
new file mode 100644
index 0000000..73a29c7
--- /dev/null
+++ b/xfce4-session/Makefile.am
@@ -0,0 +1,158 @@
+
+AM_CPPFLAGS = \
+ -I$(top_builddir) \
+ -I$(top_srcdir) \
+ -DG_LOG_DOMAIN=\"xfce4-session\" \
+ -DLIBDIR=\"$(libdir)\" \
+ -DPACKAGE_LOCALE_DIR=\"$(localedir)\" \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DXFSM_SHUTDOWN_HELPER_CMD=\"$(HELPER_PATH_PREFIX)/xfce4/session/xfsm-shutdown-helper\" \
+ -DDBUS_API_SUBJECT_TO_CHANGE \
+ -DWNCK_I_KNOW_THIS_IS_UNSTABLE \
+ -DUPOWER_ENABLE_DEPRECATED \
+ $(PLATFORM_CPPFLAGS)
+
+man_MANS = xfce4-session.1
+
+bin_PROGRAMS = xfce4-session
+
+xfce4_session_built_sources = \
+ xfsm-chooser-icon.h \
+ xfsm-client-dbus.h \
+ xfsm-manager-dbus.h \
+ xfsm-marshal.c \
+ xfsm-marshal.h
+
+xfce4_session_SOURCES = \
+ $(xfce4_session_built_sources) \
+ ice-layer.c \
+ ice-layer.h \
+ main.c \
+ sm-layer.c \
+ sm-layer.h \
+ xfsm-chooser.c \
+ xfsm-chooser.h \
+ xfsm-client.c \
+ xfsm-client.h \
+ xfsm-client-dbus.h \
+ xfsm-compat-gnome.c \
+ xfsm-compat-gnome.h \
+ xfsm-compat-kde.c \
+ xfsm-compat-kde.h \
+ xfsm-consolekit.c \
+ xfsm-consolekit.h \
+ xfsm-dns.c \
+ xfsm-dns.h \
+ xfsm-error.c \
+ xfsm-error.h \
+ xfsm-fadeout.c \
+ xfsm-fadeout.h \
+ xfsm-global.c \
+ xfsm-global.h \
+ xfsm-legacy.c \
+ xfsm-legacy.h \
+ xfsm-logout-dialog.c \
+ xfsm-logout-dialog.h \
+ xfsm-manager.c \
+ xfsm-manager.h \
+ xfsm-properties.c \
+ xfsm-properties.h \
+ xfsm-shutdown-fallback.c \
+ xfsm-shutdown-fallback.h \
+ xfsm-shutdown.c \
+ xfsm-shutdown.h \
+ xfsm-splash-screen.c \
+ xfsm-splash-screen.h \
+ xfsm-startup.c \
+ xfsm-startup.h \
+ xfsm-upower.c \
+ xfsm-upower.h \
+ xfsm-systemd.c \
+ xfsm-systemd.h
+
+
+xfce4_session_CFLAGS = \
+ $(LIBSM_CFLAGS) \
+ $(LIBX11_CFLAGS) \
+ $(LIBXFCE4UI_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ $(DBUS_GLIB_CFLAGS) \
+ $(LIBWNCK_CFLAGS) \
+ $(POLKIT_CFLAGS) \
+ $(XFCONF_CFLAGS) \
+ $(GMODULE_CFLAGS) \
+ $(PLATFORM_CFLAGS) \
+ $(UPOWER_CFLAGS)
+
+xfce4_session_LDFLAGS = \
+ -no-undefined \
+ $(PLATFORM_LDFLAGS)
+
+xfce4_session_LDADD = \
+ $(top_builddir)/libxfsm/libxfsm-4.6.la \
+ $(LIBSM_LDFLAGS) \
+ $(LIBSM_LIBS) \
+ $(LIBX11_LDFLAGS) \
+ $(LIBX11_LIBS) \
+ $(LIBXFCE4UI_LIBS) \
+ $(GMODULE_LIBS) \
+ $(DBUS_LIBS) \
+ $(DBUS_GLIB_LIBS) \
+ $(LIBWNCK_LIBS) \
+ $(POLKIT_LIBS) \
+ $(XFCONF_LIBS) \
+ $(UPOWER_LIBS) \
+ -lm
+
+xfce4_session_DEPENDENCIES = \
+ $(top_builddir)/libxfsm/libxfsm-4.6.la
+
+if HAVE_POLKIT
+
+@INTLTOOL_POLICY_RULE@
+
+polkit_policydir = $(datadir)/polkit-1/actions
+polkit_policy_DATA = \
+ org.xfce.session.policy
+.in2.in:
+ sed "s|[@]HELPER_PATH_PREFIX@|${HELPER_PATH_PREFIX}|" $< > $@
+
+endif
+
+if MAINTAINER_MODE
+
+xfsm-chooser-icon.h: $(srcdir)/xfsm-chooser-icon.png
+ $(AM_V_GEN) gdk-pixbuf-csource --static --raw --stream --name=xfsm_chooser_icon_data $< > $@
+
+xfsm-marshal.h: $(srcdir)/xfsm-marshal.list Makefile
+ $(AM_V_GEN) glib-genmarshal --prefix=xfsm_marshal --internal --header $< > $@
+
+xfsm-marshal.c: $(srcdir)/xfsm-marshal.list Makefile
+ $(AM_V_GEN) echo "#include <xfce4-session/xfsm-marshal.h>" > $@ \
+ && glib-genmarshal --prefix=xfsm_marshal --body $< >> $@
+
+xfsm-manager-dbus.h: $(srcdir)/xfsm-manager-dbus.xml
+ $(AM_V_GEN) dbus-binding-tool --mode=glib-server --prefix=xfsm_manager $< > $@
+
+xfsm-client-dbus.h: $(srcdir)/xfsm-client-dbus.xml
+ $(AM_V_GEN) dbus-binding-tool --mode=glib-server --prefix=xfsm_client $< > $@
+
+BUILT_SOURCES = \
+ $(xfce4_session_built_sources)
+
+endif
+
+EXTRA_DIST = \
+ $(man_MANS) \
+ xfsm-chooser-icon.png \
+ xfsm-marshal.list \
+ xfsm-client-dbus.xml \
+ xfsm-manager-dbus.xml \
+ org.xfce.session.policy.in2
+
+DISTCLEANFILES = \
+ $(xfce4_session_built_sources) \
+ org.xfce.session.policy \
+ org.xfce.session.policy.in
+
+# vi:set ts=8 sw=8 noet ai nocindent syntax=automake:
diff --git a/xfce4-session/Makefile.in b/xfce4-session/Makefile.in
new file mode 100644
index 0000000..506c01b
--- /dev/null
+++ b/xfce4-session/Makefile.in
@@ -0,0 +1,1325 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 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@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+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@
+bin_PROGRAMS = xfce4-session$(EXEEXT)
+subdir = xfce4-session
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \
+ "$(DESTDIR)$(polkit_policydir)"
+PROGRAMS = $(bin_PROGRAMS)
+am__objects_1 = xfce4_session-xfsm-marshal.$(OBJEXT)
+am_xfce4_session_OBJECTS = $(am__objects_1) \
+ xfce4_session-ice-layer.$(OBJEXT) xfce4_session-main.$(OBJEXT) \
+ xfce4_session-sm-layer.$(OBJEXT) \
+ xfce4_session-xfsm-chooser.$(OBJEXT) \
+ xfce4_session-xfsm-client.$(OBJEXT) \
+ xfce4_session-xfsm-compat-gnome.$(OBJEXT) \
+ xfce4_session-xfsm-compat-kde.$(OBJEXT) \
+ xfce4_session-xfsm-consolekit.$(OBJEXT) \
+ xfce4_session-xfsm-dns.$(OBJEXT) \
+ xfce4_session-xfsm-error.$(OBJEXT) \
+ xfce4_session-xfsm-fadeout.$(OBJEXT) \
+ xfce4_session-xfsm-global.$(OBJEXT) \
+ xfce4_session-xfsm-legacy.$(OBJEXT) \
+ xfce4_session-xfsm-logout-dialog.$(OBJEXT) \
+ xfce4_session-xfsm-manager.$(OBJEXT) \
+ xfce4_session-xfsm-properties.$(OBJEXT) \
+ xfce4_session-xfsm-shutdown-fallback.$(OBJEXT) \
+ xfce4_session-xfsm-shutdown.$(OBJEXT) \
+ xfce4_session-xfsm-splash-screen.$(OBJEXT) \
+ xfce4_session-xfsm-startup.$(OBJEXT) \
+ xfce4_session-xfsm-upower.$(OBJEXT) \
+ xfce4_session-xfsm-systemd.$(OBJEXT)
+xfce4_session_OBJECTS = $(am_xfce4_session_OBJECTS)
+am__DEPENDENCIES_1 =
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+xfce4_session_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(xfce4_session_CFLAGS) \
+ $(CFLAGS) $(xfce4_session_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_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) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(xfce4_session_SOURCES)
+DIST_SOURCES = $(xfce4_session_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+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__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+man1dir = $(mandir)/man1
+NROFF = nroff
+MANS = $(man_MANS)
+DATA = $(polkit_policy_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BACKEND = @BACKEND@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_GLIB_CFLAGS = @DBUS_GLIB_CFLAGS@
+DBUS_GLIB_LIBS = @DBUS_GLIB_LIBS@
+DBUS_GLIB_REQUIRED_VERSION = @DBUS_GLIB_REQUIRED_VERSION@
+DBUS_GLIB_VERSION = @DBUS_GLIB_VERSION@
+DBUS_LIBS = @DBUS_LIBS@
+DBUS_REQUIRED_VERSION = @DBUS_REQUIRED_VERSION@
+DBUS_VERSION = @DBUS_VERSION@
+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@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMODULE_CFLAGS = @GMODULE_CFLAGS@
+GMODULE_LIBS = @GMODULE_LIBS@
+GMODULE_REQUIRED_VERSION = @GMODULE_REQUIRED_VERSION@
+GMODULE_VERSION = @GMODULE_VERSION@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+GTK_REQUIRED_VERSION = @GTK_REQUIRED_VERSION@
+GTK_VERSION = @GTK_VERSION@
+HELPER_PATH_PREFIX = @HELPER_PATH_PREFIX@
+ICEAUTH = @ICEAUTH@
+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@
+INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@
+INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@
+INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@
+INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBM = @LIBM@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSM_CFLAGS = @LIBSM_CFLAGS@
+LIBSM_LDFLAGS = @LIBSM_LDFLAGS@
+LIBSM_LIBS = @LIBSM_LIBS@
+LIBTOOL = @LIBTOOL@
+LIBWNCK_CFLAGS = @LIBWNCK_CFLAGS@
+LIBWNCK_LIBS = @LIBWNCK_LIBS@
+LIBWNCK_REQUIRED_VERSION = @LIBWNCK_REQUIRED_VERSION@
+LIBWNCK_VERSION = @LIBWNCK_VERSION@
+LIBX11_CFLAGS = @LIBX11_CFLAGS@
+LIBX11_LDFLAGS = @LIBX11_LDFLAGS@
+LIBX11_LIBS = @LIBX11_LIBS@
+LIBXFCE4UI_CFLAGS = @LIBXFCE4UI_CFLAGS@
+LIBXFCE4UI_LIBS = @LIBXFCE4UI_LIBS@
+LIBXFCE4UI_REQUIRED_VERSION = @LIBXFCE4UI_REQUIRED_VERSION@
+LIBXFCE4UI_VERSION = @LIBXFCE4UI_VERSION@
+LIBXFCE4UTIL_CFLAGS = @LIBXFCE4UTIL_CFLAGS@
+LIBXFCE4UTIL_LIBS = @LIBXFCE4UTIL_LIBS@
+LIBXFCE4UTIL_REQUIRED_VERSION = @LIBXFCE4UTIL_REQUIRED_VERSION@
+LIBXFCE4UTIL_VERSION = @LIBXFCE4UTIL_VERSION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+MSGMERGE = @MSGMERGE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+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@
+POLKIT_REQUIRED_VERSION = @POLKIT_REQUIRED_VERSION@
+POLKIT_VERSION = @POLKIT_VERSION@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+RANLIB = @RANLIB@
+RM = @RM@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+UPOWER_CFLAGS = @UPOWER_CFLAGS@
+UPOWER_LIBS = @UPOWER_LIBS@
+UPOWER_REQUIRED_VERSION = @UPOWER_REQUIRED_VERSION@
+UPOWER_VERSION = @UPOWER_VERSION@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XFCE_GLADE_CATALOG_PATH = @XFCE_GLADE_CATALOG_PATH@
+XFCE_GLADE_MODULE_PATH = @XFCE_GLADE_MODULE_PATH@
+XFCE_GLADE_PIXMAP_PATH = @XFCE_GLADE_PIXMAP_PATH@
+XFCONF_CFLAGS = @XFCONF_CFLAGS@
+XFCONF_LIBS = @XFCONF_LIBS@
+XFCONF_REQUIRED_VERSION = @XFCONF_REQUIRED_VERSION@
+XFCONF_VERSION = @XFCONF_VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_ARGS = @XGETTEXT_ARGS@
+XMKMF = @XMKMF@
+XSESSION_PREFIX = @XSESSION_PREFIX@
+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_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@
+intltool__v_merge_options_ = @intltool__v_merge_options_@
+intltool__v_merge_options_0 = @intltool__v_merge_options_0@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+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@
+AM_CPPFLAGS = \
+ -I$(top_builddir) \
+ -I$(top_srcdir) \
+ -DG_LOG_DOMAIN=\"xfce4-session\" \
+ -DLIBDIR=\"$(libdir)\" \
+ -DPACKAGE_LOCALE_DIR=\"$(localedir)\" \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DXFSM_SHUTDOWN_HELPER_CMD=\"$(HELPER_PATH_PREFIX)/xfce4/session/xfsm-shutdown-helper\" \
+ -DDBUS_API_SUBJECT_TO_CHANGE \
+ -DWNCK_I_KNOW_THIS_IS_UNSTABLE \
+ -DUPOWER_ENABLE_DEPRECATED \
+ $(PLATFORM_CPPFLAGS)
+
+man_MANS = xfce4-session.1
+xfce4_session_built_sources = \
+ xfsm-chooser-icon.h \
+ xfsm-client-dbus.h \
+ xfsm-manager-dbus.h \
+ xfsm-marshal.c \
+ xfsm-marshal.h
+
+xfce4_session_SOURCES = \
+ $(xfce4_session_built_sources) \
+ ice-layer.c \
+ ice-layer.h \
+ main.c \
+ sm-layer.c \
+ sm-layer.h \
+ xfsm-chooser.c \
+ xfsm-chooser.h \
+ xfsm-client.c \
+ xfsm-client.h \
+ xfsm-client-dbus.h \
+ xfsm-compat-gnome.c \
+ xfsm-compat-gnome.h \
+ xfsm-compat-kde.c \
+ xfsm-compat-kde.h \
+ xfsm-consolekit.c \
+ xfsm-consolekit.h \
+ xfsm-dns.c \
+ xfsm-dns.h \
+ xfsm-error.c \
+ xfsm-error.h \
+ xfsm-fadeout.c \
+ xfsm-fadeout.h \
+ xfsm-global.c \
+ xfsm-global.h \
+ xfsm-legacy.c \
+ xfsm-legacy.h \
+ xfsm-logout-dialog.c \
+ xfsm-logout-dialog.h \
+ xfsm-manager.c \
+ xfsm-manager.h \
+ xfsm-properties.c \
+ xfsm-properties.h \
+ xfsm-shutdown-fallback.c \
+ xfsm-shutdown-fallback.h \
+ xfsm-shutdown.c \
+ xfsm-shutdown.h \
+ xfsm-splash-screen.c \
+ xfsm-splash-screen.h \
+ xfsm-startup.c \
+ xfsm-startup.h \
+ xfsm-upower.c \
+ xfsm-upower.h \
+ xfsm-systemd.c \
+ xfsm-systemd.h
+
+xfce4_session_CFLAGS = \
+ $(LIBSM_CFLAGS) \
+ $(LIBX11_CFLAGS) \
+ $(LIBXFCE4UI_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ $(DBUS_GLIB_CFLAGS) \
+ $(LIBWNCK_CFLAGS) \
+ $(POLKIT_CFLAGS) \
+ $(XFCONF_CFLAGS) \
+ $(GMODULE_CFLAGS) \
+ $(PLATFORM_CFLAGS) \
+ $(UPOWER_CFLAGS)
+
+xfce4_session_LDFLAGS = \
+ -no-undefined \
+ $(PLATFORM_LDFLAGS)
+
+xfce4_session_LDADD = \
+ $(top_builddir)/libxfsm/libxfsm-4.6.la \
+ $(LIBSM_LDFLAGS) \
+ $(LIBSM_LIBS) \
+ $(LIBX11_LDFLAGS) \
+ $(LIBX11_LIBS) \
+ $(LIBXFCE4UI_LIBS) \
+ $(GMODULE_LIBS) \
+ $(DBUS_LIBS) \
+ $(DBUS_GLIB_LIBS) \
+ $(LIBWNCK_LIBS) \
+ $(POLKIT_LIBS) \
+ $(XFCONF_LIBS) \
+ $(UPOWER_LIBS) \
+ -lm
+
+xfce4_session_DEPENDENCIES = \
+ $(top_builddir)/libxfsm/libxfsm-4.6.la
+
+@HAVE_POLKIT_TRUE@polkit_policydir = $(datadir)/polkit-1/actions
+@HAVE_POLKIT_TRUE@polkit_policy_DATA = \
+@HAVE_POLKIT_TRUE@ org.xfce.session.policy
+
+@MAINTAINER_MODE_TRUE@BUILT_SOURCES = \
+@MAINTAINER_MODE_TRUE@ $(xfce4_session_built_sources)
+
+EXTRA_DIST = \
+ $(man_MANS) \
+ xfsm-chooser-icon.png \
+ xfsm-marshal.list \
+ xfsm-client-dbus.xml \
+ xfsm-manager-dbus.xml \
+ org.xfce.session.policy.in2
+
+DISTCLEANFILES = \
+ $(xfce4_session_built_sources) \
+ org.xfce.session.policy \
+ org.xfce.session.policy.in
+
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .in .in2 .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(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 xfce4-session/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu xfce4-session/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: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+ fi; \
+ 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)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || 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)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+ @list='$(bin_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
+
+xfce4-session$(EXEEXT): $(xfce4_session_OBJECTS) $(xfce4_session_DEPENDENCIES) $(EXTRA_xfce4_session_DEPENDENCIES)
+ @rm -f xfce4-session$(EXEEXT)
+ $(AM_V_CCLD)$(xfce4_session_LINK) $(xfce4_session_OBJECTS) $(xfce4_session_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-ice-layer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-sm-layer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-xfsm-chooser.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-xfsm-client.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-xfsm-compat-gnome.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-xfsm-compat-kde.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-xfsm-consolekit.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-xfsm-dns.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-xfsm-error.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-xfsm-fadeout.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-xfsm-global.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-xfsm-legacy.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-xfsm-logout-dialog.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-xfsm-manager.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-xfsm-marshal.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-xfsm-properties.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-xfsm-shutdown-fallback.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-xfsm-shutdown.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-xfsm-splash-screen.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-xfsm-startup.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-xfsm-systemd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfce4_session-xfsm-upower.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+xfce4_session-xfsm-marshal.o: xfsm-marshal.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-marshal.o -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-marshal.Tpo -c -o xfce4_session-xfsm-marshal.o `test -f 'xfsm-marshal.c' || echo '$(srcdir)/'`xfsm-marshal.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-marshal.Tpo $(DEPDIR)/xfce4_session-xfsm-marshal.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-marshal.c' object='xfce4_session-xfsm-marshal.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-marshal.o `test -f 'xfsm-marshal.c' || echo '$(srcdir)/'`xfsm-marshal.c
+
+xfce4_session-xfsm-marshal.obj: xfsm-marshal.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-marshal.obj -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-marshal.Tpo -c -o xfce4_session-xfsm-marshal.obj `if test -f 'xfsm-marshal.c'; then $(CYGPATH_W) 'xfsm-marshal.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-marshal.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-marshal.Tpo $(DEPDIR)/xfce4_session-xfsm-marshal.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-marshal.c' object='xfce4_session-xfsm-marshal.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-marshal.obj `if test -f 'xfsm-marshal.c'; then $(CYGPATH_W) 'xfsm-marshal.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-marshal.c'; fi`
+
+xfce4_session-ice-layer.o: ice-layer.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-ice-layer.o -MD -MP -MF $(DEPDIR)/xfce4_session-ice-layer.Tpo -c -o xfce4_session-ice-layer.o `test -f 'ice-layer.c' || echo '$(srcdir)/'`ice-layer.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-ice-layer.Tpo $(DEPDIR)/xfce4_session-ice-layer.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ice-layer.c' object='xfce4_session-ice-layer.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-ice-layer.o `test -f 'ice-layer.c' || echo '$(srcdir)/'`ice-layer.c
+
+xfce4_session-ice-layer.obj: ice-layer.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-ice-layer.obj -MD -MP -MF $(DEPDIR)/xfce4_session-ice-layer.Tpo -c -o xfce4_session-ice-layer.obj `if test -f 'ice-layer.c'; then $(CYGPATH_W) 'ice-layer.c'; else $(CYGPATH_W) '$(srcdir)/ice-layer.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-ice-layer.Tpo $(DEPDIR)/xfce4_session-ice-layer.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ice-layer.c' object='xfce4_session-ice-layer.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-ice-layer.obj `if test -f 'ice-layer.c'; then $(CYGPATH_W) 'ice-layer.c'; else $(CYGPATH_W) '$(srcdir)/ice-layer.c'; fi`
+
+xfce4_session-main.o: main.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-main.o -MD -MP -MF $(DEPDIR)/xfce4_session-main.Tpo -c -o xfce4_session-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-main.Tpo $(DEPDIR)/xfce4_session-main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='xfce4_session-main.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
+
+xfce4_session-main.obj: main.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-main.obj -MD -MP -MF $(DEPDIR)/xfce4_session-main.Tpo -c -o xfce4_session-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-main.Tpo $(DEPDIR)/xfce4_session-main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='xfce4_session-main.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
+
+xfce4_session-sm-layer.o: sm-layer.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-sm-layer.o -MD -MP -MF $(DEPDIR)/xfce4_session-sm-layer.Tpo -c -o xfce4_session-sm-layer.o `test -f 'sm-layer.c' || echo '$(srcdir)/'`sm-layer.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-sm-layer.Tpo $(DEPDIR)/xfce4_session-sm-layer.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sm-layer.c' object='xfce4_session-sm-layer.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-sm-layer.o `test -f 'sm-layer.c' || echo '$(srcdir)/'`sm-layer.c
+
+xfce4_session-sm-layer.obj: sm-layer.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-sm-layer.obj -MD -MP -MF $(DEPDIR)/xfce4_session-sm-layer.Tpo -c -o xfce4_session-sm-layer.obj `if test -f 'sm-layer.c'; then $(CYGPATH_W) 'sm-layer.c'; else $(CYGPATH_W) '$(srcdir)/sm-layer.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-sm-layer.Tpo $(DEPDIR)/xfce4_session-sm-layer.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sm-layer.c' object='xfce4_session-sm-layer.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-sm-layer.obj `if test -f 'sm-layer.c'; then $(CYGPATH_W) 'sm-layer.c'; else $(CYGPATH_W) '$(srcdir)/sm-layer.c'; fi`
+
+xfce4_session-xfsm-chooser.o: xfsm-chooser.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-chooser.o -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-chooser.Tpo -c -o xfce4_session-xfsm-chooser.o `test -f 'xfsm-chooser.c' || echo '$(srcdir)/'`xfsm-chooser.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-chooser.Tpo $(DEPDIR)/xfce4_session-xfsm-chooser.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-chooser.c' object='xfce4_session-xfsm-chooser.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-chooser.o `test -f 'xfsm-chooser.c' || echo '$(srcdir)/'`xfsm-chooser.c
+
+xfce4_session-xfsm-chooser.obj: xfsm-chooser.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-chooser.obj -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-chooser.Tpo -c -o xfce4_session-xfsm-chooser.obj `if test -f 'xfsm-chooser.c'; then $(CYGPATH_W) 'xfsm-chooser.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-chooser.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-chooser.Tpo $(DEPDIR)/xfce4_session-xfsm-chooser.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-chooser.c' object='xfce4_session-xfsm-chooser.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-chooser.obj `if test -f 'xfsm-chooser.c'; then $(CYGPATH_W) 'xfsm-chooser.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-chooser.c'; fi`
+
+xfce4_session-xfsm-client.o: xfsm-client.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-client.o -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-client.Tpo -c -o xfce4_session-xfsm-client.o `test -f 'xfsm-client.c' || echo '$(srcdir)/'`xfsm-client.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-client.Tpo $(DEPDIR)/xfce4_session-xfsm-client.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-client.c' object='xfce4_session-xfsm-client.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-client.o `test -f 'xfsm-client.c' || echo '$(srcdir)/'`xfsm-client.c
+
+xfce4_session-xfsm-client.obj: xfsm-client.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-client.obj -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-client.Tpo -c -o xfce4_session-xfsm-client.obj `if test -f 'xfsm-client.c'; then $(CYGPATH_W) 'xfsm-client.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-client.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-client.Tpo $(DEPDIR)/xfce4_session-xfsm-client.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-client.c' object='xfce4_session-xfsm-client.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-client.obj `if test -f 'xfsm-client.c'; then $(CYGPATH_W) 'xfsm-client.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-client.c'; fi`
+
+xfce4_session-xfsm-compat-gnome.o: xfsm-compat-gnome.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-compat-gnome.o -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-compat-gnome.Tpo -c -o xfce4_session-xfsm-compat-gnome.o `test -f 'xfsm-compat-gnome.c' || echo '$(srcdir)/'`xfsm-compat-gnome.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-compat-gnome.Tpo $(DEPDIR)/xfce4_session-xfsm-compat-gnome.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-compat-gnome.c' object='xfce4_session-xfsm-compat-gnome.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-compat-gnome.o `test -f 'xfsm-compat-gnome.c' || echo '$(srcdir)/'`xfsm-compat-gnome.c
+
+xfce4_session-xfsm-compat-gnome.obj: xfsm-compat-gnome.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-compat-gnome.obj -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-compat-gnome.Tpo -c -o xfce4_session-xfsm-compat-gnome.obj `if test -f 'xfsm-compat-gnome.c'; then $(CYGPATH_W) 'xfsm-compat-gnome.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-compat-gnome.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-compat-gnome.Tpo $(DEPDIR)/xfce4_session-xfsm-compat-gnome.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-compat-gnome.c' object='xfce4_session-xfsm-compat-gnome.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-compat-gnome.obj `if test -f 'xfsm-compat-gnome.c'; then $(CYGPATH_W) 'xfsm-compat-gnome.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-compat-gnome.c'; fi`
+
+xfce4_session-xfsm-compat-kde.o: xfsm-compat-kde.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-compat-kde.o -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-compat-kde.Tpo -c -o xfce4_session-xfsm-compat-kde.o `test -f 'xfsm-compat-kde.c' || echo '$(srcdir)/'`xfsm-compat-kde.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-compat-kde.Tpo $(DEPDIR)/xfce4_session-xfsm-compat-kde.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-compat-kde.c' object='xfce4_session-xfsm-compat-kde.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-compat-kde.o `test -f 'xfsm-compat-kde.c' || echo '$(srcdir)/'`xfsm-compat-kde.c
+
+xfce4_session-xfsm-compat-kde.obj: xfsm-compat-kde.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-compat-kde.obj -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-compat-kde.Tpo -c -o xfce4_session-xfsm-compat-kde.obj `if test -f 'xfsm-compat-kde.c'; then $(CYGPATH_W) 'xfsm-compat-kde.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-compat-kde.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-compat-kde.Tpo $(DEPDIR)/xfce4_session-xfsm-compat-kde.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-compat-kde.c' object='xfce4_session-xfsm-compat-kde.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-compat-kde.obj `if test -f 'xfsm-compat-kde.c'; then $(CYGPATH_W) 'xfsm-compat-kde.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-compat-kde.c'; fi`
+
+xfce4_session-xfsm-consolekit.o: xfsm-consolekit.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-consolekit.o -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-consolekit.Tpo -c -o xfce4_session-xfsm-consolekit.o `test -f 'xfsm-consolekit.c' || echo '$(srcdir)/'`xfsm-consolekit.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-consolekit.Tpo $(DEPDIR)/xfce4_session-xfsm-consolekit.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-consolekit.c' object='xfce4_session-xfsm-consolekit.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-consolekit.o `test -f 'xfsm-consolekit.c' || echo '$(srcdir)/'`xfsm-consolekit.c
+
+xfce4_session-xfsm-consolekit.obj: xfsm-consolekit.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-consolekit.obj -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-consolekit.Tpo -c -o xfce4_session-xfsm-consolekit.obj `if test -f 'xfsm-consolekit.c'; then $(CYGPATH_W) 'xfsm-consolekit.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-consolekit.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-consolekit.Tpo $(DEPDIR)/xfce4_session-xfsm-consolekit.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-consolekit.c' object='xfce4_session-xfsm-consolekit.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-consolekit.obj `if test -f 'xfsm-consolekit.c'; then $(CYGPATH_W) 'xfsm-consolekit.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-consolekit.c'; fi`
+
+xfce4_session-xfsm-dns.o: xfsm-dns.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-dns.o -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-dns.Tpo -c -o xfce4_session-xfsm-dns.o `test -f 'xfsm-dns.c' || echo '$(srcdir)/'`xfsm-dns.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-dns.Tpo $(DEPDIR)/xfce4_session-xfsm-dns.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-dns.c' object='xfce4_session-xfsm-dns.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-dns.o `test -f 'xfsm-dns.c' || echo '$(srcdir)/'`xfsm-dns.c
+
+xfce4_session-xfsm-dns.obj: xfsm-dns.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-dns.obj -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-dns.Tpo -c -o xfce4_session-xfsm-dns.obj `if test -f 'xfsm-dns.c'; then $(CYGPATH_W) 'xfsm-dns.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-dns.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-dns.Tpo $(DEPDIR)/xfce4_session-xfsm-dns.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-dns.c' object='xfce4_session-xfsm-dns.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-dns.obj `if test -f 'xfsm-dns.c'; then $(CYGPATH_W) 'xfsm-dns.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-dns.c'; fi`
+
+xfce4_session-xfsm-error.o: xfsm-error.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-error.o -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-error.Tpo -c -o xfce4_session-xfsm-error.o `test -f 'xfsm-error.c' || echo '$(srcdir)/'`xfsm-error.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-error.Tpo $(DEPDIR)/xfce4_session-xfsm-error.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-error.c' object='xfce4_session-xfsm-error.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-error.o `test -f 'xfsm-error.c' || echo '$(srcdir)/'`xfsm-error.c
+
+xfce4_session-xfsm-error.obj: xfsm-error.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-error.obj -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-error.Tpo -c -o xfce4_session-xfsm-error.obj `if test -f 'xfsm-error.c'; then $(CYGPATH_W) 'xfsm-error.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-error.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-error.Tpo $(DEPDIR)/xfce4_session-xfsm-error.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-error.c' object='xfce4_session-xfsm-error.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-error.obj `if test -f 'xfsm-error.c'; then $(CYGPATH_W) 'xfsm-error.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-error.c'; fi`
+
+xfce4_session-xfsm-fadeout.o: xfsm-fadeout.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-fadeout.o -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-fadeout.Tpo -c -o xfce4_session-xfsm-fadeout.o `test -f 'xfsm-fadeout.c' || echo '$(srcdir)/'`xfsm-fadeout.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-fadeout.Tpo $(DEPDIR)/xfce4_session-xfsm-fadeout.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-fadeout.c' object='xfce4_session-xfsm-fadeout.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-fadeout.o `test -f 'xfsm-fadeout.c' || echo '$(srcdir)/'`xfsm-fadeout.c
+
+xfce4_session-xfsm-fadeout.obj: xfsm-fadeout.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-fadeout.obj -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-fadeout.Tpo -c -o xfce4_session-xfsm-fadeout.obj `if test -f 'xfsm-fadeout.c'; then $(CYGPATH_W) 'xfsm-fadeout.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-fadeout.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-fadeout.Tpo $(DEPDIR)/xfce4_session-xfsm-fadeout.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-fadeout.c' object='xfce4_session-xfsm-fadeout.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-fadeout.obj `if test -f 'xfsm-fadeout.c'; then $(CYGPATH_W) 'xfsm-fadeout.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-fadeout.c'; fi`
+
+xfce4_session-xfsm-global.o: xfsm-global.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-global.o -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-global.Tpo -c -o xfce4_session-xfsm-global.o `test -f 'xfsm-global.c' || echo '$(srcdir)/'`xfsm-global.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-global.Tpo $(DEPDIR)/xfce4_session-xfsm-global.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-global.c' object='xfce4_session-xfsm-global.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-global.o `test -f 'xfsm-global.c' || echo '$(srcdir)/'`xfsm-global.c
+
+xfce4_session-xfsm-global.obj: xfsm-global.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-global.obj -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-global.Tpo -c -o xfce4_session-xfsm-global.obj `if test -f 'xfsm-global.c'; then $(CYGPATH_W) 'xfsm-global.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-global.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-global.Tpo $(DEPDIR)/xfce4_session-xfsm-global.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-global.c' object='xfce4_session-xfsm-global.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-global.obj `if test -f 'xfsm-global.c'; then $(CYGPATH_W) 'xfsm-global.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-global.c'; fi`
+
+xfce4_session-xfsm-legacy.o: xfsm-legacy.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-legacy.o -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-legacy.Tpo -c -o xfce4_session-xfsm-legacy.o `test -f 'xfsm-legacy.c' || echo '$(srcdir)/'`xfsm-legacy.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-legacy.Tpo $(DEPDIR)/xfce4_session-xfsm-legacy.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-legacy.c' object='xfce4_session-xfsm-legacy.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-legacy.o `test -f 'xfsm-legacy.c' || echo '$(srcdir)/'`xfsm-legacy.c
+
+xfce4_session-xfsm-legacy.obj: xfsm-legacy.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-legacy.obj -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-legacy.Tpo -c -o xfce4_session-xfsm-legacy.obj `if test -f 'xfsm-legacy.c'; then $(CYGPATH_W) 'xfsm-legacy.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-legacy.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-legacy.Tpo $(DEPDIR)/xfce4_session-xfsm-legacy.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-legacy.c' object='xfce4_session-xfsm-legacy.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-legacy.obj `if test -f 'xfsm-legacy.c'; then $(CYGPATH_W) 'xfsm-legacy.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-legacy.c'; fi`
+
+xfce4_session-xfsm-logout-dialog.o: xfsm-logout-dialog.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-logout-dialog.o -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-logout-dialog.Tpo -c -o xfce4_session-xfsm-logout-dialog.o `test -f 'xfsm-logout-dialog.c' || echo '$(srcdir)/'`xfsm-logout-dialog.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-logout-dialog.Tpo $(DEPDIR)/xfce4_session-xfsm-logout-dialog.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-logout-dialog.c' object='xfce4_session-xfsm-logout-dialog.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-logout-dialog.o `test -f 'xfsm-logout-dialog.c' || echo '$(srcdir)/'`xfsm-logout-dialog.c
+
+xfce4_session-xfsm-logout-dialog.obj: xfsm-logout-dialog.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-logout-dialog.obj -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-logout-dialog.Tpo -c -o xfce4_session-xfsm-logout-dialog.obj `if test -f 'xfsm-logout-dialog.c'; then $(CYGPATH_W) 'xfsm-logout-dialog.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-logout-dialog.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-logout-dialog.Tpo $(DEPDIR)/xfce4_session-xfsm-logout-dialog.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-logout-dialog.c' object='xfce4_session-xfsm-logout-dialog.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-logout-dialog.obj `if test -f 'xfsm-logout-dialog.c'; then $(CYGPATH_W) 'xfsm-logout-dialog.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-logout-dialog.c'; fi`
+
+xfce4_session-xfsm-manager.o: xfsm-manager.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-manager.o -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-manager.Tpo -c -o xfce4_session-xfsm-manager.o `test -f 'xfsm-manager.c' || echo '$(srcdir)/'`xfsm-manager.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-manager.Tpo $(DEPDIR)/xfce4_session-xfsm-manager.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-manager.c' object='xfce4_session-xfsm-manager.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-manager.o `test -f 'xfsm-manager.c' || echo '$(srcdir)/'`xfsm-manager.c
+
+xfce4_session-xfsm-manager.obj: xfsm-manager.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-manager.obj -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-manager.Tpo -c -o xfce4_session-xfsm-manager.obj `if test -f 'xfsm-manager.c'; then $(CYGPATH_W) 'xfsm-manager.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-manager.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-manager.Tpo $(DEPDIR)/xfce4_session-xfsm-manager.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-manager.c' object='xfce4_session-xfsm-manager.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-manager.obj `if test -f 'xfsm-manager.c'; then $(CYGPATH_W) 'xfsm-manager.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-manager.c'; fi`
+
+xfce4_session-xfsm-properties.o: xfsm-properties.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-properties.o -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-properties.Tpo -c -o xfce4_session-xfsm-properties.o `test -f 'xfsm-properties.c' || echo '$(srcdir)/'`xfsm-properties.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-properties.Tpo $(DEPDIR)/xfce4_session-xfsm-properties.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-properties.c' object='xfce4_session-xfsm-properties.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-properties.o `test -f 'xfsm-properties.c' || echo '$(srcdir)/'`xfsm-properties.c
+
+xfce4_session-xfsm-properties.obj: xfsm-properties.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-properties.obj -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-properties.Tpo -c -o xfce4_session-xfsm-properties.obj `if test -f 'xfsm-properties.c'; then $(CYGPATH_W) 'xfsm-properties.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-properties.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-properties.Tpo $(DEPDIR)/xfce4_session-xfsm-properties.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-properties.c' object='xfce4_session-xfsm-properties.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-properties.obj `if test -f 'xfsm-properties.c'; then $(CYGPATH_W) 'xfsm-properties.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-properties.c'; fi`
+
+xfce4_session-xfsm-shutdown-fallback.o: xfsm-shutdown-fallback.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-shutdown-fallback.o -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-shutdown-fallback.Tpo -c -o xfce4_session-xfsm-shutdown-fallback.o `test -f 'xfsm-shutdown-fallback.c' || echo '$(srcdir)/'`xfsm-shutdown-fallback.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-shutdown-fallback.Tpo $(DEPDIR)/xfce4_session-xfsm-shutdown-fallback.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-shutdown-fallback.c' object='xfce4_session-xfsm-shutdown-fallback.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-shutdown-fallback.o `test -f 'xfsm-shutdown-fallback.c' || echo '$(srcdir)/'`xfsm-shutdown-fallback.c
+
+xfce4_session-xfsm-shutdown-fallback.obj: xfsm-shutdown-fallback.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-shutdown-fallback.obj -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-shutdown-fallback.Tpo -c -o xfce4_session-xfsm-shutdown-fallback.obj `if test -f 'xfsm-shutdown-fallback.c'; then $(CYGPATH_W) 'xfsm-shutdown-fallback.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-shutdown-fallback.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-shutdown-fallback.Tpo $(DEPDIR)/xfce4_session-xfsm-shutdown-fallback.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-shutdown-fallback.c' object='xfce4_session-xfsm-shutdown-fallback.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-shutdown-fallback.obj `if test -f 'xfsm-shutdown-fallback.c'; then $(CYGPATH_W) 'xfsm-shutdown-fallback.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-shutdown-fallback.c'; fi`
+
+xfce4_session-xfsm-shutdown.o: xfsm-shutdown.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-shutdown.o -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-shutdown.Tpo -c -o xfce4_session-xfsm-shutdown.o `test -f 'xfsm-shutdown.c' || echo '$(srcdir)/'`xfsm-shutdown.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-shutdown.Tpo $(DEPDIR)/xfce4_session-xfsm-shutdown.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-shutdown.c' object='xfce4_session-xfsm-shutdown.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-shutdown.o `test -f 'xfsm-shutdown.c' || echo '$(srcdir)/'`xfsm-shutdown.c
+
+xfce4_session-xfsm-shutdown.obj: xfsm-shutdown.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-shutdown.obj -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-shutdown.Tpo -c -o xfce4_session-xfsm-shutdown.obj `if test -f 'xfsm-shutdown.c'; then $(CYGPATH_W) 'xfsm-shutdown.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-shutdown.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-shutdown.Tpo $(DEPDIR)/xfce4_session-xfsm-shutdown.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-shutdown.c' object='xfce4_session-xfsm-shutdown.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-shutdown.obj `if test -f 'xfsm-shutdown.c'; then $(CYGPATH_W) 'xfsm-shutdown.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-shutdown.c'; fi`
+
+xfce4_session-xfsm-splash-screen.o: xfsm-splash-screen.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-splash-screen.o -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-splash-screen.Tpo -c -o xfce4_session-xfsm-splash-screen.o `test -f 'xfsm-splash-screen.c' || echo '$(srcdir)/'`xfsm-splash-screen.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-splash-screen.Tpo $(DEPDIR)/xfce4_session-xfsm-splash-screen.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-splash-screen.c' object='xfce4_session-xfsm-splash-screen.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-splash-screen.o `test -f 'xfsm-splash-screen.c' || echo '$(srcdir)/'`xfsm-splash-screen.c
+
+xfce4_session-xfsm-splash-screen.obj: xfsm-splash-screen.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-splash-screen.obj -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-splash-screen.Tpo -c -o xfce4_session-xfsm-splash-screen.obj `if test -f 'xfsm-splash-screen.c'; then $(CYGPATH_W) 'xfsm-splash-screen.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-splash-screen.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-splash-screen.Tpo $(DEPDIR)/xfce4_session-xfsm-splash-screen.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-splash-screen.c' object='xfce4_session-xfsm-splash-screen.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-splash-screen.obj `if test -f 'xfsm-splash-screen.c'; then $(CYGPATH_W) 'xfsm-splash-screen.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-splash-screen.c'; fi`
+
+xfce4_session-xfsm-startup.o: xfsm-startup.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-startup.o -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-startup.Tpo -c -o xfce4_session-xfsm-startup.o `test -f 'xfsm-startup.c' || echo '$(srcdir)/'`xfsm-startup.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-startup.Tpo $(DEPDIR)/xfce4_session-xfsm-startup.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-startup.c' object='xfce4_session-xfsm-startup.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-startup.o `test -f 'xfsm-startup.c' || echo '$(srcdir)/'`xfsm-startup.c
+
+xfce4_session-xfsm-startup.obj: xfsm-startup.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-startup.obj -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-startup.Tpo -c -o xfce4_session-xfsm-startup.obj `if test -f 'xfsm-startup.c'; then $(CYGPATH_W) 'xfsm-startup.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-startup.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-startup.Tpo $(DEPDIR)/xfce4_session-xfsm-startup.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-startup.c' object='xfce4_session-xfsm-startup.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-startup.obj `if test -f 'xfsm-startup.c'; then $(CYGPATH_W) 'xfsm-startup.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-startup.c'; fi`
+
+xfce4_session-xfsm-upower.o: xfsm-upower.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-upower.o -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-upower.Tpo -c -o xfce4_session-xfsm-upower.o `test -f 'xfsm-upower.c' || echo '$(srcdir)/'`xfsm-upower.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-upower.Tpo $(DEPDIR)/xfce4_session-xfsm-upower.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-upower.c' object='xfce4_session-xfsm-upower.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-upower.o `test -f 'xfsm-upower.c' || echo '$(srcdir)/'`xfsm-upower.c
+
+xfce4_session-xfsm-upower.obj: xfsm-upower.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-upower.obj -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-upower.Tpo -c -o xfce4_session-xfsm-upower.obj `if test -f 'xfsm-upower.c'; then $(CYGPATH_W) 'xfsm-upower.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-upower.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-upower.Tpo $(DEPDIR)/xfce4_session-xfsm-upower.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-upower.c' object='xfce4_session-xfsm-upower.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-upower.obj `if test -f 'xfsm-upower.c'; then $(CYGPATH_W) 'xfsm-upower.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-upower.c'; fi`
+
+xfce4_session-xfsm-systemd.o: xfsm-systemd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-systemd.o -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-systemd.Tpo -c -o xfce4_session-xfsm-systemd.o `test -f 'xfsm-systemd.c' || echo '$(srcdir)/'`xfsm-systemd.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-systemd.Tpo $(DEPDIR)/xfce4_session-xfsm-systemd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-systemd.c' object='xfce4_session-xfsm-systemd.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-systemd.o `test -f 'xfsm-systemd.c' || echo '$(srcdir)/'`xfsm-systemd.c
+
+xfce4_session-xfsm-systemd.obj: xfsm-systemd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -MT xfce4_session-xfsm-systemd.obj -MD -MP -MF $(DEPDIR)/xfce4_session-xfsm-systemd.Tpo -c -o xfce4_session-xfsm-systemd.obj `if test -f 'xfsm-systemd.c'; then $(CYGPATH_W) 'xfsm-systemd.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-systemd.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xfce4_session-xfsm-systemd.Tpo $(DEPDIR)/xfce4_session-xfsm-systemd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='xfsm-systemd.c' object='xfce4_session-xfsm-systemd.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfce4_session_CFLAGS) $(CFLAGS) -c -o xfce4_session-xfsm-systemd.obj `if test -f 'xfsm-systemd.c'; then $(CYGPATH_W) 'xfsm-systemd.c'; else $(CYGPATH_W) '$(srcdir)/xfsm-systemd.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man1: $(man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(man_MANS)'; \
+ test -n "$(man1dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.1[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man1:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man1dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.1[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
+install-polkit_policyDATA: $(polkit_policy_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(polkit_policy_DATA)'; test -n "$(polkit_policydir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(polkit_policydir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(polkit_policydir)" || exit 1; \
+ fi; \
+ 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)$(polkit_policydir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(polkit_policydir)" || exit $$?; \
+ done
+
+uninstall-polkit_policyDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(polkit_policy_DATA)'; test -n "$(polkit_policydir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(polkit_policydir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ 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-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ 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"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+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) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(polkit_policydir)"; 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:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+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)
+ -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-binPROGRAMS clean-generic 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-man install-polkit_policyDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man1
+
+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-binPROGRAMS uninstall-man \
+ uninstall-polkit_policyDATA
+
+uninstall-man: uninstall-man1
+
+.MAKE: all check install install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
+ clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-binPROGRAMS \
+ 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-man1 \
+ install-pdf install-pdf-am install-polkit_policyDATA \
+ 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 tags-am uninstall uninstall-am uninstall-binPROGRAMS \
+ uninstall-man uninstall-man1 uninstall-polkit_policyDATA
+
+
+@HAVE_POLKIT_TRUE@@INTLTOOL_POLICY_RULE@
+@HAVE_POLKIT_TRUE@.in2.in:
+@HAVE_POLKIT_TRUE@ sed "s|[@]HELPER_PATH_PREFIX@|${HELPER_PATH_PREFIX}|" $< > $@
+
+@MAINTAINER_MODE_TRUE@xfsm-chooser-icon.h: $(srcdir)/xfsm-chooser-icon.png
+@MAINTAINER_MODE_TRUE@ $(AM_V_GEN) gdk-pixbuf-csource --static --raw --stream --name=xfsm_chooser_icon_data $< > $@
+
+@MAINTAINER_MODE_TRUE@xfsm-marshal.h: $(srcdir)/xfsm-marshal.list Makefile
+@MAINTAINER_MODE_TRUE@ $(AM_V_GEN) glib-genmarshal --prefix=xfsm_marshal --internal --header $< > $@
+
+@MAINTAINER_MODE_TRUE@xfsm-marshal.c: $(srcdir)/xfsm-marshal.list Makefile
+@MAINTAINER_MODE_TRUE@ $(AM_V_GEN) echo "#include <xfce4-session/xfsm-marshal.h>" > $@ \
+@MAINTAINER_MODE_TRUE@ && glib-genmarshal --prefix=xfsm_marshal --body $< >> $@
+
+@MAINTAINER_MODE_TRUE@xfsm-manager-dbus.h: $(srcdir)/xfsm-manager-dbus.xml
+@MAINTAINER_MODE_TRUE@ $(AM_V_GEN) dbus-binding-tool --mode=glib-server --prefix=xfsm_manager $< > $@
+
+@MAINTAINER_MODE_TRUE@xfsm-client-dbus.h: $(srcdir)/xfsm-client-dbus.xml
+@MAINTAINER_MODE_TRUE@ $(AM_V_GEN) dbus-binding-tool --mode=glib-server --prefix=xfsm_client $< > $@
+
+# vi:set ts=8 sw=8 noet ai nocindent syntax=automake:
+
+# 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/xfce4-session/ice-layer.c b/xfce4-session/ice-layer.c
new file mode 100644
index 0000000..9ae7473
--- /dev/null
+++ b/xfce4-session/ice-layer.c
@@ -0,0 +1,384 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2008 Brian Tarricone <bjt23@cornell.edu>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <X11/ICE/ICElib.h>
+#include <X11/ICE/ICEutil.h>
+#include <X11/SM/SMlib.h>
+
+#include <libxfce4util/libxfce4util.h>
+
+#include <xfce4-session/ice-layer.h>
+#include <xfce4-session/xfsm-global.h>
+#include <xfce4-session/xfsm-manager.h>
+
+typedef struct
+{
+ XfsmManager *manager;
+ IceConn ice_conn;
+} XfsmIceConnData;
+
+
+/* prototypes */
+static void ice_error_handler (IceConn);
+static gboolean ice_process_messages (GIOChannel *channel,
+ GIOCondition condition,
+ gpointer user_data);
+static gboolean ice_connection_accept (GIOChannel *channel,
+ GIOCondition condition,
+ gpointer watch_data);
+static FILE *ice_tmpfile (char **name);
+static void ice_auth_add (FILE *,
+ FILE *,
+ char *,
+ IceListenObj);
+
+static char *auth_cleanup_file;
+
+
+Bool
+ice_auth_proc (char *hostname)
+{
+ return False;
+}
+
+
+static void
+ice_error_handler (IceConn ice_conn)
+{
+ /*
+ * The I/O error handlers does whatever is necessary to respond
+ * to the I/O error and then returns, but it does not call
+ * IceCloseConnection. The ICE connection is given a "bad IO"
+ * status, and all future reads and writes to the connection
+ * are ignored. The next time IceProcessMessages is called it
+ * will return a status of IceProcessMessagesIOError. At that
+ * time, the application should call IceCloseConnection.
+ */
+ xfsm_verbose ("ICE connection fd = %d, ICE I/O error on connection\n",
+ IceConnectionNumber (ice_conn));
+}
+
+
+static gboolean
+ice_process_messages (GIOChannel *channel,
+ GIOCondition condition,
+ gpointer user_data)
+{
+ IceProcessMessagesStatus status;
+ XfsmIceConnData *icdata = user_data;
+
+ status = IceProcessMessages (icdata->ice_conn, NULL, NULL);
+
+ if (status == IceProcessMessagesIOError)
+ {
+ xfsm_manager_close_connection_by_ice_conn (icdata->manager,
+ icdata->ice_conn);
+
+ /* remove the I/O watch */
+ return FALSE;
+ }
+
+ /* keep the I/O watch running */
+ return TRUE;
+}
+
+
+static void
+ice_connection_watch (IceConn ice_conn,
+ IcePointer client_data,
+ Bool opening,
+ IcePointer *watch_data)
+{
+ XfsmManager *manager = XFSM_MANAGER (client_data);
+ GIOChannel *channel;
+ guint watchid;
+ gint fd;
+ gint ret;
+
+ if (opening)
+ {
+ XfsmIceConnData *icdata = g_new(XfsmIceConnData, 1);
+ icdata->manager = manager;
+ icdata->ice_conn = ice_conn;
+
+ fd = IceConnectionNumber (ice_conn);
+
+ /* Make sure we don't pass on these file descriptors to an
+ * exec'd child process.
+ */
+ ret = fcntl (fd, F_SETFD, fcntl (fd, F_GETFD, 0) | FD_CLOEXEC);
+ if (ret == -1)
+ {
+ perror ("ice_connection_watch: fcntl (fd, F_SETFD, fcntl (fd, F_GETFD, 0) | FD_CLOEXEC) failed");
+ }
+
+ channel = g_io_channel_unix_new (fd);
+ watchid = g_io_add_watch_full (channel, G_PRIORITY_DEFAULT,
+ G_IO_ERR | G_IO_HUP | G_IO_IN,
+ ice_process_messages,
+ icdata, (GDestroyNotify) g_free);
+ g_io_channel_unref (channel);
+
+ *watch_data = (IcePointer) GUINT_TO_POINTER (watchid);
+ }
+ else
+ {
+ watchid = GPOINTER_TO_UINT (*watch_data);
+ g_source_remove (watchid);
+ }
+}
+
+
+static gboolean
+ice_connection_accept (GIOChannel *channel,
+ GIOCondition condition,
+ gpointer watch_data)
+{
+ IceConnectStatus cstatus;
+ IceAcceptStatus astatus;
+ IceListenObj ice_listener = (IceListenObj) watch_data;
+ IceConn ice_conn;
+
+ ice_conn = IceAcceptConnection (ice_listener, &astatus);
+
+ if (astatus != IceAcceptSuccess)
+ {
+ g_warning ("Failed to accept ICE connection on listener %p",
+ (gpointer) ice_listener);
+ }
+ else
+ {
+ /* Wait for the connection to leave pending state */
+ do
+ {
+ IceProcessMessages (ice_conn, NULL, NULL);
+ }
+ while ((cstatus = IceConnectionStatus (ice_conn)) == IceConnectPending);
+
+ if (cstatus != IceConnectAccepted)
+ {
+ if (cstatus == IceConnectIOError)
+ {
+ g_warning ("I/O error opening ICE connection %p", (gpointer) ice_conn);
+ }
+ else
+ {
+ g_warning ("ICE connection %p rejected", (gpointer) ice_conn);
+ }
+
+ IceSetShutdownNegotiation (ice_conn, False);
+ IceCloseConnection (ice_conn);
+ }
+ }
+
+ return TRUE;
+}
+
+
+static FILE*
+ice_tmpfile (char **name)
+{
+ GError *error = NULL;
+ mode_t mode;
+ FILE *fp = NULL;
+ int fd;
+
+ mode = umask (0077);
+
+ fd = g_file_open_tmp(".xfsm-ICE-XXXXXX", name, &error);
+ if (fd < 0)
+ {
+ g_warning ("Unable to open temporary file: %s", error->message);
+ g_error_free (error);
+ }
+ else
+ {
+ fp = fdopen (fd, "wb");
+ }
+
+ umask (mode);
+
+ return fp;
+}
+
+
+static void
+fprintfhex (FILE *fp, int len, char *cp)
+{
+ static char hexchars[] = "0123456789abcdef";
+
+ for (; len > 0; len--, cp++)
+ {
+ unsigned char s = *cp;
+ putc (hexchars[s >> 4], fp);
+ putc (hexchars[s & 0x0f], fp);
+ }
+}
+
+
+static void
+ice_auth_add (FILE *setup_fp,
+ FILE *cleanup_fp,
+ char *protocol,
+ IceListenObj ice_listener)
+{
+ IceAuthDataEntry entry;
+
+ entry.protocol_name = protocol;
+ entry.network_id = IceGetListenConnectionString (ice_listener);
+ entry.auth_name = "MIT-MAGIC-COOKIE-1";
+ entry.auth_data = IceGenerateMagicCookie (16);
+ entry.auth_data_length = 16;
+
+ IceSetPaAuthData (1, &entry);
+
+ fprintf (setup_fp,
+ "add %s \"\" %s MIT-MAGIC-COOKIE-1 ",
+ protocol,
+ entry.network_id);
+ fprintfhex (setup_fp, 16, entry.auth_data);
+ fprintf (setup_fp, "\n");
+
+ fprintf (cleanup_fp,
+ "remove protoname=%s protodata=\"\" netid=%s authname=MIT-MAGIC-COOKIE-1\n",
+ protocol,
+ entry.network_id);
+
+ free (entry.network_id);
+ free (entry.auth_data);
+}
+
+
+gboolean
+ice_setup_listeners (int num_listeners,
+ IceListenObj *listen_objs,
+ XfsmManager *manager)
+{
+ GIOChannel *channel;
+ char *auth_setup_file;
+ gchar *command;
+ FILE *cleanup_fp;
+ FILE *setup_fp;
+ int fd;
+ int n;
+ int ret;
+
+ IceSetIOErrorHandler (ice_error_handler);
+ IceAddConnectionWatch (ice_connection_watch, manager);
+
+ cleanup_fp = ice_tmpfile(&auth_cleanup_file);
+ if (cleanup_fp == NULL)
+ return FALSE;
+
+ setup_fp = ice_tmpfile(&auth_setup_file);
+ if (setup_fp == NULL)
+ {
+ fclose (cleanup_fp);
+ unlink (auth_cleanup_file);
+ g_free (auth_cleanup_file);
+ return FALSE;
+ }
+
+ for (n = 0; n < num_listeners; n++)
+ {
+ fd = IceGetListenConnectionNumber (listen_objs[n]);
+
+ /* Make sure we don't pass on these file descriptors to an
+ * exec'd child process.
+ */
+ ret = fcntl (fd, F_SETFD, fcntl (fd, F_GETFD, 0) | FD_CLOEXEC);
+ if (ret == -1)
+ {
+ perror ("ice_setup_listeners: fcntl (fd, F_SETFD, fcntl (fd, F_GETFD, 0) | FD_CLOEXEC) failed");
+ }
+
+ channel = g_io_channel_unix_new (fd);
+ g_io_add_watch (channel, G_IO_ERR | G_IO_HUP | G_IO_IN,
+ ice_connection_accept,
+ listen_objs[n]);
+ g_io_channel_unref (channel);
+
+ /* setup auth for this listener */
+ ice_auth_add (setup_fp, cleanup_fp, "ICE", listen_objs[n]);
+ ice_auth_add (setup_fp, cleanup_fp, "XSMP", listen_objs[n]);
+ IceSetHostBasedAuthProc (listen_objs[n], ice_auth_proc);
+ }
+
+ fclose (setup_fp);
+ fclose (cleanup_fp);
+
+ /* setup ICE authority and remove setup file */
+ command = g_strdup_printf ("%s source %s", ICEAUTH_CMD, auth_setup_file);
+ if (system (command) != 0)
+ {
+ g_warning ("Failed to setup the ICE authentication data, session "
+ "management might not work properly.");
+ }
+ g_free (command);
+ unlink (auth_setup_file);
+ g_free (auth_setup_file);
+
+ return TRUE;
+}
+
+void
+ice_cleanup (void)
+{
+ gchar *command;
+
+ g_return_if_fail (auth_cleanup_file != NULL);
+
+ /* remove newly added ICE authority entries */
+ command = g_strdup_printf ("%s source %s", ICEAUTH_CMD, auth_cleanup_file);
+ if (system (command))
+ g_warning ("Failed to execute \"%s\"", command);
+ g_free (command);
+
+ /* remove the cleanup file, no longer needed */
+ unlink (auth_cleanup_file);
+ g_free (auth_cleanup_file);
+ auth_cleanup_file = NULL;
+}
+
+
diff --git a/xfce4-session/ice-layer.h b/xfce4-session/ice-layer.h
new file mode 100644
index 0000000..7e8d81b
--- /dev/null
+++ b/xfce4-session/ice-layer.h
@@ -0,0 +1,37 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifndef __XFSM_ICE_LAYER_H__
+#define __XFSM_ICE_LAYER_H__
+
+#include <X11/ICE/ICElib.h>
+
+#include <glib.h>
+
+#include <xfce4-session/xfsm-manager.h>
+
+Bool ice_auth_proc (char *hostname);
+gboolean ice_setup_listeners (int num_listeners,
+ IceListenObj *listen_objs,
+ XfsmManager *manager);
+void ice_cleanup (void);
+
+#endif /* !__XFSM_ICE_LAYER_H__ */
diff --git a/xfce4-session/main.c b/xfce4-session/main.c
new file mode 100644
index 0000000..0c27a55
--- /dev/null
+++ b/xfce4-session/main.c
@@ -0,0 +1,334 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2003-2006 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2008 Brian Tarricone <bjt23@cornell.edu>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <xfconf/xfconf.h>
+
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+
+#include <libxfce4util/libxfce4util.h>
+#include <libxfce4ui/libxfce4ui.h>
+
+#include <libxfsm/xfsm-util.h>
+
+#include <xfce4-session/ice-layer.h>
+#include <xfce4-session/sm-layer.h>
+#include <xfce4-session/xfsm-dns.h>
+#include <xfce4-session/xfsm-global.h>
+#include <xfce4-session/xfsm-manager.h>
+#include <xfce4-session/xfsm-shutdown.h>
+#include <xfce4-session/xfsm-startup.h>
+#include <xfce4-session/xfsm-error.h>
+
+static gboolean opt_disable_tcp = FALSE;
+static gboolean opt_version = FALSE;
+
+static GOptionEntry option_entries[] =
+{
+ { "disable-tcp", '\0', 0, G_OPTION_ARG_NONE, &opt_disable_tcp, N_("Disable binding to TCP ports"), NULL },
+ { "version", 'V', 0, G_OPTION_ARG_NONE, &opt_version, N_("Print version information and exit"), NULL },
+ { NULL }
+};
+
+static void
+setup_environment (void)
+{
+ const gchar *lang;
+ const gchar *sm;
+ gchar *authfile;
+ int fd;
+
+ /* check that no other session manager is running */
+ sm = g_getenv ("SESSION_MANAGER");
+ if (sm != NULL && strlen (sm) > 0)
+ {
+ g_printerr ("%s: Another session manager is already running\n", PACKAGE_NAME);
+ exit (EXIT_FAILURE);
+ }
+
+ /* check if running in verbose mode */
+ if (g_getenv ("XFSM_VERBOSE") != NULL)
+ xfsm_enable_verbose ();
+
+ /* pass correct DISPLAY to children, in case of --display in argv */
+ g_setenv ("DISPLAY", gdk_display_get_name (gdk_display_get_default ()), TRUE);
+
+ /* this is for compatibility with the GNOME Display Manager */
+ lang = g_getenv ("GDM_LANG");
+ if (lang != NULL && strlen (lang) > 0)
+ {
+ g_setenv ("LANG", lang, TRUE);
+ g_unsetenv ("GDM_LANG");
+ }
+
+ /* check access to $ICEAUTHORITY or $HOME/.ICEauthority if unset */
+ if (g_getenv ("ICEAUTHORITY"))
+ authfile = g_strdup (g_getenv ("ICEAUTHORITY"));
+ else
+ authfile = xfce_get_homefile (".ICEauthority", NULL);
+ fd = open (authfile, O_RDWR | O_CREAT, 0600);
+ if (fd < 0)
+ {
+ fprintf (stderr, "xfce4-session: Unable to access file %s: %s\n",
+ authfile, g_strerror (errno));
+ exit (EXIT_FAILURE);
+ }
+ g_free (authfile);
+ close (fd);
+}
+
+static void
+init_display (XfsmManager *manager,
+ GdkDisplay *dpy,
+ XfconfChannel *channel,
+ gboolean disable_tcp)
+{
+ gchar *engine;
+
+ engine = xfconf_channel_get_string (channel, "/splash/Engine", "mice");
+
+ splash_screen = xfsm_splash_screen_new (dpy, engine);
+ g_free (engine);
+ xfsm_splash_screen_next (splash_screen, _("Loading desktop settings"));
+
+ gdk_flush ();
+
+ sm_init (channel, disable_tcp, manager);
+
+ /* gtk resource files may have changed */
+ gtk_rc_reparse_all ();
+}
+
+
+static void
+xfsm_dbus_init (void)
+{
+ DBusGConnection *dbus_conn;
+ int ret;
+ GError *error = NULL;
+
+ xfsm_error_dbus_init ();
+
+ dbus_conn = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+ if (G_UNLIKELY (!dbus_conn))
+ {
+ g_critical ("Unable to contact D-Bus session bus: %s", error ? error->message : "Unknown error");
+ if (error)
+ g_error_free (error);
+ return;
+ }
+
+ ret = dbus_bus_request_name (dbus_g_connection_get_connection (dbus_conn),
+ "org.xfce.SessionManager",
+ DBUS_NAME_FLAG_DO_NOT_QUEUE,
+ NULL);
+ if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret)
+ {
+ g_printerr ("%s: Another session manager is already running\n", PACKAGE_NAME);
+ exit (EXIT_FAILURE);
+ }
+}
+
+static void
+xfsm_dbus_cleanup (void)
+{
+ DBusGConnection *dbus_conn;
+
+ /* this is all not really necessary, but... */
+
+ dbus_conn = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
+ if (G_UNLIKELY (!dbus_conn))
+ return;
+
+ dbus_bus_release_name (dbus_g_connection_get_connection (dbus_conn),
+ "org.xfce.SessionManager", NULL);
+}
+
+static gboolean
+xfsm_dbus_require_session (gint argc, gchar **argv)
+{
+ gchar **new_argv;
+ gchar *path;
+ gint i;
+ guint m = 0;
+
+ if (g_getenv ("DBUS_SESSION_BUS_ADDRESS") != NULL)
+ return TRUE;
+
+ path = g_find_program_in_path ("dbus-launch");
+ if (path == NULL)
+ {
+ g_critical ("dbus-launch not found, the desktop will not work properly!");
+ return TRUE;
+ }
+
+ /* avoid rondtrips */
+ g_assert (!g_str_has_prefix (*argv, "dbus-launch"));
+
+ new_argv = g_new0 (gchar *, argc + 4);
+ new_argv[m++] = path;
+ new_argv[m++] = "--sh-syntax";
+ new_argv[m++] = "--exit-with-session";
+
+ for (i = 0; i < argc; i++)
+ new_argv[m++] = argv[i];
+
+ if (!execvp ("dbus-launch", new_argv))
+ {
+ g_critical ("Could not spawn %s: %s", path, g_strerror (errno));
+ }
+
+ g_free (path);
+ g_free (new_argv);
+
+ return FALSE;
+}
+
+int
+main (int argc, char **argv)
+{
+ XfsmManager *manager;
+ GError *error = NULL;
+ GdkDisplay *dpy;
+ XfconfChannel *channel;
+ XfsmShutdownType shutdown_type;
+ XfsmShutdown *shutdown_helper;
+ gboolean succeed = TRUE;
+
+ if (!xfsm_dbus_require_session (argc, argv))
+ return EXIT_SUCCESS;
+
+ xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
+
+ /* install required signal handlers */
+ signal (SIGPIPE, SIG_IGN);
+
+ if (!gtk_init_with_args (&argc, &argv, "", option_entries, GETTEXT_PACKAGE, &error))
+ {
+ g_print ("%s: %s.\n", G_LOG_DOMAIN, error->message);
+ g_print (_("Type '%s --help' for usage."), G_LOG_DOMAIN);
+ g_print ("\n");
+ g_error_free (error);
+ return EXIT_FAILURE;
+ }
+
+ if (opt_version)
+ {
+ g_print ("%s %s (Xfce %s)\n\n", G_LOG_DOMAIN, PACKAGE_VERSION, xfce_version_string ());
+ g_print ("%s\n", "Copyright (c) 2003-2014");
+ g_print ("\t%s\n\n", _("The Xfce development team. All rights reserved."));
+ g_print (_("Please report bugs to <%s>."), PACKAGE_BUGREPORT);
+ g_print ("\n");
+
+ return EXIT_SUCCESS;
+ }
+
+ if (!xfconf_init (&error))
+ {
+ xfce_dialog_show_error (NULL, error, _("Unable to contact settings server"));
+ g_error_free (error);
+ }
+
+ /* fake a client id for the manager, so the legacy management does not
+ * recognize us to be a session client.
+ */
+ gdk_set_sm_client_id (xfsm_generate_client_id (NULL));
+
+ xfsm_dbus_init ();
+
+ manager = xfsm_manager_new ();
+ setup_environment ();
+
+ channel = xfsm_open_config ();
+
+ dpy = gdk_display_get_default ();
+ init_display (manager, dpy, channel, opt_disable_tcp);
+
+ if (!opt_disable_tcp && xfconf_channel_get_bool (channel, "/security/EnableTcp", FALSE))
+ {
+ /* verify that the DNS settings are ok */
+ xfsm_splash_screen_next (splash_screen, _("Verifying DNS settings"));
+ xfsm_dns_check ();
+ }
+
+ xfsm_splash_screen_next (splash_screen, _("Loading session data"));
+
+ xfsm_startup_init (channel);
+ xfsm_manager_load (manager, channel);
+ xfsm_manager_restart (manager);
+
+ gtk_main ();
+
+ xfsm_startup_shutdown ();
+
+ shutdown_type = xfsm_manager_get_shutdown_type (manager);
+
+ /* take over the ref before we release the manager */
+ shutdown_helper = xfsm_shutdown_get ();
+
+ g_object_unref (manager);
+ g_object_unref (channel);
+
+ xfsm_dbus_cleanup ();
+ ice_cleanup ();
+
+ if (shutdown_type == XFSM_SHUTDOWN_SHUTDOWN
+ || shutdown_type == XFSM_SHUTDOWN_RESTART)
+ {
+ succeed = xfsm_shutdown_try_type (shutdown_helper, shutdown_type, &error);
+ if (!succeed)
+ g_warning ("Failed to shutdown/restart: %s", ERROR_MSG (error));
+ }
+
+ g_object_unref (shutdown_helper);
+
+ return succeed ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/xfce4-session/org.xfce.session.policy.in2 b/xfce4-session/org.xfce.session.policy.in2
new file mode 100644
index 0000000..7f7c5ae
--- /dev/null
+++ b/xfce4-session/org.xfce.session.policy.in2
@@ -0,0 +1,34 @@
+<?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>
+
+ <!--
+ Policy definitions for XFCE Session Manager system-wide actions.
+ Copyright (c) 2014 Eric Koegel <eric@xfce.org>
+ Based on the XFCE Power Manager policy file.
+ -->
+
+ <vendor>XFCE Session Manager</vendor>
+ <vendor_url>http://xfce.org/</vendor_url>
+ <icon_name>xfce4-session</icon_name>
+
+
+ <action id="org.xfce.session.xfsm-shutdown-helper">
+ <!-- SECURITY:
+ - A normal active user on the local machine does not need permission
+ to suspend or hibernate their system.
+ -->
+ <_description>Shutdown, restart, suspend, or hibernate the system</_description>
+ <_message>Authentication is required to shutdown, restart, suspend, or hibernate the system.</_message>
+ <defaults>
+ <allow_any>auth_admin</allow_any>
+ <allow_inactive>auth_admin</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ <annotate key="org.freedesktop.policykit.exec.path">@HELPER_PATH_PREFIX@/xfce4/session/xfsm-shutdown-helper</annotate>
+ </action>
+
+</policyconfig>
+
diff --git a/xfce4-session/sm-layer.c b/xfce4-session/sm-layer.c
new file mode 100644
index 0000000..5428569
--- /dev/null
+++ b/xfce4-session/sm-layer.c
@@ -0,0 +1,431 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <X11/ICE/ICElib.h>
+#include <X11/SM/SMlib.h>
+
+#include <libxfce4util/libxfce4util.h>
+
+#include <xfce4-session/ice-layer.h>
+#include <xfce4-session/sm-layer.h>
+#include <xfce4-session/xfsm-global.h>
+#include <xfce4-session/xfsm-manager.h>
+
+#define XFSM_CLIENT_MANAGER(c) (XFSM_MANAGER (g_object_get_data (G_OBJECT (c), "--xfsm-manager")))
+
+#ifdef HAVE__ICETRANSNOLISTEN
+extern void _IceTransNoListen (char *protocol);
+#endif
+
+/* local prototypes */
+static Status sm_new_client (SmsConn sms_conn,
+ SmPointer manager_data,
+ unsigned long *mask,
+ SmsCallbacks *callbacks,
+ char **failure_reason);
+static Status sm_register_client (SmsConn sms_conn,
+ SmPointer client_data,
+ char *previous_id);
+static void sm_interact_request (SmsConn sms_conn,
+ SmPointer client_data,
+ int dialog_type);
+static void sm_interact_done (SmsConn sms_conn,
+ SmPointer client_data,
+ Bool cancel_shutdown);
+static void sm_save_yourself_request (SmsConn sms_conn,
+ SmPointer client_data,
+ int save_type,
+ Bool shutdown,
+ int interact_style,
+ Bool fast,
+ Bool global);
+static void sm_save_yourself_phase2_request(SmsConn sms_conn,
+ SmPointer client_data);
+static void sm_save_yourself_done (SmsConn sms_conn,
+ SmPointer client_data,
+ Bool success);
+static void sm_close_connection (SmsConn sms_conn,
+ SmPointer client_data,
+ int num_reasons,
+ char **reasons);
+static void sm_set_properties (SmsConn sms_conn,
+ SmPointer client_data,
+ int num_props,
+ SmProp **props);
+static void sm_delete_properties (SmsConn sms_conn,
+ SmPointer client_data,
+ int num_props,
+ char **prop_names);
+static void sm_get_properties (SmsConn sms_conn,
+ SmPointer client_data);
+
+
+#define SET_CALLBACK(_callbacks, _callback, _client) \
+G_STMT_START{ \
+ _callbacks->_callback.callback = sm_##_callback; \
+ _callbacks->_callback.manager_data = (SmPointer) _client; \
+}G_STMT_END
+
+
+static int num_listeners;
+static IceListenObj *listen_objs;
+
+
+void
+sm_init (XfconfChannel *channel,
+ gboolean disable_tcp,
+ XfsmManager *manager)
+{
+ char *network_idlist;
+ char error[2048];
+
+ if (disable_tcp || !xfconf_channel_get_bool (channel, "/security/EnableTcp", FALSE))
+ {
+#ifdef HAVE__ICETRANSNOLISTEN
+ _IceTransNoListen ("tcp");
+#else
+ fprintf (stderr,
+ "xfce4-session: Requested to disable tcp connections, but "
+ "_IceTransNoListen is not available on this plattform. "
+ "Request will be ignored.\n");
+ xfsm_verbose ("_IceTransNoListen unavailable on this platform");
+#endif
+ }
+
+ if (!SmsInitialize (PACKAGE, VERSION, sm_new_client, manager, ice_auth_proc,
+ 2048, error))
+ {
+ fprintf (stderr, "xfce4-session: Unable to register XSM protocol: %s\n", error);
+ /* log to verbose so we don't have to look at both files */
+ xfsm_verbose ("xfce4-session: Unable to register XSM protocol: %s\n", error);
+ exit (EXIT_FAILURE);
+ }
+
+ if (!IceListenForConnections (&num_listeners, &listen_objs, 2048, error))
+ {
+ fprintf (stderr, "xfce4-session: Unable to establish ICE listeners: %s\n", error);
+ /* log to verbose so we don't have to look at both files */
+ xfsm_verbose ("xfce4-session: Unable to establish ICE listeners: %s\n", error);
+ exit (EXIT_FAILURE);
+ }
+
+ ice_setup_listeners (num_listeners, listen_objs, manager);
+
+ network_idlist = IceComposeNetworkIdList (num_listeners, listen_objs);
+ g_setenv ("SESSION_MANAGER", network_idlist, TRUE);
+ free (network_idlist);
+}
+
+
+static Status
+sm_new_client (SmsConn sms_conn,
+ SmPointer manager_data,
+ unsigned long *mask,
+ SmsCallbacks *callbacks,
+ char **failure_reason)
+{
+ XfsmManager *manager = XFSM_MANAGER (manager_data);
+ XfsmClient *client;
+ gchar *error = NULL;
+
+ xfsm_verbose ("ICE connection fd = %d, received NEW CLIENT\n\n",
+ IceConnectionNumber (SmsGetIceConnection (sms_conn)));
+
+ client = xfsm_manager_new_client (manager, sms_conn, &error);
+ if (client == NULL)
+ {
+ xfsm_verbose ("NEW CLIENT failed: %s\n", error);
+
+#ifdef HAVE_STRDUP
+ *failure_reason = strdup (error);
+#else
+ *failure_reason = (char *) malloc (strlen (error) + 1);
+ if (*failure_reason != NULL)
+ strcpy (*failure_reason, error);
+#endif
+
+ return False;
+ }
+
+ SET_CALLBACK (callbacks, register_client, client);
+ SET_CALLBACK (callbacks, interact_request, client);
+ SET_CALLBACK (callbacks, interact_done, client);
+ SET_CALLBACK (callbacks, save_yourself_request, client);
+ SET_CALLBACK (callbacks, save_yourself_phase2_request, client);
+ SET_CALLBACK (callbacks, save_yourself_done, client);
+ SET_CALLBACK (callbacks, close_connection, client);
+ SET_CALLBACK (callbacks, set_properties, client);
+ SET_CALLBACK (callbacks, delete_properties, client);
+ SET_CALLBACK (callbacks, get_properties, client);
+
+ *mask = SmsRegisterClientProcMask | SmsInteractRequestProcMask
+ | SmsInteractDoneProcMask | SmsSaveYourselfRequestProcMask
+ | SmsSaveYourselfP2RequestProcMask | SmsSaveYourselfDoneProcMask
+ | SmsCloseConnectionProcMask | SmsSetPropertiesProcMask
+ | SmsDeletePropertiesProcMask | SmsGetPropertiesProcMask;
+
+ g_object_set_data (G_OBJECT (client), "--xfsm-manager", manager);
+
+ return True;
+}
+
+
+static Status
+sm_register_client (SmsConn sms_conn,
+ SmPointer client_data,
+ char *previous_id)
+{
+ XfsmClient *client = (XfsmClient *) client_data;
+ Status result;
+
+ xfsm_verbose ("ICE connection fd = %d, received REGISTER CLIENT [Previous Id = %s]\n\n",
+ IceConnectionNumber (SmsGetIceConnection (sms_conn)),
+ previous_id != NULL ? previous_id : "None");
+
+ result = xfsm_manager_register_client (XFSM_CLIENT_MANAGER (client), client, previous_id);
+
+ if (previous_id != NULL)
+ free (previous_id);
+
+ return result;
+}
+
+
+static void
+sm_interact_request (SmsConn sms_conn,
+ SmPointer client_data,
+ int dialog_type)
+{
+ XfsmClient *client = (XfsmClient *) client_data;
+
+ xfsm_verbose ("Client Id = %s, received INTERACT REQUEST [Dialog type = %s]\n\n",
+ xfsm_client_get_id (client), dialog_type == SmDialogError ? "Error" : "Normal");
+
+ xfsm_manager_interact (XFSM_CLIENT_MANAGER (client), client, dialog_type);
+}
+
+
+static void
+sm_interact_done (SmsConn sms_conn,
+ SmPointer client_data,
+ Bool cancel_shutdown)
+{
+ XfsmClient *client = (XfsmClient *) client_data;
+
+ xfsm_verbose ("Client Id = %s, received INTERACT DONE [Cancel shutdown = %s]\n\n",
+ xfsm_client_get_id (client), cancel_shutdown ? "True" : "False");
+
+ xfsm_manager_interact_done (XFSM_CLIENT_MANAGER (client), client, cancel_shutdown);
+}
+
+
+static void
+sm_save_yourself_request (SmsConn sms_conn,
+ SmPointer client_data,
+ int save_type,
+ Bool shutdown,
+ int interact_style,
+ Bool fast,
+ Bool global)
+{
+ XfsmClient *client = (XfsmClient *) client_data;
+
+ if (G_UNLIKELY (verbose))
+ {
+ xfsm_verbose ("Client Id = %s, received SAVE YOURSELF REQUEST\n",
+ xfsm_client_get_id (client));
+ xfsm_verbose (" Save type: %s\n",
+ save_type == SmSaveLocal ? "Local"
+ : (save_type == SmSaveGlobal ? "Global" : "Both"));
+ xfsm_verbose (" Shutdown: %s\n", shutdown ? "True" : "False");
+ xfsm_verbose (" Interact Style: %s\n",
+ interact_style == SmInteractStyleNone ? "None"
+ : (interact_style == SmInteractStyleErrors ? "Errors" : "Any"));
+ xfsm_verbose (" Fast: %s\n", fast ? "True" : "False");
+ xfsm_verbose (" Global: %s\n", global ? "True" : "False");
+ xfsm_verbose ("\n");
+ }
+
+ xfsm_manager_save_yourself (XFSM_CLIENT_MANAGER (client), client, save_type, shutdown, interact_style, fast, global);
+}
+
+
+static void
+sm_save_yourself_phase2_request (SmsConn sms_conn,
+ SmPointer client_data)
+{
+ XfsmClient *client = (XfsmClient *) client_data;
+
+ xfsm_verbose ("Client Id = %s, received SAVE YOURSELF PHASE2 REQUEST\n\n",
+ xfsm_client_get_id (client));
+
+ xfsm_manager_save_yourself_phase2 (XFSM_CLIENT_MANAGER (client), client);
+}
+
+
+static void
+sm_save_yourself_done (SmsConn sms_conn,
+ SmPointer client_data,
+ Bool success)
+{
+ XfsmClient *client = (XfsmClient *) client_data;
+
+ xfsm_verbose ("Client Id = %s, received SAVE YOURSELF DONE [Success = %s]\n\n",
+ xfsm_client_get_id (client), success ? "True" : "False");
+
+ xfsm_manager_save_yourself_done (XFSM_CLIENT_MANAGER (client), client, success);
+}
+
+
+static void
+sm_close_connection (SmsConn sms_conn,
+ SmPointer client_data,
+ int num_reasons,
+ char **reasons)
+{
+ XfsmClient *client = (XfsmClient *) client_data;
+ gint n;
+
+ if (G_UNLIKELY (verbose))
+ {
+ xfsm_verbose ("Client Id = %s, received CLOSE CONNECTION [Num reasons = %d]\n",
+ xfsm_client_get_id (client), num_reasons);
+ for (n = 0; n < num_reasons; ++n)
+ xfsm_verbose (" Reason %2d: %s\n", n, reasons[n]);
+ xfsm_verbose ("\n");
+ }
+
+ xfsm_manager_close_connection (XFSM_CLIENT_MANAGER (client), client, TRUE);
+
+ if (num_reasons > 0)
+ SmFreeReasons (num_reasons, reasons);
+}
+
+
+static void
+sm_set_properties (SmsConn sms_conn,
+ SmPointer client_data,
+ int num_props,
+ SmProp **props)
+{
+ XfsmClient *client = (XfsmClient *) client_data;
+ int n;
+ int i;
+
+ if (G_UNLIKELY (verbose))
+ {
+ xfsm_verbose ("Client Id = %s, received SET PROPERTIES [Num props = %d]\n",
+ xfsm_client_get_id (client), num_props);
+ for (n = 0; n < num_props; ++n)
+ {
+ xfsm_verbose (" Name: %s\n", props[n]->name);
+ xfsm_verbose (" Type: %s\n", props[n]->type);
+ if (strcmp (props[n]->type, "ARRAY8") == 0)
+ {
+ xfsm_verbose (" Value: %s\n", (const gchar *) props[n]->vals->value);
+ }
+ else if (strcmp (props[n]->type, "CARD8") == 0)
+ {
+ const guint8 *cardptr = (const guint8 *) props[n]->vals->value;
+ xfsm_verbose (" Value: %u\n", (unsigned) *cardptr);
+ }
+ else if (strcmp (props[n]->type, "LISTofARRAY8") == 0)
+ {
+ xfsm_verbose (" Value:\n");
+ for (i = 0; i < props[n]->num_vals; ++i)
+ {
+ xfsm_verbose (" %s%s\n", (const gchar *) props[n]->vals[i].value,
+ (i == props[n]->num_vals - 1) ? "" : ",");
+ }
+ }
+ xfsm_verbose ("\n");
+ }
+ xfsm_verbose ("\n");
+ }
+
+ xfsm_client_merge_properties (client, props, num_props);
+
+ while (num_props-- > 0)
+ SmFreeProperty (props[num_props]);
+ free (props);
+}
+
+
+static void
+sm_delete_properties (SmsConn sms_conn,
+ SmPointer client_data,
+ int num_props,
+ char **prop_names)
+{
+ XfsmClient *client = (XfsmClient *) client_data;
+ int n;
+
+ if (G_UNLIKELY (verbose))
+ {
+ xfsm_verbose ("Client Id = %s, received DELETE PROPERTIES [Num props = %d]\n",
+ xfsm_client_get_id (client), num_props);
+ for (n = 0; n < num_props; ++n)
+ xfsm_verbose (" Name: %s\n", prop_names[n]);
+ xfsm_verbose ("\n");
+ }
+
+ xfsm_client_delete_properties (client, prop_names, num_props);
+
+ while (num_props-- > 0)
+ free (prop_names[num_props]);
+ free (prop_names);
+}
+
+
+static void
+sm_get_properties (SmsConn sms_conn,
+ SmPointer client_data)
+{
+ XfsmClient *client = (XfsmClient *) client_data;
+ XfsmProperties *properties = xfsm_client_get_properties (client);
+ SmProp **props = NULL;
+ gint num_props = 0;
+
+ xfsm_verbose ("Client Id = %s, received GET PROPERTIES\n\n", properties->client_id);
+
+ xfsm_properties_extract (properties, &num_props, &props);
+
+ SmsReturnProperties (sms_conn, num_props, props);
+
+ if (num_props > 0)
+ {
+ while (num_props-- > 0)
+ SmFreeProperty (props[num_props]);
+ free (props);
+ }
+}
diff --git a/xfce4-session/sm-layer.h b/xfce4-session/sm-layer.h
new file mode 100644
index 0000000..fc50487
--- /dev/null
+++ b/xfce4-session/sm-layer.h
@@ -0,0 +1,34 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifndef __SM_LAYER_H__
+#define __SM_LAYER_H__
+
+#include <xfconf/xfconf.h>
+#include <libxfce4util/libxfce4util.h>
+
+#include <xfce4-session/xfsm-manager.h>
+
+void sm_init (XfconfChannel *channel,
+ gboolean disable_tcp,
+ XfsmManager *manager);
+
+#endif /* !__SM_LAYER_H__ */
diff --git a/xfce4-session/xfce4-session.1 b/xfce4-session/xfce4-session.1
new file mode 100644
index 0000000..47cc135
--- /dev/null
+++ b/xfce4-session/xfce4-session.1
@@ -0,0 +1,84 @@
+.TH xfce4-session 1 "Sep 28, 2014"
+.SH NAME
+xfce4-session \- Starts up the Xfce Desktop Environment
+.SH SYNOPSIS
+.B xfce4-session
+.br
+.SH DESCRIPTION
+This manual page documents briefly the
+.B xfce4-session
+command.
+.PP
+The \fBxfce4-session\fP program starts up the Xfce Desktop Environment and
+is typically executed by your login manager (e.g. xdm, gdm, kdm, wdm or from
+your X startup scripts). It will load your last session or a default session
+that includes the standard Xfce programs if no saved session is available.
+
+\fBxfce4-session\fP is an standard X11R6 session manager that can manage
+any X11R6 SM compliant program, including GNOME and KDE programs.
+
+\fBxfce4-session\fP uses the contents of the ~/.cache/sessions/ directory
+for starting previously saved sessions.
+
+
+.SH OPTIONS
+\fBxfce4-session\fP takes the following command line options:
+.TP
+.B \-\-disable\-tcp
+Disable binding to TCP ports in the ICE layer. This is not possible on every
+platform. If you use this option on a platform that does not support it,
+\fBxfce4-session\fP will print a warning message and ignore the setting.
+.TP
+.B \-\-help
+Print a help screen and exit.
+.TP
+.B \-\-version
+Output version information and exit.
+
+
+.SH ENVIRONMENT
+\fBxfce4-session\fP's behaviour is affected by the following environment
+variables.
+.PP
+.TP
+.B XDG_CONFIG_HOME
+Specifies the root for all user-specific configuration files. If this
+environment variable is unset, it defaults to
+.I ~/.config/
+.TP
+.B XDG_CONFIG_DIRS
+Set of preference ordered base directories relative to which configuration
+files should be searched in addition to the
+.B $XDG_CONFIG_HOME
+base directory. The directories should be separated with a colon.
+.TP
+.B XDG_CACHE_HOME
+Specifies the root for all user-specific cache data. If this environment
+variable is unset, it defaults to
+.I ~/.cache/
+.TP
+.B XFSM_VERBOSE
+When defined, this environment variable enables debugging messages to be
+saved to
+.I ~/.xfce4-session.verbose-log
+The log file from the last session run with this environment variable
+set is retained at
+.I ~/.xfce4-session.verbose-log.last
+These debugging messages are useful for troubleshooting and development.
+
+.SH FILES
+\fBxfce4-session\fP reads its configuration from Xfconf.
+\fBxfce4-session\fP stores its session data into
+.IR $XDG_CACHE_HOME/sessions/ .
+
+.SH AUTHOR
+\fBxfce4-session\fP was written by Benedikt Meurer
+<benny@xfce.org> as part of the Xfce project.
+This manual page was written by Oliver M. Bolzer <oliver@debian.org>
+and Benedikt Meurer <benny@xfce.org>.
+
+.SH "REPORTING BUGS"
+Report bugs to http://bugzilla.xfce.org/.
+
+.SH COPYRIGHT
+Copyright \(co 2003-2014 Benedikt Meurer.
diff --git a/xfce4-session/xfsm-chooser-icon.h b/xfce4-session/xfsm-chooser-icon.h
new file mode 100644
index 0000000..9718ac5
--- /dev/null
+++ b/xfce4-session/xfsm-chooser-icon.h
@@ -0,0 +1,327 @@
+/* GdkPixbuf RGBA C-Source image dump */
+
+#ifdef __SUNPRO_C
+#pragma align 4 (xfsm_chooser_icon_data)
+#endif
+#ifdef __GNUC__
+static const guint8 xfsm_chooser_icon_data[] __attribute__ ((__aligned__ (4))) =
+#else
+static const guint8 xfsm_chooser_icon_data[] =
+#endif
+{ ""
+ /* Pixbuf magic (0x47646b50) */
+ "GdkP"
+ /* length: header (24) + pixel_data (8736) */
+ "\0\0\"8"
+ /* pixdata_type (0x1010002) */
+ "\1\1\0\2"
+ /* rowstride (208) */
+ "\0\0\0\320"
+ /* width (52) */
+ "\0\0\0""4"
+ /* height (42) */
+ "\0\0\0*"
+ /* pixel_data: */
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0!!-\0!!-\0\37\37*\2\23\23\32\5\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0!!-\0!!-\0\32\32#\2\21\21\27\6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0!!-\0!!-\1!!-\4!!-\13&'4\33\247\255\265r\232\237\243\243\17\17\24"
+ "\11\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0!!-\0!!-\1!!-\4!!"
+ "-\12!\".\24*,;%\252\262\274\207\225\234\243\250\15\15\22\17\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0!!-\0!"
+ "!-\1!!-\5!!-\13&'4\25""78J&RTkB\243\251\267\220\367\371\372\374\364\366"
+ "\370\375lpuu\26\26\37\2\0\0\0\0\0\0\0\0\0\0\0\0!!-\0!!-\1!!-\5!!-\15"
+ "$%2\31""24G,LPiF\217\227\252\207\334\346\356\373\335\347\357\377\223"
+ "\233\242\252\15\15\22\17\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0!!-\1!!-\4!!-\10''5\17""67I\31ILa(cf\200@\203\207\242a\261\267\307"
+ "\242\367\371\372\374\374\375\376\377\372\374\375\377\336\342\345\362"
+ "\77BGB\35\35'\0!!-\0!!-\2!!-\6##0\15+,<\26<\77T&V[v@{\202\242d\245\256"
+ "\307\230\330\342\353\366\336\350\360\377\334\347\357\377\331\345\356"
+ "\377\221\232\241\253\15\15\22\20\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0!!-\0!!-\1!!-\3!!-\6()7\14""9"
+ ":M\30KMa,NPYYkn\211J\226\232\265l\276\302\326\220\320\325\341\303\367"
+ "\371\373\375\374\375\376\377\372\374\375\377\370\372\374\377\366\371"
+ "\373\377\300\305\312\330\23\23\27\35!!-\5!!-\14'(7\27<\77T(X^z\77|\205"
+ "\250^\244\256\314\203\306\316\341\254\330\342\353\362\336\350\360\377"
+ "\333\347\357\377\331\345\356\377\327\344\355\377\325\342\354\377\221"
+ "\232\242\254\15\15\22\20\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0!!-\0!!-\2!!-\7&&4\20""77I\40NPf:qt\217cz{\212"
+ "\263rsz\320\251\253\264\274\335\342\350\326\370\371\373\376\374\375\376"
+ "\377\372\374\375\377\370\372\374\377\366\371\373\377\364\367\372\377"
+ "\361\366\371\377\230\236\243\256\24\24\34\16!!-\15\"\".\31,->-\77BXK"
+ "Z_zv}\205\246\245X\\e\353ptx\377\330\343\353\377\331\345\356\377\327"
+ "\344\355\377\325\342\354\377\325\342\354\377\325\342\354\377\222\233"
+ "\242\256\15\15\22\20\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0!!-\0!!-\3!!-\12##0\26""12B'GG\\Ahh\202c\221\222\256\215"
+ "\247\251\275\274\220\222\230\361\202\202\202\377\247\247\250\377\345"
+ "\346\347\377\370\372\374\377\366\371\373\377\364\367\372\377\362\366"
+ "\371\377\360\365\370\377\350\356\363\375lqvz\40\40,\26%&5/24EZILb\225"
+ "**-\356kpy\361=\77@\377\37\40\40\377\300\312\322\377\327\344\355\377"
+ "\325\342\354\377\325\342\354\377\316\332\344\377\325\342\353\377\325"
+ "\342\354\377\222\233\243\256\14\14\20\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0!!-\0!!-\2!!-\6\"#/\17""12C\36KMb3mp\214O\224\227\263"
+ "t\300\303\327\236\331\334\347\311\355\360\363\374\354\355\355\377\250"
+ "\251\252\377jjj\377\246\247\250\377\360\363\366\377\362\366\371\377\360"
+ "\365\370\377\356\363\367\377\354\362\366\377\324\334\341\3649<C`\"#0"
+ "<*+:l9:L\256\36\36\37\375''(\377EHJ\377\20\21\21\377\256\270\300\377"
+ "\325\342\354\377\325\342\354\377\304\320\331\377\203\213\221\377\230"
+ "\241\250\377\324\341\353\377\200\210\217\266\14\14\20\20\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0!!-\1!!-\4!!-\13()7\26<>S'Z]"
+ "wA\201\205\243c\256\262\312\212\324\327\346\262\327\333\342\342\365\370"
+ "\372\377\367\371\373\377\333\336\340\377z{|\377tuv\377\340\345\350\377"
+ "\356\363\367\377\354\362\366\377\352\360\365\377\350\357\364\377\270"
+ "\277\306\337\34\35&R%%3uORa\304)+,\375\20\20\20\377\22\22\23\377\5\5"
+ "\5\377\37\40\"\377IMP\377{\202\210\377\237\251\260\377bgl\377\263\276"
+ "\307\377\220\231\240\305\12\12\16\34!!-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0!!-\1!!-\6!!-\15&&4\32""68J-QTkIuy\226"
+ "k\236\243\276\220\303\307\332\271\315\322\334\352\364\370\372\377\364"
+ "\367\372\377\354\360\364\377\226\230\232\377]^_\377\305\311\315\377\213"
+ "\216\220\377}\200\202\377\231\235\241\377\273\302\307\377{\200\210\324"
+ "\77AQ\302\213\222\232\372\16\16\16\377\10\10\10\377\3\3\3\377\11\11\12"
+ "\377kqv\377\0\0\0\377\0\0\0\377\6\7\7\377\\ae\377\225\236\246\324\16"
+ "\17\23'\40\40+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0!!-\0!!-\4!!-\12\"\".\27/0@,EG]Igj\206o\225\232"
+ "\270\236\276\303\330\314\321\327\340\366\361\366\371\377\360\364\370"
+ "\377\354\362\366\377\217\222\225\377333\377---\377'''\377\"\"\"\377\34"
+ "\34\34\377\30\30\31\377\26\26\27\376\13\13\14\377\2\2\2\377\0\0\0\377"
+ "\0\0\0\377$%'\377135\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\14\14"
+ "\16z\32\32#\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0!!-\0!!-\2!!-\7!!-\21&'4\"23D9DEZVZ^x{|\201"
+ "\240\245\236\244\277\320\315\324\336\370\356\363\367\377\354\362\366"
+ "\377moq\377+++\377%%%\377\37\37\37\377\30\30\30\377\13\13\13\377\2\2"
+ "\2\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
+ "\0\0\377\31\32\33\377\1\1\1\377\0\0\0\377\1\1\1\374\13\13\16}\25\25\35"
+ "\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0!!-\0!!-\0!!-\1!!-\5!!-\15!\".\32##0-()7H68JmMPh\233"
+ "im\206\316\311\320\331\372\337\345\352\377++,\377\"\"\"\377\34\34\34"
+ "\377\14\14\14\377\1\1\1\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"
+ "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\23\24\24\377DGJ\377\20\21\21\377"
+ "\3\3\4\364\13\13\16\246\17\17\24\40\31\31\"\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0!!-\0!!-\2!!-\7!!-\22!!-\"!\".;%%3`.0@\223KN^\322\246"
+ "\254\262\375\40\40\40\377\30\30\30\377\4\4\4\377\0\0\0\377\0\0\0\377"
+ "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
+ "\0\0\0\377\0\0\0\377\34\35\36\375\10\10\11\321\16\16\22f\20\20\27\21"
+ "\31\31!\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0!!-\0!!-\1!!-\2!!-\5"
+ "!!-\14!!-\34!!-/!!-G!!-m##0\242,-6\343\27\27\27\377\3\3\3\377\0\0\0\377"
+ "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
+ "\0\0\0\377\0\0\0\377\0\0\0\377\21\22\23\374\32\33\36\233\17\17\25\37"
+ "\25\25\35\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0!!-\0!!-\1!!-\4!!-\16!!-\32!!-+!!-T!!-\222\37\37(\330\11"
+ "\11\11\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
+ "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\2\2\2\367"
+ "\15\15\20""9\31\31!\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0!!-\0!!-\2!!-\5!!-\13!!-\23!!-\33!!--!!-_\"\""
+ ".\255\21\21\25\364\3\3\3\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
+ "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"
+ "\12\13\13\376\1\1\1\375\4\4\4\321\22\22\27\21\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0!!-\0!!-\3!!-\6!!-\14"
+ "!!-\25!!-\"!!-;!!-j\40\40+\263\20\20\24\361\6\6\7\375\4\4\4\37758:\377"
+ "\40\"#\377\13\14\14\377\4\4\4\377\2\2\2\377\4\4\5\377\13\14\15\377\32"
+ "\33\34\377\14\15\15\377\0\0\0\377\20\21\22\377>AE\313\13\13\15\222\17"
+ "\17\23/\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0!!-\0!!-\2!!-\5!!-\14!!.\25&(9$14G:AE\\\\[a\177\221nv\222\321"
+ "\11\12\13\376afk\377\301\314\325\377\306\322\333\377\267\302\313\377"
+ "\253\265\275\377\244\256\266\377\250\262\272\377\260\272\303\377\272"
+ "\306\316\377\266\301\311\377cim\377\27\30\31\377JNR\374gmt~\23\23\33"
+ "\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0!!"
+ "-\0!!-\3!!-\11$%3\22""03F\37BH_1Zb\177J{\204\241m\237\247\301\231\275"
+ "\305\331\310\273\305\321\364\202\211\216\377\306\322\333\377\325\342"
+ "\354\377\325\342\354\377\325\342\354\377\325\342\354\377\325\342\354"
+ "\377\325\342\354\377\325\342\354\377\325\342\354\377\325\342\354\377"
+ "\324\341\352\377\303\317\330\377\254\267\277\377\311\326\337\370\\ag"
+ "b\27\27\40\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0!!-\0!!-\1!!-\4!!-\11$(9"
+ "\23""1<T$E]}\77e\216\257j\261\322\337\313Y|\237\202\224\266\326\234\300"
+ "\334\356\310\255\330\350\362\220\307\333\377\323\337\351\377\325\342"
+ "\354\377\304\336\353\377\302\335\352\377\275\334\351\377\271\332\351"
+ "\377\262\330\350\377\320\335\347\377\325\342\354\377\325\342\354\377"
+ "\325\342\354\377\325\342\354\377\311\334\350\377\266\331\350\377\251"
+ "\310\325\377\303\317\331\361\200\245\264\207\244\325\346\177\221\314"
+ "\340~~\304\333}l\276\330z6}\224B\31\31#\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0!!-\0!!-"
+ "\0!!-\1!!-\4!!.\11&+;\21""6@W\40L`}6i\206\245V\214\257\313\177\247\320"
+ "\345\254\330\357\367\357\336\364\373\377\206\277\324\343\205\313\344"
+ "\303\252\332\352\356h\313\352\377G\301\346\377\200\273\321\377\323\340"
+ "\352\377\330\361\370\377\323\360\371\377\267\347\366\377\233\336\362"
+ "\377v\321\355\377\256\271\301\377\325\342\354\377\325\342\354\377\314"
+ "\336\351\377\302\340\354\377\276\350\365\377\245\341\363\377z\264\307"
+ "\377\322\337\351\377\312\345\360\377\323\360\371\377\267\347\366\377"
+ "\234\336\362\377\201\325\357\3775w\214\240\32\32$\1\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0!!-\0!!-\1!!-\5!!-\14\"%5\30""08O*FVtBd\201\244_\217\262\320\205\274"
+ "\333\354\261\310\346\360\340\323\357\367\376\301\352\367\377\241\340"
+ "\363\377{\275\320\366t\314\350\377I\302\347\377+\270\344\377F\224\255"
+ "\377\315\332\343\377\270\346\364\377\256\344\365\377\216\331\357\377"
+ "n\314\351\377N\302\345\377\254\267\277\377\325\342\354\377\311\336\352"
+ "\377\323\355\365\377\307\354\370\377\235\336\362\377s\320\355\377N\256"
+ "\314\377\313\327\341\377\274\341\357\377\265\346\365\377\227\334\362"
+ "\377\\\247\277\356L\244\300\346\40^s\220\32\32#\1\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0!!-\0!!-\0!!-\3!!-\12!#1\24&2H%4Mj>Iy\240bl\257\322\217\230\330"
+ "\355\275\233\326\345\352\237\336\362\377\206\327\357\377e\313\352\377"
+ "J\303\350\377,\271\344\3776\223\261\377\273\306\317\377\324\341\353\377"
+ "\230\333\360\377\211\330\360\377b\251\300\377\244\260\271\376|\206\216"
+ "\346\306\321\331\365\314\337\352\377\321\355\366\377\277\352\367\377"
+ "\224\333\361\377n\267\316\377\215\267\307\377\270\310\322\377\323\340"
+ "\352\377\256\334\355\377\227\334\361\377v\321\355\377\10\27\37e\23\23"
+ "\33\32\22\22\30\15\33\33&\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0!!-\1!!-\5!!-\13!\"1\25\"/F'*Ef@:m\227eP\245\317\221w\321\354\301x"
+ "\311\337\360h\315\353\377K\303\350\377-\271\344\377*\230\272\377\260"
+ "\275\306\377\325\342\354\377\324\341\353\377x\321\354\377d\313\353\377"
+ "H\263\324\377S\250\305\366R\261\323\333\304\331\343\330\267\333\350\374"
+ "\267\347\366\377\215\331\360\377o\254\301\377\307\323\334\377\325\342"
+ "\354\377\325\342\354\377\325\342\354\377\240\330\353\377y\322\356\377"
+ "]\311\352\3777\263\332\365\37\260\335\355\10!,>\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0!!-\0!!-\2!!-\6!!-\15!&7\32$8R10V|P\77\211\270"
+ "zZ\275\342\252\203\332\357\327\231\322\345\373K\302\347\377.\271\344"
+ "\377\21\260\340\377!\245\316\377\302\324\337\377\325\342\354\377\324"
+ "\341\353\377X\306\350\377@\277\346\377$\266\343\377\12\255\337\377\5"
+ "\236\315\374\226\305\322\323\236\336\360\367\205\326\357\377[\310\352"
+ "\377\226\262\276\377\325\342\354\377\325\342\354\377\325\342\354\377"
+ "\325\342\354\377\222\323\351\377[\310\352\377\77\277\346\377$\266\343"
+ "\377\12\255\337\377\6\34%P\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0!!-\0!!-\4!!-\15!%7\33\"7S1+T{N:\203\257tQ\270\337\242v\332\361\316"
+ "\227\324\347\371M\303\347\377/\272\344\377\24\252\330\377\1\252\336\377"
+ "\0\252\336\3777\253\321\377\313\331\343\377\324\341\353\3778\273\344"
+ "\377\33\263\341\377\6\232\310\371\10\202\253\342\17\205\252\345j\302"
+ "\327\316p\321\353\365S\306\351\377)\270\343\377l\254\302\377\322\337"
+ "\351\377\325\342\354\377\325\342\354\377\325\342\354\377\205\316\350"
+ "\377=\276\346\377!\265\342\377b\226\250\377n\241\264\371\22\30\35P\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0!!-\0!!-\1!!-\6!!-\17!'9\34!7T2#R{"
+ "T+\200\256~7\267\340\256I\320\356\337J\302\346\3760\272\344\377\32\246"
+ "\321\377\204\241\255\377&\257\332\377\0\252\336\377\0\252\336\377K\256"
+ "\316\377\317\334\346\377\30\261\340\377\2\253\336\377\2\203\254\345\37"
+ "Ls`'\203\262\202/\274\345\2646\310\351\351!\265\342\377\4\253\337\377"
+ "\2\251\335\3772\255\324\377U\270\331\377R\271\333\377\253\305\322\377"
+ "w\312\346\377\37\264\342\377\7\254\337\377Z\253\306\377/\211\246\323"
+ "\6i\213K\30\30!\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0!!-\1!!-\3!!-\7!!/\21!*B"
+ "\40!;_5#V\204S,\201\262{;\264\337\255C\277\341\3410\271\343\377\24\256"
+ "\335\377g\225\246\377\322\337\350\377\266\323\341\377\21\253\333\377"
+ "\0\252\336\377A\216\250\377\307\324\336\376\7\252\334\376\0\252\336\377"
+ "\2\203\254\341\35""8[A\"[\216X\"\211\276\206\40\270\344\273\10\255\334"
+ "\366\0\252\336\377\0\252\336\377\0\252\336\377\0\252\336\377\0\252\336"
+ "\377\220\261\300\377i\305\344\377\5\254\337\377\0\252\336\377\0\252\336"
+ "\377\0\252\336\377\2j\213\252\27\27\37\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "!!-\0!!-\1!!-\2!!-\6!$2\15!/B\27%<W&.Ot:9l\224ZJ\216\267\2040\233\304"
+ "\310%\177\237\347\260\277\314\346\325\342\354\377\325\342\354\377\233"
+ "\312\335\377;\223\260\377\300\313\324\377t\210\227\322\1\236\317\364"
+ "\0\237\320\372\2|\242\331\33!3+!6X5\"P\177Q\"y\260x\36\241\321\250\16"
+ "\241\316\333\6\241\321\366\5\246\327\376\7\247\330\377\24\244\320\377"
+ "\234\270\305\377j\301\337\377\10\235\313\376\1\232\311\371\1\232\312"
+ "\367\1\232\312\366\3a\177\244\27\27\37\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0!!-\0!!-\1!!-\3!!-\7\"#0\16*-=\27:@U&NWr>`i\204"
+ "b\214\227\264\203\270\304\322\331\325\342\354\377\325\342\354\377\316"
+ "\333\345\377\240\252\262\330\17\21\31*\15\20\31(\13\13\20""2\12\12\16"
+ ")\34\34'\10!!.\15!$3\26'.B\"3\77W4GVsRav\230|\204\222\252\260\300\314"
+ "\326\372\313\327\341\377\323\340\352\377\302\316\327\370:>C\210\17\22"
+ "\32/\16\20\27+\16\16\24*\16\16\23\33\31\31#\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0!!-\0!!-\1!!-\2!!-\5!!.\13"
+ "&(6\26""14F%CG^<Y_y_\266\301\315\322\325\342\354\377\271\304\315\355"
+ "%'+D\35\35'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0!!-\1!!-\5!!-\13!!-\23'"
+ ")8!8;O7RXrV\216\227\250\241\324\341\353\376\310\324\336\370QU[{\22\22"
+ "\31\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0!!-\0!!-\3!!-\7!!-\14##0\27""7:G9\260\273\304\311EIOl\26\26\36"
+ "\2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0!!-\0!!-\0!!-\1!!-"
+ "\3!!-\11\"#/\23()8)\234\245\256\237RV\\|\22\22\30\6\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0!!-\0!!-\0!!-\1\17\17\25\16\20\20\26\6\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0!!-\0!!-\0!!-\1\24\24\34\5\23\23\32\4\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
+ "\0\0\0\0"};
+
+
diff --git a/xfce4-session/xfsm-chooser-icon.png b/xfce4-session/xfsm-chooser-icon.png
new file mode 100644
index 0000000..7bb5979
--- /dev/null
+++ b/xfce4-session/xfsm-chooser-icon.png
Binary files differ
diff --git a/xfce4-session/xfsm-chooser.c b/xfce4-session/xfsm-chooser.c
new file mode 100644
index 0000000..7f7c1e9
--- /dev/null
+++ b/xfce4-session/xfsm-chooser.c
@@ -0,0 +1,239 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2004 Benedikt Meurer <benny@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+#include <libxfce4util/libxfce4util.h>
+#include <libxfce4ui/libxfce4ui.h>
+
+#include <libxfsm/xfsm-splash-engine.h>
+#include <libxfsm/xfsm-util.h>
+
+#include <xfce4-session/xfsm-chooser.h>
+
+
+#define BORDER 6
+
+
+static void xfsm_chooser_row_activated (GtkTreeView *treeview,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ XfsmChooser *chooser);
+static void xfsm_chooser_realized (GtkWidget *widget,
+ XfsmChooser *chooser);
+
+
+enum
+{
+ PREVIEW_COLUMN,
+ NAME_COLUMN,
+ TITLE_COLUMN,
+ ATIME_COLUMN,
+ N_COLUMNS,
+};
+
+
+
+G_DEFINE_TYPE (XfsmChooser, xfsm_chooser, GTK_TYPE_DIALOG)
+
+
+
+void
+xfsm_chooser_set_sessions (XfsmChooser *chooser,
+ GList *sessions,
+ const gchar *default_session)
+{
+ XfsmSessionInfo *session;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gchar *accessed;
+ gchar *title;
+ GList *lp;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (chooser->tree));
+ gtk_list_store_clear (GTK_LIST_STORE (model));
+
+ for (lp = sessions; lp != NULL; lp = lp->next)
+ {
+ session = (XfsmSessionInfo *) lp->data;
+
+ accessed = g_strdup_printf (_("Last accessed: %s"),
+ ctime (&session->atime));
+ title = g_strdup_printf ("<b><big>%s</big></b>\n"
+ "<small><i>%s</i></small>",
+ session->name, accessed);
+
+ gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+ PREVIEW_COLUMN, session->preview,
+ NAME_COLUMN, session->name,
+ TITLE_COLUMN, title,
+ ATIME_COLUMN, session->atime,
+ -1);
+
+ g_free (accessed);
+ g_free (title);
+ }
+}
+
+
+gchar*
+xfsm_chooser_get_session (const XfsmChooser *chooser)
+{
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GValue value;
+ gchar *name;
+
+ bzero (&value, sizeof (value));
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (chooser->tree));
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ g_warning ("xfsm_chooser_get_session: !gtk_tree_selection_get_selected");
+ return NULL;
+ }
+ gtk_tree_model_get_value (model, &iter, NAME_COLUMN, &value);
+ name = g_value_dup_string (&value);
+ g_value_unset (&value);
+
+ return name;
+}
+
+
+static void
+xfsm_chooser_class_init (XfsmChooserClass *klass)
+{
+}
+
+
+static void
+xfsm_chooser_init (XfsmChooser *chooser)
+{
+ GtkTreeSelection *selection;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+ GtkListStore *model;
+ GtkWidget *button;
+ GtkWidget *swin;
+ GtkWidget *dbox;
+
+ dbox = GTK_DIALOG (chooser)->vbox;
+
+ gtk_dialog_set_has_separator (GTK_DIALOG (chooser), FALSE);
+ g_signal_connect_after (G_OBJECT (chooser), "realize",
+ G_CALLBACK (xfsm_chooser_realized), chooser);
+
+ /* scrolled window */
+ swin = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
+ GTK_POLICY_NEVER,
+ GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin),
+ GTK_SHADOW_ETCHED_IN);
+ gtk_box_pack_start (GTK_BOX (dbox), swin, TRUE, TRUE, 0);
+ gtk_widget_show (swin);
+
+ /* tree view */
+ model = gtk_list_store_new (N_COLUMNS,
+ GDK_TYPE_PIXBUF,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_INT);
+ chooser->tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL(model));
+ g_object_unref (G_OBJECT (model));
+ gtk_widget_set_tooltip_text (chooser->tree,
+ _("Choose the session you want to restore. "
+ "You can simply double-click the session "
+ "name to restore it."));
+
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (chooser->tree), FALSE);
+ column = gtk_tree_view_column_new ();
+ renderer = gtk_cell_renderer_pixbuf_new ();
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
+ gtk_tree_view_column_set_attributes (column, renderer,
+ "pixbuf", PREVIEW_COLUMN,
+ NULL);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_column_set_attributes (column, renderer,
+ "markup", TITLE_COLUMN,
+ NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (chooser->tree), column);
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (chooser->tree));
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
+ g_signal_connect (G_OBJECT (chooser->tree), "row-activated",
+ G_CALLBACK (xfsm_chooser_row_activated), chooser);
+ gtk_container_add (GTK_CONTAINER (swin), chooser->tree);
+ gtk_widget_set_size_request (chooser->tree, -1, 150);
+ gtk_widget_show (chooser->tree);
+
+ /* "Logout" button */
+ button = xfce_gtk_button_new_mixed (GTK_STOCK_QUIT, _("Log out"));
+ gtk_widget_set_tooltip_text (button,
+ _("Cancel the login attempt and return to "
+ "the login screen."));
+ gtk_dialog_add_action_widget (GTK_DIALOG (chooser), button,
+ GTK_RESPONSE_CANCEL);
+ gtk_widget_show (button);
+
+ /* "New" button */
+ button = xfce_gtk_button_new_mixed (GTK_STOCK_NEW, _("New session"));
+ gtk_widget_set_tooltip_text (button, _("Create a new session."));
+ gtk_dialog_add_action_widget (GTK_DIALOG (chooser), button,
+ XFSM_RESPONSE_NEW);
+ gtk_widget_show (button);
+}
+
+
+static void
+xfsm_chooser_row_activated (GtkTreeView *treeview,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ XfsmChooser *chooser)
+{
+ gtk_dialog_response (GTK_DIALOG (chooser), XFSM_RESPONSE_LOAD);
+}
+
+
+static void
+xfsm_chooser_realized (GtkWidget *widget,
+ XfsmChooser *chooser)
+{
+ GdkCursor *cursor;
+
+ cursor = gdk_cursor_new (GDK_LEFT_PTR);
+ gdk_window_set_cursor (widget->window, cursor);
+ gdk_cursor_unref (cursor);
+}
+
diff --git a/xfce4-session/xfsm-chooser.h b/xfce4-session/xfsm-chooser.h
new file mode 100644
index 0000000..e75f60a
--- /dev/null
+++ b/xfce4-session/xfsm-chooser.h
@@ -0,0 +1,64 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2004 Benedikt Meurer <benny@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifndef __XFSM_CHOOSER_H__
+#define __XFSM_CHOOSER_H__
+
+#include <gtk/gtk.h>
+
+
+G_BEGIN_DECLS;
+
+#define XFSM_TYPE_CHOOSER xfsm_chooser_get_type()
+#define XFSM_CHOOSER(obj) G_TYPE_CHECK_INSTANCE_CAST(obj, XFSM_TYPE_CHOOSER, XfsmChooser)
+#define XFSM_CHOOSER_CLASS(klass) G_TYPE_CHECK_CLASS_CAST(klass, XFSM_TYPE_CHOOSER, XfsmChooserClass)
+#define XFSM_IS_CHOOSER(obj) G_TYPE_CHECK_INSTANCE_TYPE(obj, XFSM_TYPE_CHOOSER)
+
+#define XFSM_RESPONSE_LOAD 1
+#define XFSM_RESPONSE_NEW 2
+
+typedef struct _XfsmChooser XfsmChooser;
+typedef struct _XfsmChooserClass XfsmChooserClass;
+
+struct _XfsmChooserClass
+{
+ GtkDialogClass parent_class;
+};
+
+struct _XfsmChooser
+{
+ GtkDialog dialog;
+
+ GtkWidget *tree;
+};
+
+GType xfsm_chooser_get_type (void) G_GNUC_CONST;
+
+void xfsm_chooser_set_sessions (XfsmChooser *chooser,
+ GList *sessions,
+ const gchar *default_session);
+
+gchar *xfsm_chooser_get_session (const XfsmChooser *chooser);
+
+G_END_DECLS;
+
+
+#endif /* !__XFSM_CHOOSER_H__ */
diff --git a/xfce4-session/xfsm-client-dbus.h b/xfce4-session/xfsm-client-dbus.h
new file mode 100644
index 0000000..91f6de2
--- /dev/null
+++ b/xfce4-session/xfsm-client-dbus.h
@@ -0,0 +1,268 @@
+/* Generated by dbus-binding-tool; do not edit! */
+
+
+#ifndef __dbus_glib_marshal_xfsm_client_MARSHAL_H__
+#define __dbus_glib_marshal_xfsm_client_MARSHAL_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#ifdef G_ENABLE_DEBUG
+#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
+#define g_marshal_value_peek_char(v) g_value_get_schar (v)
+#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
+#define g_marshal_value_peek_int(v) g_value_get_int (v)
+#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
+#define g_marshal_value_peek_long(v) g_value_get_long (v)
+#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
+#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
+#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
+#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
+#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
+#define g_marshal_value_peek_float(v) g_value_get_float (v)
+#define g_marshal_value_peek_double(v) g_value_get_double (v)
+#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
+#define g_marshal_value_peek_param(v) g_value_get_param (v)
+#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
+#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
+#define g_marshal_value_peek_object(v) g_value_get_object (v)
+#define g_marshal_value_peek_variant(v) g_value_get_variant (v)
+#else /* !G_ENABLE_DEBUG */
+/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
+ * Do not access GValues directly in your code. Instead, use the
+ * g_value_get_*() functions
+ */
+#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
+#define g_marshal_value_peek_char(v) (v)->data[0].v_int
+#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
+#define g_marshal_value_peek_int(v) (v)->data[0].v_int
+#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
+#define g_marshal_value_peek_long(v) (v)->data[0].v_long
+#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
+#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
+#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
+#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
+#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
+#define g_marshal_value_peek_float(v) (v)->data[0].v_float
+#define g_marshal_value_peek_double(v) (v)->data[0].v_double
+#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer
+#endif /* !G_ENABLE_DEBUG */
+
+
+/* BOOLEAN:POINTER */
+extern void dbus_glib_marshal_xfsm_client_BOOLEAN__POINTER (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+void
+dbus_glib_marshal_xfsm_client_BOOLEAN__POINTER (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+{
+ typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER) (gpointer data1,
+ gpointer arg_1,
+ gpointer data2);
+ register GMarshalFunc_BOOLEAN__POINTER callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+ gboolean v_return;
+
+ g_return_if_fail (return_value != NULL);
+ g_return_if_fail (n_param_values == 2);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_BOOLEAN__POINTER) (marshal_data ? marshal_data : cc->callback);
+
+ v_return = callback (data1,
+ g_marshal_value_peek_pointer (param_values + 1),
+ data2);
+
+ g_value_set_boolean (return_value, v_return);
+}
+
+/* BOOLEAN:POINTER,POINTER */
+extern void dbus_glib_marshal_xfsm_client_BOOLEAN__POINTER_POINTER (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+void
+dbus_glib_marshal_xfsm_client_BOOLEAN__POINTER_POINTER (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+{
+ typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER_POINTER) (gpointer data1,
+ gpointer arg_1,
+ gpointer arg_2,
+ gpointer data2);
+ register GMarshalFunc_BOOLEAN__POINTER_POINTER callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+ gboolean v_return;
+
+ g_return_if_fail (return_value != NULL);
+ g_return_if_fail (n_param_values == 3);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_BOOLEAN__POINTER_POINTER) (marshal_data ? marshal_data : cc->callback);
+
+ v_return = callback (data1,
+ g_marshal_value_peek_pointer (param_values + 1),
+ g_marshal_value_peek_pointer (param_values + 2),
+ data2);
+
+ g_value_set_boolean (return_value, v_return);
+}
+
+/* BOOLEAN:BOXED,POINTER,POINTER */
+extern void dbus_glib_marshal_xfsm_client_BOOLEAN__BOXED_POINTER_POINTER (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+void
+dbus_glib_marshal_xfsm_client_BOOLEAN__BOXED_POINTER_POINTER (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+{
+ typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_POINTER_POINTER) (gpointer data1,
+ gpointer arg_1,
+ gpointer arg_2,
+ gpointer arg_3,
+ gpointer data2);
+ register GMarshalFunc_BOOLEAN__BOXED_POINTER_POINTER callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+ gboolean v_return;
+
+ g_return_if_fail (return_value != NULL);
+ g_return_if_fail (n_param_values == 4);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_BOOLEAN__BOXED_POINTER_POINTER) (marshal_data ? marshal_data : cc->callback);
+
+ v_return = callback (data1,
+ g_marshal_value_peek_boxed (param_values + 1),
+ g_marshal_value_peek_pointer (param_values + 2),
+ g_marshal_value_peek_pointer (param_values + 3),
+ data2);
+
+ g_value_set_boolean (return_value, v_return);
+}
+
+/* BOOLEAN:BOXED,POINTER */
+extern void dbus_glib_marshal_xfsm_client_BOOLEAN__BOXED_POINTER (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+void
+dbus_glib_marshal_xfsm_client_BOOLEAN__BOXED_POINTER (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+{
+ typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED_POINTER) (gpointer data1,
+ gpointer arg_1,
+ gpointer arg_2,
+ gpointer data2);
+ register GMarshalFunc_BOOLEAN__BOXED_POINTER callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+ gboolean v_return;
+
+ g_return_if_fail (return_value != NULL);
+ g_return_if_fail (n_param_values == 3);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_BOOLEAN__BOXED_POINTER) (marshal_data ? marshal_data : cc->callback);
+
+ v_return = callback (data1,
+ g_marshal_value_peek_boxed (param_values + 1),
+ g_marshal_value_peek_pointer (param_values + 2),
+ data2);
+
+ g_value_set_boolean (return_value, v_return);
+}
+
+G_END_DECLS
+
+#endif /* __dbus_glib_marshal_xfsm_client_MARSHAL_H__ */
+
+#include <dbus/dbus-glib.h>
+static const DBusGMethodInfo dbus_glib_xfsm_client_methods[] = {
+ { (GCallback) xfsm_client_dbus_get_id, dbus_glib_marshal_xfsm_client_BOOLEAN__POINTER_POINTER, 0 },
+ { (GCallback) xfsm_client_dbus_get_state, dbus_glib_marshal_xfsm_client_BOOLEAN__POINTER_POINTER, 44 },
+ { (GCallback) xfsm_client_dbus_get_all_sm_properties, dbus_glib_marshal_xfsm_client_BOOLEAN__POINTER_POINTER, 94 },
+ { (GCallback) xfsm_client_dbus_get_sm_properties, dbus_glib_marshal_xfsm_client_BOOLEAN__BOXED_POINTER_POINTER, 163 },
+ { (GCallback) xfsm_client_dbus_set_sm_properties, dbus_glib_marshal_xfsm_client_BOOLEAN__BOXED_POINTER, 236 },
+ { (GCallback) xfsm_client_dbus_delete_sm_properties, dbus_glib_marshal_xfsm_client_BOOLEAN__BOXED_POINTER, 298 },
+ { (GCallback) xfsm_client_dbus_terminate, dbus_glib_marshal_xfsm_client_BOOLEAN__POINTER, 355 },
+};
+
+const DBusGObjectInfo dbus_glib_xfsm_client_object_info = { 1,
+ dbus_glib_xfsm_client_methods,
+ 7,
+"org.xfce.Session.Client\0GetID\0S\0id\0O\0F\0N\0s\0\0org.xfce.Session.Client\0GetState\0S\0state\0O\0F\0N\0u\0\0org.xfce.Session.Client\0GetAllSmProperties\0S\0properties\0O\0F\0N\0a{sv}\0\0org.xfce.Session.Client\0GetSmProperties\0S\0names\0I\0as\0values\0O\0F\0N\0a{sv}\0\0org.xfce.Session.Client\0SetSmProperties\0S\0properties\0I\0a{sv}\0\0org.xfce.Session.Client\0DeleteSmProperties\0S\0names\0I\0as\0\0org.xfce.Session.Client\0Terminate\0S\0\0\0",
+"org.xfce.Session.Client\0StateChanged\0org.xfce.Session.Client\0SmPropertyChanged\0org.xfce.Session.Client\0SmPropertyDeleted\0\0",
+"\0"
+};
+
diff --git a/xfce4-session/xfsm-client-dbus.xml b/xfce4-session/xfsm-client-dbus.xml
new file mode 100644
index 0000000..6d1ead4
--- /dev/null
+++ b/xfce4-session/xfsm-client-dbus.xml
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<node name="/org/xfce/SessionClients">
+ <interface name="org.xfce.Session.Client">
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol"
+ value="xfsm_client_dbus"/>
+ <annotation name="org.freedesktop.DBus.GLib.ClientCSymbol"
+ value="xfsm_client_dbus_client"/>
+
+ <!--
+ String org.xfce.Session.Client.GetID()
+
+ Retrieves the client's SM client ID.
+ -->
+ <method name="GetID">
+ <arg direction="out" name="id" type="s"/>
+ </method>
+
+ <!--
+ Unsigned Int org.xfce.Session.Client.GetState()
+
+ Queries the session manager for a client's state.
+ Valid states are:
+ 0 Idle: the client is operating normally.
+ 1 Interacting: the client is interacting with the
+ user as part of the shutdown process.
+ 2 Save Done: the client has finished saving its state.
+ 3 Saving: the client is saving its state.
+ 4 Saving Local: the client is saving its local state
+ (as opposed to global state).
+ 5 Wait for Interact: the client is waiting for the
+ session manager to allow it to interact with the
+ user.
+ 6 Wait for Phase 2: the client is waiting for the
+ session manager to enter Phase 2 so it can continue
+ saving its state.
+ 7 Disconnected: the client has disconnected from the
+ session mananger (depending on its restart style,
+ it may still remain in the session after
+ disconnecting).
+ -->
+ <method name="GetState">
+ <arg direction="out" name="state" type="u"/>
+ </method>
+
+ <!--
+ Dict[] org.xfce.Session.Client.GetAllSmProperties()
+
+ Retrieves all session management properties set on
+ the client.
+ -->
+ <method name="GetAllSmProperties">
+ <arg direction="out" name="properties" type="a{sv}"/>
+ </method>
+
+ <!--
+ Dict[] org.xfce.Session.Client.GetSmProperties(String[] names)
+
+ @names: A string array of property names to fetch.
+
+ Retrieves the values of one or more SM propertis as an
+ array of variants.
+ -->
+ <method name="GetSmProperties">
+ <arg direction="in" name="names" type="as"/>
+ <arg direction="out" name="values" type="a{sv}"/>
+ </method>
+
+ <!--
+ void org.xfce.Session.Client.SetSmProperties(HashArray properties)
+
+ @properties: A hash array of properties, with string
+ keys and variant values.
+
+ Sets properties specified in the hash array. Other
+ properties are not affected.
+
+ Implementation note: properties may be validated in
+ sequence, so an error return from this method may
+ indicate that some properties have been set, but
+ others have not.
+ -->
+ <method name="SetSmProperties">
+ <arg direction="in" name="properties" type="a{sv}"/>
+ </method>
+
+ <!--
+ void org.xfce.Session.Client.DeleteSmProperties(String[] names)
+
+ @names: An string array of property names.
+
+ Deletes one or more SM properties.
+
+ Implementation note: Some properties defined in the
+ XSMP spec have defined semantics and default values.
+ This properties may not actually be deleted, but simply
+ reset to their default values.
+ -->
+ <method name="DeleteSmProperties">
+ <arg direction="in" name="names" type="as"/>
+ </method>
+
+ <!--
+ void org.xfce.Session.Client.Terminate()
+
+ Instructs the client to exit. Whether or not the client
+ remains in the session depends on its restart hint
+ SM property. If the restart hint is RestartImmediately,
+ the client will likely indeed be restarted immediately.
+
+ To actually remove a running client from the running
+ session, it's best to set the restart hint SM property
+ to RestartIfRunning before calling Terminate.
+ -->
+ <method name="Terminate"/>
+
+ <!--
+ void org.xfce.Session.Client.StateChanged(Unsigned Int old_state,
+ Unsigned Int new_state)
+
+ @old_state: The client's previous state.
+ @new_state: The client's new (current) state.
+
+ Emitted when a client changes state. See GetState() above
+ for valid state values.
+ -->
+ <signal name="StateChanged">
+ <arg name="old_state" type="u"/>
+ <arg name="new_state" type="u"/>
+ </signal>
+
+ <!--
+ void org.xfce.Session.Client.SmPropertyChanged(String name,
+ Variant value)
+
+ @name: The name of a property.
+ @value: the value of the named property.
+
+ Emitted when a property changes. The new value is included
+ in the message for convenience.
+ -->
+ <signal name="SmPropertyChanged">
+ <arg name="name" type="s"/>
+ <arg name="value" type="v"/>
+ </signal>
+
+ <!--
+ void org.xfce.Session.Client.SmPropertyDeleted(String name)
+
+ @name: The name of a property.
+
+ Emitted when a property is deleted.
+
+ Implementation note: this message should be rare;
+ most SM properties are defined with default values and
+ will merely be reset to their default upon deletion
+ (resulting in a SmPropertyChanged signal instead).
+ -->
+ <signal name="SmPropertyDeleted">
+ <arg name="name" type="s"/>
+ </signal>
+ </interface>
+</node>
diff --git a/xfce4-session/xfsm-client.c b/xfce4-session/xfsm-client.c
new file mode 100644
index 0000000..0455c6c
--- /dev/null
+++ b/xfce4-session/xfsm-client.c
@@ -0,0 +1,601 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2008 Brian Tarricone <bjt23@cornell.edu>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <dbus/dbus-glib.h>
+
+#include <libxfsm/xfsm-util.h>
+
+#include <xfce4-session/xfsm-client.h>
+#include <xfce4-session/xfsm-manager.h>
+#include <xfce4-session/xfsm-global.h>
+#include <xfce4-session/xfsm-marshal.h>
+#include <xfce4-session/xfsm-error.h>
+
+#define XFSM_CLIENT_OBJECT_PATH_PREFIX "/org/xfce/SessionClients/"
+
+struct _XfsmClient
+{
+ GObject parent;
+
+ XfsmManager *manager;
+
+ gchar *id;
+ gchar *object_path;
+
+ XfsmClientState state;
+ XfsmProperties *properties;
+ SmsConn sms_conn;
+
+ DBusGConnection *dbus_conn;
+};
+
+typedef struct _XfsmClientClass
+{
+ GObjectClass parent;
+
+ /*< signals >*/
+ void (*state_changed) (XfsmClient *client,
+ XfsmClientState old_state,
+ XfsmClientState new_state);
+
+ void (*sm_property_changed) (XfsmClient *client,
+ const gchar *name,
+ const GValue *value);
+
+ void (*sm_property_deleted) (XfsmClient *client,
+ const gchar *name);
+} XfsmClientClass;
+
+typedef struct
+{
+ SmProp *props;
+ gint count;
+} HtToPropsData;
+
+enum
+{
+ SIG_STATE_CHANGED = 0,
+ SIG_SM_PROPERTY_CHANGED,
+ SIG_SM_PROPERTY_DELETED,
+ N_SIGS
+};
+
+
+static void xfsm_client_finalize (GObject *obj);
+
+static void xfsm_properties_discard_command_changed (XfsmProperties *properties,
+ gchar **old_discard);
+static void xfsm_client_dbus_class_init (XfsmClientClass *klass);
+static void xfsm_client_dbus_init (XfsmClient *client);
+static void xfsm_client_dbus_cleanup (XfsmClient *client);
+
+
+static guint signals[N_SIGS] = { 0, };
+
+
+G_DEFINE_TYPE(XfsmClient, xfsm_client, G_TYPE_OBJECT)
+
+
+static void
+xfsm_client_class_init (XfsmClientClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+
+ gobject_class->finalize = xfsm_client_finalize;
+
+ signals[SIG_STATE_CHANGED] = g_signal_new ("state-changed",
+ XFSM_TYPE_CLIENT,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (XfsmClientClass,
+ state_changed),
+ NULL, NULL,
+ xfsm_marshal_VOID__UINT_UINT,
+ G_TYPE_NONE, 2,
+ G_TYPE_UINT, G_TYPE_UINT);
+
+ signals[SIG_SM_PROPERTY_CHANGED] = g_signal_new ("sm-property-changed",
+ XFSM_TYPE_CLIENT,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (XfsmClientClass,
+ sm_property_changed),
+ NULL, NULL,
+ xfsm_marshal_VOID__STRING_BOXED,
+ G_TYPE_NONE, 2,
+ G_TYPE_STRING, G_TYPE_VALUE);
+
+ signals[SIG_SM_PROPERTY_DELETED] = g_signal_new ("sm-property-deleted",
+ XFSM_TYPE_CLIENT,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (XfsmClientClass,
+ sm_property_deleted),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ xfsm_client_dbus_class_init (klass);
+}
+
+
+static void
+xfsm_client_init (XfsmClient *client)
+{
+
+}
+
+static void
+xfsm_client_finalize (GObject *obj)
+{
+ XfsmClient *client = XFSM_CLIENT (obj);
+
+ xfsm_client_dbus_cleanup (client);
+
+ if (client->properties != NULL)
+ xfsm_properties_free (client->properties);
+
+ g_free (client->id);
+ g_free (client->object_path);
+
+ G_OBJECT_CLASS (xfsm_client_parent_class)->finalize (obj);
+}
+
+
+
+
+static void
+xfsm_properties_discard_command_changed (XfsmProperties *properties,
+ gchar **old_discard)
+{
+ gchar **new_discard;
+
+ g_return_if_fail (properties != NULL);
+ g_return_if_fail (old_discard != NULL);
+
+ new_discard = xfsm_properties_get_strv (properties, SmDiscardCommand);
+
+ if (!xfsm_strv_equal (old_discard, new_discard))
+ {
+ xfsm_verbose ("Client Id = %s, running old discard command.\n\n",
+ properties->client_id);
+
+ g_spawn_sync (xfsm_properties_get_string(properties, SmCurrentDirectory),
+ old_discard,
+ xfsm_properties_get_strv(properties, SmEnvironment),
+ G_SPAWN_SEARCH_PATH,
+ NULL, NULL,
+ NULL, NULL,
+ NULL, NULL);
+ }
+}
+
+
+static void
+xfsm_client_signal_prop_change (XfsmClient *client,
+ const gchar *name)
+{
+ const GValue *value;
+ XfsmProperties *properties = client->properties;
+
+ value = xfsm_properties_get (properties, name);
+ if (value)
+ {
+ g_signal_emit (client, signals[SIG_SM_PROPERTY_CHANGED], 0,
+ name, value);
+ }
+}
+
+
+
+XfsmClient*
+xfsm_client_new (XfsmManager *manager,
+ SmsConn sms_conn)
+{
+ XfsmClient *client;
+
+ g_return_val_if_fail (sms_conn, NULL);
+
+ client = g_object_new (XFSM_TYPE_CLIENT, NULL);
+
+ client->manager = manager;
+ client->sms_conn = sms_conn;
+ client->state = XFSM_CLIENT_IDLE;
+
+ return client;
+}
+
+
+void
+xfsm_client_set_initial_properties (XfsmClient *client,
+ XfsmProperties *properties)
+{
+ g_return_if_fail (XFSM_IS_CLIENT (client));
+ g_return_if_fail (properties != NULL);
+
+ if (client->properties != NULL)
+ xfsm_properties_free (client->properties);
+ client->properties = properties;
+
+ client->id = g_strdup (properties->client_id);
+
+ g_free (client->object_path);
+ client->object_path = g_strconcat (XFSM_CLIENT_OBJECT_PATH_PREFIX,
+ client->id, NULL);
+ g_strcanon (client->object_path + strlen (XFSM_CLIENT_OBJECT_PATH_PREFIX),
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_",
+ '_');
+
+ xfsm_client_dbus_init (client);
+}
+
+
+XfsmClientState
+xfsm_client_get_state (XfsmClient *client)
+{
+ g_return_val_if_fail (XFSM_IS_CLIENT (client), XFSM_CLIENT_DISCONNECTED);
+ return client->state;
+}
+
+
+void
+xfsm_client_set_state (XfsmClient *client,
+ XfsmClientState state)
+{
+ g_return_if_fail (XFSM_IS_CLIENT (client));
+
+ if (G_LIKELY (client->state != state))
+ {
+ XfsmClientState old_state = client->state;
+ client->state = state;
+ g_signal_emit (client, signals[SIG_STATE_CHANGED], 0, old_state, state);
+ }
+}
+
+
+const gchar *
+xfsm_client_get_id (XfsmClient *client)
+{
+ g_return_val_if_fail (XFSM_IS_CLIENT (client), NULL);
+ return client->id;
+}
+
+
+SmsConn
+xfsm_client_get_sms_connection (XfsmClient *client)
+{
+ g_return_val_if_fail (XFSM_IS_CLIENT (client), NULL);
+ return client->sms_conn;
+}
+
+
+XfsmProperties *
+xfsm_client_get_properties (XfsmClient *client)
+{
+ g_return_val_if_fail (XFSM_IS_CLIENT (client), NULL);
+ return client->properties;
+}
+
+
+XfsmProperties *
+xfsm_client_steal_properties (XfsmClient *client)
+{
+ XfsmProperties *properties;
+
+ g_return_val_if_fail(XFSM_IS_CLIENT (client), NULL);
+
+ properties = client->properties;
+ client->properties = NULL;
+
+ return properties;
+}
+
+
+void
+xfsm_client_merge_properties (XfsmClient *client,
+ SmProp **props,
+ gint num_props)
+{
+ XfsmProperties *properties;
+ SmProp *prop;
+ gint n;
+
+ g_return_if_fail (XFSM_IS_CLIENT (client));
+ g_return_if_fail (client->properties != NULL);
+
+ properties = client->properties;
+
+ for (n = 0; n < num_props; ++n)
+ {
+ gchar **old_discard = NULL;
+
+ prop = props[n];
+
+ if (!strcmp (prop->name, SmDiscardCommand))
+ {
+ old_discard = xfsm_properties_get_strv (properties, SmDiscardCommand);
+ if (old_discard)
+ old_discard = g_strdupv (old_discard);
+ }
+
+ if (xfsm_properties_set_from_smprop (properties, prop))
+ {
+ if (old_discard)
+ xfsm_properties_discard_command_changed (properties, old_discard);
+
+ xfsm_client_signal_prop_change (client, prop->name);
+ }
+
+ g_strfreev (old_discard);
+ }
+}
+
+
+void
+xfsm_client_delete_properties (XfsmClient *client,
+ gchar **prop_names,
+ gint num_props)
+{
+ XfsmProperties *properties;
+ gint n;
+
+ g_return_if_fail (XFSM_IS_CLIENT (client));
+ g_return_if_fail (client->properties != NULL);
+
+ properties = client->properties;
+
+ for (n = 0; n < num_props; ++n)
+ {
+ if (xfsm_properties_remove (properties, prop_names[n]))
+ {
+ g_signal_emit (client, signals[SIG_SM_PROPERTY_DELETED], 0,
+ prop_names[n]);
+ }
+ }
+}
+
+
+const gchar *
+xfsm_client_get_object_path (XfsmClient *client)
+{
+ g_return_val_if_fail (XFSM_IS_CLIENT (client), NULL);
+ return client->object_path;
+}
+
+
+
+/*
+ * dbus server impl
+ */
+
+static gboolean xfsm_client_dbus_get_id (XfsmClient *client,
+ gchar **OUT_id,
+ GError **error);
+static gboolean xfsm_client_dbus_get_state (XfsmClient *client,
+ guint *OUT_state,
+ GError **error);
+static gboolean xfsm_client_dbus_get_all_sm_properties (XfsmClient *client,
+ GHashTable **OUT_properties,
+ GError **error);
+static gboolean xfsm_client_dbus_get_sm_properties (XfsmClient *client,
+ gchar **names,
+ GHashTable **OUT_values,
+ GError **error);
+static gboolean xfsm_client_dbus_set_sm_properties (XfsmClient *client,
+ GHashTable *properties,
+ GError **error);
+static gboolean xfsm_client_dbus_delete_sm_properties (XfsmClient *client,
+ gchar **names,
+ GError **error);
+static gboolean xfsm_client_dbus_terminate (XfsmClient *client,
+ GError **error);
+
+
+/* header needs the above fwd decls */
+#include <xfce4-session/xfsm-client-dbus.h>
+
+
+static void
+xfsm_client_dbus_class_init (XfsmClientClass *klass)
+{
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
+ &dbus_glib_xfsm_client_object_info);
+}
+
+
+static void
+xfsm_client_dbus_init (XfsmClient *client)
+{
+ GError *error = NULL;
+
+ client->dbus_conn = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+
+ if (G_UNLIKELY(!client->dbus_conn))
+ {
+ g_critical ("Unable to contact D-Bus session bus: %s", error ? error->message : "Unknown error");
+ if (error)
+ g_error_free (error);
+ return;
+ }
+
+ dbus_g_connection_register_g_object (client->dbus_conn, client->object_path,
+ G_OBJECT (client));
+}
+
+
+static void
+xfsm_client_dbus_cleanup (XfsmClient *client)
+{
+ if (G_LIKELY (client->dbus_conn))
+ {
+ dbus_g_connection_unref (client->dbus_conn);
+ client->dbus_conn = NULL;
+ }
+}
+
+
+static gboolean
+xfsm_client_dbus_get_id (XfsmClient *client,
+ gchar **OUT_id,
+ GError **error)
+{
+ *OUT_id = g_strdup (client->id);
+ return TRUE;
+}
+
+
+static gboolean
+xfsm_client_dbus_get_state (XfsmClient *client,
+ guint *OUT_state,
+ GError **error)
+{
+ *OUT_state = client->state;
+ return TRUE;
+}
+
+
+static gboolean
+xfsm_client_properties_tree_foreach (gpointer key,
+ gpointer value,
+ gpointer data)
+{
+ gchar *prop_name = key;
+ GValue *prop_value = value;
+ GHashTable *hash_table = data;
+
+ g_hash_table_insert (hash_table, prop_name, prop_value);
+
+ return FALSE;
+}
+
+static gboolean
+xfsm_client_dbus_get_all_sm_properties (XfsmClient *client,
+ GHashTable **OUT_properties,
+ GError **error)
+{
+ XfsmProperties *properties = client->properties;
+
+ if (G_UNLIKELY (properties == NULL))
+ {
+ g_set_error (error, XFSM_ERROR, XFSM_ERROR_BAD_VALUE,
+ _("The client doesn't have any properties set yet"));
+ return FALSE;
+ }
+
+ *OUT_properties = g_hash_table_new_full (g_str_hash, g_str_equal,
+ NULL, NULL);
+ g_tree_foreach (properties->sm_properties,
+ xfsm_client_properties_tree_foreach,
+ *OUT_properties);
+
+ return TRUE;
+}
+
+
+static gboolean
+xfsm_client_dbus_get_sm_properties (XfsmClient *client,
+ gchar **names,
+ GHashTable **OUT_properties,
+ GError **error)
+{
+ XfsmProperties *properties = client->properties;
+ gint i;
+
+ if (G_UNLIKELY (properties == NULL))
+ {
+ g_set_error (error, XFSM_ERROR, XFSM_ERROR_BAD_VALUE,
+ _("The client doesn't have any properties set yet"));
+ return FALSE;
+ }
+
+ *OUT_properties = g_hash_table_new_full (g_str_hash, g_str_equal,
+ NULL, NULL);
+
+ for (i = 0; names[i]; ++i)
+ {
+ GValue *value = g_tree_lookup (properties->sm_properties, names[i]);
+ if (G_LIKELY (value))
+ g_hash_table_insert (*OUT_properties, names[i], value);
+ }
+
+ return TRUE;
+}
+
+
+static void
+xfsm_client_dbus_merge_properties_ht (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ gchar *prop_name = key;
+ GValue *prop_value = value;
+ XfsmProperties *properties = user_data;
+
+ xfsm_properties_set (properties, prop_name, prop_value);
+}
+
+
+static gboolean
+xfsm_client_dbus_set_sm_properties (XfsmClient *client,
+ GHashTable *properties,
+ GError **error)
+{
+ if (G_UNLIKELY (client->properties == NULL))
+ {
+ g_set_error (error, XFSM_ERROR, XFSM_ERROR_BAD_VALUE,
+ _("The client doesn't have any properties set yet"));
+ return FALSE;
+ }
+
+ g_hash_table_foreach (properties, xfsm_client_dbus_merge_properties_ht,
+ client->properties);
+
+ return TRUE;
+}
+
+
+static gboolean
+xfsm_client_dbus_delete_sm_properties (XfsmClient *client,
+ gchar **names,
+ GError **error)
+{
+ if (G_UNLIKELY (client->properties == NULL))
+ return TRUE;
+
+ xfsm_client_delete_properties (client, names, g_strv_length (names));
+
+ return TRUE;
+}
+
+
+static gboolean
+xfsm_client_dbus_terminate (XfsmClient *client,
+ GError **error)
+{
+ return xfsm_manager_terminate_client (client->manager, client, error);
+}
diff --git a/xfce4-session/xfsm-client.h b/xfce4-session/xfsm-client.h
new file mode 100644
index 0000000..50aa541
--- /dev/null
+++ b/xfce4-session/xfsm-client.h
@@ -0,0 +1,82 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifndef __XFSM_CLIENT_H__
+#define __XFSM_CLIENT_H__
+
+#include <glib-object.h>
+
+#include <xfce4-session/xfsm-properties.h>
+
+G_BEGIN_DECLS
+
+#define XFSM_TYPE_CLIENT (xfsm_client_get_type ())
+#define XFSM_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XFSM_TYPE_CLIENT, XfsmClient))
+#define XFSM_IS_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XFSM_TYPE_CLIENT))
+
+/* fwd decl */
+struct _XfsmManager;
+
+typedef struct _XfsmClient XfsmClient;
+
+typedef enum
+{
+ XFSM_CLIENT_IDLE,
+ XFSM_CLIENT_INTERACTING,
+ XFSM_CLIENT_SAVEDONE,
+ XFSM_CLIENT_SAVING,
+ XFSM_CLIENT_SAVINGLOCAL,
+ XFSM_CLIENT_WAITFORINTERACT,
+ XFSM_CLIENT_WAITFORPHASE2,
+ XFSM_CLIENT_DISCONNECTED,
+} XfsmClientState;
+
+GType xfsm_client_get_type (void) G_GNUC_CONST;
+
+XfsmClient *xfsm_client_new (struct _XfsmManager *manager,
+ SmsConn sms_conn);
+
+void xfsm_client_set_initial_properties (XfsmClient *client,
+ XfsmProperties *properties);
+
+XfsmClientState xfsm_client_get_state (XfsmClient *client);
+void xfsm_client_set_state (XfsmClient *client,
+ XfsmClientState state);
+
+const gchar *xfsm_client_get_id (XfsmClient *client);
+
+SmsConn xfsm_client_get_sms_connection (XfsmClient *client);
+
+XfsmProperties *xfsm_client_get_properties (XfsmClient *client);
+XfsmProperties *xfsm_client_steal_properties (XfsmClient *client);
+
+void xfsm_client_merge_properties (XfsmClient *client,
+ SmProp **props,
+ gint num_props);
+void xfsm_client_delete_properties (XfsmClient *client,
+ gchar **prop_names,
+ gint num_props);
+
+const gchar *xfsm_client_get_object_path (XfsmClient *client);
+
+G_END_DECLS
+
+#endif /* !__XFSM_CLIENT_H__ */
diff --git a/xfce4-session/xfsm-compat-gnome.c b/xfce4-session/xfsm-compat-gnome.c
new file mode 100644
index 0000000..35e9617
--- /dev/null
+++ b/xfce4-session/xfsm-compat-gnome.c
@@ -0,0 +1,275 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2004-2005 Benedikt Meurer <benny@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ *
+ * Most parts of this file where taken from gnome-session.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#include <X11/Xatom.h>
+#include <X11/Xlib.h>
+
+#include <gdk/gdkx.h>
+
+#include <libxfce4util/libxfce4util.h>
+
+#include <xfce4-session/xfsm-compat-gnome.h>
+
+#define GNOME_KEYRING_DAEMON "gnome-keyring-daemon"
+
+
+static gboolean gnome_compat_started = FALSE;
+static int keyring_lifetime_pipe[2];
+static pid_t gnome_keyring_daemon_pid = 0;
+static Window gnome_smproxy_window = None;
+
+static void
+child_setup (gpointer user_data)
+{
+ gint open_max;
+ gint fd;
+ char *fd_str;
+ int ret;
+
+ open_max = sysconf (_SC_OPEN_MAX);
+ for (fd = 3; fd < open_max; fd++)
+ {
+ if (fd != keyring_lifetime_pipe[0])
+ {
+ ret = fcntl (fd, F_SETFD, FD_CLOEXEC);
+ /* We end up trying to close a lot of non-existant FDs here */
+ if (ret == -1 && errno != EBADF)
+ {
+ perror ("child_setup: fcntl (fd, F_SETFD, FD_CLOEXEC) failed");
+ }
+ }
+ }
+
+ fd_str = g_strdup_printf ("%d", keyring_lifetime_pipe[0]);
+ g_setenv ("GNOME_KEYRING_LIFETIME_FD", fd_str, TRUE);
+ g_free (fd_str);
+}
+
+
+static void
+gnome_keyring_daemon_startup (void)
+{
+ GError *error = NULL;
+ gchar *sout;
+ gchar **lines;
+ gsize lineno;
+ gint status;
+ glong pid;
+ gchar *end;
+ gchar *argv[3];
+ gchar *p;
+ gchar *name;
+ const gchar *value;
+
+ /* Pipe to slave keyring lifetime to */
+ if (pipe (keyring_lifetime_pipe))
+ {
+ g_warning ("Failed to set up pipe for gnome-keyring: %s", strerror (errno));
+ return;
+ }
+
+ error = NULL;
+ argv[0] = GNOME_KEYRING_DAEMON;
+ argv[1] = "--start";
+ argv[2] = NULL;
+ g_spawn_sync (NULL, argv, NULL,
+ G_SPAWN_SEARCH_PATH | G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
+ child_setup, NULL,
+ &sout, NULL, &status, &error);
+
+ close (keyring_lifetime_pipe[0]);
+ /* We leave keyring_lifetime_pipe[1] open for the lifetime of the session,
+ in order to slave the keyring daemon lifecycle to the session. */
+
+ if (error != NULL)
+ {
+ g_printerr ("Failed to run gnome-keyring-daemon: %s\n",
+ error->message);
+ g_error_free (error);
+ }
+ else
+ {
+ if (WIFEXITED (status) && WEXITSTATUS (status) == 0 && sout != NULL)
+ {
+ lines = g_strsplit (sout, "\n", 0);
+
+ for (lineno = 0; lines[lineno] != NULL; lineno++)
+ {
+ p = strchr (lines[lineno], '=');
+ if (p == NULL)
+ continue;
+
+ name = g_strndup (lines[lineno], p - lines[lineno]);
+ value = p + 1;
+
+ g_setenv (name, value, TRUE);
+
+ if (g_strcmp0 (name, "GNOME_KEYRING_PID") == 0)
+ {
+ pid = strtol (value, &end, 10);
+ if (end != value)
+ gnome_keyring_daemon_pid = pid;
+ }
+
+ g_free (name);
+ }
+
+ g_strfreev (lines);
+ }
+ else
+ {
+ /* daemon failed for some reason */
+ g_printerr ("gnome-keyring-daemon failed to start correctly, "
+ "exit code: %d\n", WEXITSTATUS (status));
+ }
+
+ g_free (sout);
+ }
+}
+
+static void
+gnome_keyring_daemon_shutdown (void)
+{
+ if (gnome_keyring_daemon_pid != 0)
+ {
+ kill (gnome_keyring_daemon_pid, SIGTERM);
+ gnome_keyring_daemon_pid = 0;
+ }
+}
+
+
+
+static void
+xfsm_compat_gnome_smproxy_startup (void)
+{
+ Atom gnome_sm_proxy;
+ Display *dpy;
+ Window root;
+
+ gdk_error_trap_push ();
+
+ /* Set GNOME_SM_PROXY property, since some apps (like OOo) seem to require
+ * it to behave properly. Thanks to Jasper/Francois for reporting this.
+ * This has another advantage, since it prevents people from running
+ * gnome-smproxy in xfce4, which would cause trouble otherwise.
+ */
+ dpy = gdk_display;
+ root = RootWindow (dpy, 0);
+
+ if (gnome_smproxy_window != None)
+ XDestroyWindow (dpy, gnome_smproxy_window);
+
+ gnome_sm_proxy = XInternAtom (dpy, "GNOME_SM_PROXY", False);
+ gnome_smproxy_window = XCreateSimpleWindow (dpy, root, 1, 1, 1, 1, 0, 0, 0);
+
+ XChangeProperty (dpy, gnome_smproxy_window, gnome_sm_proxy,
+ XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char *) (void *) &gnome_smproxy_window, 1);
+ XChangeProperty (dpy, root, gnome_sm_proxy,
+ XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char *) (void *) &gnome_smproxy_window, 1);
+
+ XSync (dpy, False);
+
+ gdk_error_trap_pop ();
+}
+
+
+static void
+xfsm_compat_gnome_smproxy_shutdown (void)
+{
+ gdk_error_trap_push ();
+
+ if (gnome_smproxy_window != None)
+ {
+ XDestroyWindow (gdk_display, gnome_smproxy_window);
+ XSync (gdk_display, False);
+ gnome_smproxy_window = None;
+ }
+
+ gdk_error_trap_pop ();
+}
+
+
+void
+xfsm_compat_gnome_startup (XfsmSplashScreen *splash)
+{
+ if (G_UNLIKELY (gnome_compat_started))
+ return;
+
+ xfsm_compat_gnome_smproxy_startup ();
+
+ /* fire up the keyring daemon */
+ if (G_LIKELY (splash != NULL))
+ xfsm_splash_screen_next (splash, _("Starting The Gnome Keyring Daemon"));
+ gnome_keyring_daemon_startup ();
+
+ gnome_compat_started = TRUE;
+}
+
+
+void
+xfsm_compat_gnome_shutdown (void)
+{
+ if (G_UNLIKELY (!gnome_compat_started))
+ return;
+
+ /* shutdown the keyring daemon */
+ gnome_keyring_daemon_shutdown ();
+
+ xfsm_compat_gnome_smproxy_shutdown ();
+
+ gnome_compat_started = FALSE;
+}
+
diff --git a/xfce4-session/xfsm-compat-gnome.h b/xfce4-session/xfsm-compat-gnome.h
new file mode 100644
index 0000000..b404ec1
--- /dev/null
+++ b/xfce4-session/xfsm-compat-gnome.h
@@ -0,0 +1,32 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2004 Benedikt Meurer <benny@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ *
+ * Most parts of this file where taken from gnome-session.
+ */
+
+#ifndef __XFSM_COMPAT_GNOME_H__
+#define __XFSM_COMPAT_GNOME_H__
+
+#include <xfce4-session/xfsm-splash-screen.h>
+
+void xfsm_compat_gnome_startup (XfsmSplashScreen *splash);
+void xfsm_compat_gnome_shutdown (void);
+
+#endif /* !__XFSM_COMPAT_GNOME_H__ */
diff --git a/xfce4-session/xfsm-compat-kde.c b/xfce4-session/xfsm-compat-kde.c
new file mode 100644
index 0000000..b51387e
--- /dev/null
+++ b/xfce4-session/xfsm-compat-kde.c
@@ -0,0 +1,157 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2004 Benedikt Meurer <benny@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <libxfce4util/libxfce4util.h>
+
+#include <xfce4-session/xfsm-compat-kde.h>
+
+
+static gboolean kde_compat_started = FALSE;
+
+
+static gboolean
+run_timeout (gpointer user_data)
+{
+ int status;
+ int result;
+ pid_t pid = *((pid_t *) user_data);
+
+ result = waitpid (pid, &status, WNOHANG);
+
+ if (result == pid)
+ {
+ gtk_main_quit ();
+ }
+ else if (result == -1)
+ {
+ g_warning ("Failed to wait for process %d: %s",
+ (int)pid, g_strerror (errno));
+ gtk_main_quit ();
+ }
+
+ return TRUE;
+}
+
+
+static void
+run (const gchar *command)
+{
+ gchar buffer[2048];
+ GError *error = NULL;
+ gchar **argv;
+ gint argc;
+ pid_t pid;
+
+ g_snprintf (buffer, 2048, "env DYLD_FORCE_FLAT_NAMESPACE= LD_BIND_NOW=true "
+ "SESSION_MANAGER= %s", command);
+
+ if (!g_shell_parse_argv (buffer, &argc, &argv, &error))
+ {
+ g_warning ("Unable to parse \"%s\": %s", buffer, error->message);
+ g_error_free (error);
+ return;
+ }
+
+ if (g_spawn_async (NULL, argv, NULL,
+ G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH,
+ NULL, NULL, &pid, &error))
+ {
+ guint id = g_timeout_add (300, run_timeout, &pid);
+ gtk_main ();
+ g_source_remove (id);
+ }
+ else
+ {
+ g_warning ("Unable to exec \"%s\": %s", buffer, error->message);
+ g_error_free (error);
+ }
+
+ g_strfreev (argv);
+}
+
+
+void
+xfsm_compat_kde_startup (XfsmSplashScreen *splash)
+{
+ gchar command[256];
+
+ if (G_UNLIKELY (kde_compat_started))
+ return;
+
+ if (G_LIKELY (splash != NULL))
+ xfsm_splash_screen_next (splash, _("Starting KDE services"));
+
+ run ("kdeinit4");
+
+ /* tell klauncher about the session manager */
+ g_snprintf (command, 256, "qdbus org.kde.klauncher /KLauncher setLaunchEnv "
+ "SESSION_MANAGER \"%s\"",
+ g_getenv ("SESSION_MANAGER"));
+ run (command);
+
+ /* tell kde if we are running multi-head */
+ if (gdk_display_get_n_screens (gdk_display_get_default ()) > 1)
+ {
+ g_snprintf (command, 256, "qdbus org.kde.klauncher /KLauncher setLaunchEnv "
+ "KDE_MULTIHEAD \"true\"");
+ run (command);
+ }
+
+ kde_compat_started = TRUE;
+}
+
+
+void
+xfsm_compat_kde_shutdown (void)
+{
+ if (G_UNLIKELY (!kde_compat_started))
+ return;
+
+ /* shutdown KDE services */
+ run ("kdeinit4_shutdown");
+
+ kde_compat_started = FALSE;
+}
+
diff --git a/xfce4-session/xfsm-compat-kde.h b/xfce4-session/xfsm-compat-kde.h
new file mode 100644
index 0000000..1e60de4
--- /dev/null
+++ b/xfce4-session/xfsm-compat-kde.h
@@ -0,0 +1,31 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2004 Benedikt Meurer <benny@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifndef __XFSM_COMPAT_KDE_H__
+#define __XFSM_COMPAT_KDE_H__
+
+#include <xfce4-session/xfsm-splash-screen.h>
+
+
+void xfsm_compat_kde_startup (XfsmSplashScreen *splash);
+void xfsm_compat_kde_shutdown (void);
+
+#endif /* !__XFSM_COMPAT_KDE_H__ */
diff --git a/xfce4-session/xfsm-consolekit.c b/xfce4-session/xfsm-consolekit.c
new file mode 100644
index 0000000..8d99398
--- /dev/null
+++ b/xfce4-session/xfsm-consolekit.c
@@ -0,0 +1,491 @@
+/*-
+ * Copyright (c) 2010 Ali Abdallah <aliov@xfce.org>
+ * Copyright (c) 2011 Nick Schermer <nick@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <xfce4-session/xfsm-consolekit.h>
+#include <libxfsm/xfsm-util.h>
+
+
+#define CK_NAME "org.freedesktop.ConsoleKit"
+#define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager"
+#define CK_MANAGER_NAME CK_NAME ".Manager"
+
+
+
+static void xfsm_consolekit_finalize (GObject *object);
+static gboolean xfsm_consolekit_proxy_ensure (XfsmConsolekit *consolekit,
+ GError **error);
+static void xfsm_consolekit_proxy_free (XfsmConsolekit *consolekit);
+
+
+
+struct _XfsmConsolekitClass
+{
+ GObjectClass __parent__;
+};
+
+struct _XfsmConsolekit
+{
+ GObject __parent__;
+
+ DBusGConnection *dbus_conn;
+ DBusGProxy *ck_proxy;
+ DBusGProxy *dbus_proxy;
+};
+
+
+
+G_DEFINE_TYPE (XfsmConsolekit, xfsm_consolekit, G_TYPE_OBJECT)
+
+
+
+static void
+xfsm_consolekit_class_init (XfsmConsolekitClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = xfsm_consolekit_finalize;
+}
+
+
+
+static void
+xfsm_consolekit_init (XfsmConsolekit *consolekit)
+{
+}
+
+
+
+static void
+xfsm_consolekit_finalize (GObject *object)
+{
+ xfsm_consolekit_proxy_free (XFSM_CONSOLEKIT (object));
+
+ (*G_OBJECT_CLASS (xfsm_consolekit_parent_class)->finalize) (object);
+}
+
+
+
+static DBusHandlerResult
+xfsm_consolekit_dbus_filter (DBusConnection *connection,
+ DBusMessage *message,
+ gpointer data)
+{
+ g_return_val_if_fail (XFSM_IS_CONSOLEKIT (data), DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+
+ if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected")
+ && g_strcmp0 (dbus_message_get_path (message), DBUS_PATH_LOCAL) == 0)
+ {
+ g_debug ("Consolekit disconnected");
+ xfsm_consolekit_proxy_free (XFSM_CONSOLEKIT (data));
+ }
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+
+
+static void
+xfsm_consolekit_name_owner_changed (DBusGProxy *dbus_proxy,
+ const gchar *name,
+ const gchar *prev_owner,
+ const gchar *new_owner,
+ XfsmConsolekit *consolekit)
+{
+ GError *err = NULL;
+
+ g_return_if_fail (XFSM_IS_CONSOLEKIT (consolekit));
+ g_return_if_fail (consolekit->dbus_proxy == dbus_proxy);
+
+ if (g_strcmp0 (name, CK_NAME) == 0)
+ {
+ g_debug ("Consolekit owner changed");
+
+ /* only reconnect the consolekit proxy */
+ if (consolekit->ck_proxy != NULL)
+ {
+ g_object_unref (G_OBJECT (consolekit->ck_proxy));
+ consolekit->ck_proxy = NULL;
+ }
+
+ if (!xfsm_consolekit_proxy_ensure (consolekit, &err))
+ {
+ g_warning ("Failed to reconnect to consolekit: %s", err->message);
+ g_error_free (err);
+ }
+ }
+}
+
+
+
+static gboolean
+xfsm_consolekit_proxy_ensure (XfsmConsolekit *consolekit,
+ GError **error)
+{
+ GError *err = NULL;
+ DBusConnection *connection;
+
+ if (consolekit->dbus_conn == NULL)
+ {
+ consolekit->dbus_conn = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err);
+ if (consolekit->dbus_conn == NULL)
+ goto error1;
+
+ connection = dbus_g_connection_get_connection (consolekit->dbus_conn);
+ dbus_connection_set_exit_on_disconnect (connection, FALSE);
+ dbus_connection_add_filter (connection, xfsm_consolekit_dbus_filter, consolekit, NULL);
+ }
+
+ if (consolekit->dbus_proxy == NULL)
+ {
+ consolekit->dbus_proxy = dbus_g_proxy_new_for_name_owner (consolekit->dbus_conn,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ &err);
+ if (consolekit->dbus_proxy == NULL)
+ goto error1;
+
+ /* (dis)connect to consolekit if stopped/started */
+ dbus_g_proxy_add_signal (consolekit->dbus_proxy,
+ "NameOwnerChanged",
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_INVALID);
+
+ dbus_g_proxy_connect_signal (consolekit->dbus_proxy,
+ "NameOwnerChanged",
+ G_CALLBACK (xfsm_consolekit_name_owner_changed),
+ consolekit, NULL);
+ }
+
+ if (consolekit->ck_proxy == NULL)
+ {
+ consolekit->ck_proxy = dbus_g_proxy_new_for_name_owner (consolekit->dbus_conn,
+ CK_NAME,
+ CK_MANAGER_PATH,
+ CK_MANAGER_NAME,
+ &err);
+ if (consolekit->ck_proxy == NULL)
+ goto error1;
+ }
+
+ return TRUE;
+
+ error1:
+
+ g_propagate_error (error, err);
+ xfsm_consolekit_proxy_free (consolekit);
+
+ return FALSE;
+}
+
+
+
+static void
+xfsm_consolekit_proxy_free (XfsmConsolekit *consolekit)
+{
+ DBusConnection *connection;
+
+ if (consolekit->ck_proxy != NULL)
+ {
+ g_object_unref (G_OBJECT (consolekit->ck_proxy));
+ consolekit->ck_proxy = NULL;
+ }
+
+ if (consolekit->dbus_proxy != NULL)
+ {
+ g_object_unref (G_OBJECT (consolekit->dbus_proxy));
+ consolekit->dbus_proxy = NULL;
+ }
+
+ if (consolekit->dbus_conn != NULL)
+ {
+ connection = dbus_g_connection_get_connection (consolekit->dbus_conn);
+ dbus_connection_remove_filter (connection,
+ xfsm_consolekit_dbus_filter,
+ consolekit);
+
+ dbus_g_connection_unref (consolekit->dbus_conn);
+ consolekit->dbus_conn = NULL;
+ }
+}
+
+
+
+static gboolean
+xfsm_consolekit_can_method (XfsmConsolekit *consolekit,
+ const gchar *method,
+ gboolean *can_method,
+ GError **error)
+{
+ g_return_val_if_fail (can_method != NULL, FALSE);
+
+ /* never return true if something fails */
+ *can_method = FALSE;
+
+ if (!xfsm_consolekit_proxy_ensure (consolekit, error))
+ return FALSE;
+
+ return dbus_g_proxy_call (consolekit->ck_proxy, method,
+ error, G_TYPE_INVALID,
+ G_TYPE_BOOLEAN, can_method,
+ G_TYPE_INVALID);
+}
+
+
+
+static gboolean
+xfsm_consolekit_can_sleep (XfsmConsolekit *consolekit,
+ const gchar *method,
+ gboolean *can_method,
+ gboolean *auth_method,
+ GError **error)
+{
+ gboolean ret;
+ gchar *can_string;
+ g_return_val_if_fail (can_method != NULL, FALSE);
+
+ /* never return true if something fails */
+ *can_method = FALSE;
+
+ if (!xfsm_consolekit_proxy_ensure (consolekit, error))
+ return FALSE;
+
+ ret = dbus_g_proxy_call (consolekit->ck_proxy, method,
+ error, G_TYPE_INVALID,
+ G_TYPE_STRING, &can_string,
+ G_TYPE_INVALID);
+
+ if (ret == FALSE)
+ return FALSE;
+
+ /* If yes or challenge then we can sleep, it just might take a password */
+ if (g_strcmp0 (can_string, "yes") == 0 || g_strcmp0 (can_string, "challenge") == 0)
+ {
+ *can_method = TRUE;
+ *auth_method = TRUE;
+ }
+ else
+ {
+ *can_method = FALSE;
+ *auth_method = FALSE;
+ }
+
+ return TRUE;
+}
+
+
+
+static gboolean
+xfsm_consolekit_try_method (XfsmConsolekit *consolekit,
+ const gchar *method,
+ GError **error)
+{
+ if (!xfsm_consolekit_proxy_ensure (consolekit, error))
+ return FALSE;
+
+ return dbus_g_proxy_call (consolekit->ck_proxy, method, error,
+ G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+
+
+static gboolean
+xfsm_consolekit_try_sleep (XfsmConsolekit *consolekit,
+ const gchar *method,
+ GError **error)
+{
+ if (!xfsm_consolekit_proxy_ensure (consolekit, error))
+ return FALSE;
+
+ return dbus_g_proxy_call (consolekit->ck_proxy, method, error,
+ G_TYPE_BOOLEAN, TRUE,
+ G_TYPE_INVALID, G_TYPE_INVALID);
+}
+
+
+
+XfsmConsolekit *
+xfsm_consolekit_get (void)
+{
+ static XfsmConsolekit *object = NULL;
+
+ if (G_LIKELY (object != NULL))
+ {
+ g_object_ref (G_OBJECT (object));
+ }
+ else
+ {
+ object = g_object_new (XFSM_TYPE_CONSOLEKIT, NULL);
+ g_object_add_weak_pointer (G_OBJECT (object), (gpointer) &object);
+ }
+
+ return object;
+}
+
+
+
+gboolean
+xfsm_consolekit_try_restart (XfsmConsolekit *consolekit,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_CONSOLEKIT (consolekit), FALSE);
+
+ return xfsm_consolekit_try_method (consolekit, "Restart", error);
+}
+
+
+
+gboolean
+xfsm_consolekit_try_shutdown (XfsmConsolekit *consolekit,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_CONSOLEKIT (consolekit), FALSE);
+
+ return xfsm_consolekit_try_method (consolekit, "Stop", error);
+}
+
+
+
+gboolean
+xfsm_consolekit_can_restart (XfsmConsolekit *consolekit,
+ gboolean *can_restart,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_CONSOLEKIT (consolekit), FALSE);
+
+
+ return xfsm_consolekit_can_method (consolekit, "CanRestart",
+ can_restart, error);
+}
+
+
+
+gboolean
+xfsm_consolekit_can_shutdown (XfsmConsolekit *consolekit,
+ gboolean *can_shutdown,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_CONSOLEKIT (consolekit), FALSE);
+
+ return xfsm_consolekit_can_method (consolekit, "CanStop",
+ can_shutdown, error);
+}
+
+
+static gboolean
+lock_screen (GError **error)
+{
+ XfconfChannel *channel;
+ gboolean ret = TRUE;
+
+ channel = xfsm_open_config ();
+ if (xfconf_channel_get_bool (channel, "/shutdown/LockScreen", FALSE))
+ ret = g_spawn_command_line_async ("xflock4", error);
+
+ return ret;
+}
+
+gboolean
+xfsm_consolekit_try_suspend (XfsmConsolekit *consolekit,
+ GError **error)
+{
+ gboolean can_suspend, auth_suspend;
+
+ g_return_val_if_fail (XFSM_IS_CONSOLEKIT (consolekit), FALSE);
+
+ /* Check if consolekit can suspend before we call lock screen. */
+ if (xfsm_consolekit_can_suspend (consolekit, &can_suspend, &auth_suspend, NULL))
+ {
+ if (!can_suspend)
+ return FALSE;
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ if (!lock_screen (error))
+ return FALSE;
+
+ return xfsm_consolekit_try_sleep (consolekit, "Suspend", error);
+}
+
+
+
+gboolean
+xfsm_consolekit_try_hibernate (XfsmConsolekit *consolekit,
+ GError **error)
+{
+ gboolean can_hibernate, auth_hibernate;
+
+ g_return_val_if_fail (XFSM_IS_CONSOLEKIT (consolekit), FALSE);
+
+ /* Check if consolekit can hibernate before we call lock screen. */
+ if (xfsm_consolekit_can_hibernate (consolekit, &can_hibernate, &auth_hibernate, NULL))
+ {
+ if (!can_hibernate)
+ return FALSE;
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ if (!lock_screen (error))
+ return FALSE;
+
+ return xfsm_consolekit_try_sleep (consolekit, "Hibernate", error);
+}
+
+
+
+gboolean
+xfsm_consolekit_can_suspend (XfsmConsolekit *consolekit,
+ gboolean *can_suspend,
+ gboolean *auth_suspend,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_CONSOLEKIT (consolekit), FALSE);
+
+ return xfsm_consolekit_can_sleep (consolekit, "CanSuspend",
+ can_suspend, auth_suspend, error);
+}
+
+
+
+gboolean
+xfsm_consolekit_can_hibernate (XfsmConsolekit *consolekit,
+ gboolean *can_hibernate,
+ gboolean *auth_hibernate,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_CONSOLEKIT (consolekit), FALSE);
+
+ return xfsm_consolekit_can_sleep (consolekit, "CanHibernate",
+ can_hibernate, auth_hibernate, error);
+}
diff --git a/xfce4-session/xfsm-consolekit.h b/xfce4-session/xfsm-consolekit.h
new file mode 100644
index 0000000..413ad68
--- /dev/null
+++ b/xfce4-session/xfsm-consolekit.h
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 2003-2006 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2010 Ali Abdallah <aliov@xfce.org>
+ * Copyright (c) 2011 Nick Schermer <nick@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifndef __XFSM_CONSOLEKIT_HELPER_H__
+#define __XFSM_CONSOLEKIT_HELPER_H__
+
+typedef struct _XfsmConsolekitClass XfsmConsolekitClass;
+typedef struct _XfsmConsolekit XfsmConsolekit;
+
+#define XFSM_TYPE_CONSOLEKIT (xfsm_consolekit_get_type ())
+#define XFSM_CONSOLEKIT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFSM_TYPE_CONSOLEKIT, XfsmConsolekit))
+#define XFSM_CONSOLEKIT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFSM_TYPE_CONSOLEKIT, XfsmConsolekitClass))
+#define XFSM_IS_CONSOLEKIT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFSM_TYPE_CONSOLEKIT))
+#define XFSM_IS_CONSOLEKIT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFSM_TYPE_CONSOLEKIT))
+#define XFSM_CONSOLEKIT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XFSM_TYPE_CONSOLEKIT, XfsmConsolekitClass))
+
+GType xfsm_consolekit_get_type (void) G_GNUC_CONST;
+
+XfsmConsolekit *xfsm_consolekit_get (void);
+
+gboolean xfsm_consolekit_try_restart (XfsmConsolekit *consolekit,
+ GError **error);
+
+gboolean xfsm_consolekit_try_shutdown (XfsmConsolekit *consolekit,
+ GError **error);
+
+gboolean xfsm_consolekit_can_restart (XfsmConsolekit *consolekit,
+ gboolean *can_restart,
+ GError **error);
+
+gboolean xfsm_consolekit_can_shutdown (XfsmConsolekit *consolekit,
+ gboolean *can_shutdown,
+ GError **error);
+
+gboolean xfsm_consolekit_try_suspend (XfsmConsolekit *consolekit,
+ GError **error);
+
+gboolean xfsm_consolekit_try_hibernate(XfsmConsolekit *consolekit,
+ GError **error);
+
+gboolean xfsm_consolekit_can_suspend (XfsmConsolekit *consolekit,
+ gboolean *can_suspend,
+ gboolean *auth_suspend,
+ GError **error);
+
+gboolean xfsm_consolekit_can_hibernate(XfsmConsolekit *consolekit,
+ gboolean *can_hibernate,
+ gboolean *auth_hibernate,
+ GError **error);
+
+
+#endif /* !__XFSM_CONSOLEKIT_HELPER_H__ */
diff --git a/xfce4-session/xfsm-dns.c b/xfce4-session/xfsm-dns.c
new file mode 100644
index 0000000..abb9cef
--- /dev/null
+++ b/xfce4-session/xfsm-dns.c
@@ -0,0 +1,176 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2004 Benedikt Meurer <benny@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ *
+ * Parts of this file where taken from gnome-session/main.c, which
+ * was written by Tom Tromey.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include <libxfce4ui/libxfce4ui.h>
+
+#include <libxfsm/xfsm-util.h>
+
+#include <xfce4-session/xfsm-dns.h>
+#include <xfce4-session/xfsm-global.h>
+
+
+static gchar*
+queryhostname (gchar *buffer, gsize length, gboolean readable)
+{
+#ifdef HAVE_GETHOSTNAME
+ if (gethostname (buffer, length) == 0)
+ return buffer;
+#else
+ struct utsname utsname;
+ if (uname (&utsname) == 0)
+ {
+ g_strlcpy (buffer, utsname.nodename, length);
+ return buffer;
+ }
+#endif
+ if (readable)
+ {
+ g_strlcpy (buffer, _("(Unknown)"), length);
+ return buffer;
+ }
+ return NULL;
+}
+
+
+static gboolean
+check_for_dns (void)
+{
+#ifdef HAVE_GETADDRINFO
+ struct addrinfo *result = NULL;
+ struct addrinfo hints;
+#endif
+ char buffer[256];
+ gchar *hostname;
+
+ hostname = queryhostname (buffer, 256, FALSE);
+ if (hostname == NULL)
+ return FALSE;
+
+#ifdef HAVE_GETADDRINFO
+ bzero (&hints, sizeof (hints));
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_CANONNAME;
+
+ if (getaddrinfo (hostname, NULL, &hints, &result) != 0)
+ return FALSE;
+
+ if (g_ascii_strncasecmp (result->ai_canonname, hostname, 0) != 0)
+ return FALSE;
+#else
+#ifdef HAVE_GETHOSTBYNAME
+ if (gethostbyname (hostname) == NULL)
+ {
+ return FALSE;
+ }
+#endif
+#endif
+
+ return TRUE;
+}
+
+
+enum
+{
+ RESPONSE_LOG_IN,
+ RESPONSE_TRY_AGAIN,
+};
+
+
+void
+xfsm_dns_check (void)
+{
+ GtkWidget *msgbox = NULL;
+ gchar hostname[256];
+ gint response;
+
+ while (!check_for_dns ())
+ {
+ if (msgbox == NULL)
+ {
+ GdkScreen *screen = xfce_gdk_screen_get_active (NULL);
+
+ queryhostname (hostname, 256, TRUE);
+
+ msgbox = gtk_message_dialog_new (NULL, 0,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_NONE,
+ _("Could not look up internet address for %s.\n"
+ "This will prevent Xfce from operating correctly.\n"
+ "It may be possible to correct the problem by adding\n"
+ "%s to the file /etc/hosts on your system."),
+ hostname, hostname);
+
+ gtk_dialog_add_buttons (GTK_DIALOG (msgbox),
+ _("Continue anyway"), RESPONSE_LOG_IN,
+ _("Try again"), RESPONSE_TRY_AGAIN,
+ NULL);
+
+ gtk_window_set_screen (GTK_WINDOW (msgbox), screen);
+ xfsm_window_add_border (GTK_WINDOW (msgbox));
+ gtk_window_set_position (GTK_WINDOW (msgbox), GTK_WIN_POS_CENTER);
+ }
+
+ gtk_dialog_set_default_response (GTK_DIALOG (msgbox), RESPONSE_TRY_AGAIN);
+
+ response = xfsm_splash_screen_run (splash_screen, msgbox);
+ if (response != RESPONSE_TRY_AGAIN)
+ break;
+
+ gtk_widget_hide (msgbox);
+ }
+
+ if (msgbox != NULL)
+ gtk_widget_destroy (msgbox);
+}
+
+
diff --git a/xfce4-session/xfsm-dns.h b/xfce4-session/xfsm-dns.h
new file mode 100644
index 0000000..08d652e
--- /dev/null
+++ b/xfce4-session/xfsm-dns.h
@@ -0,0 +1,28 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2004 Benedikt Meurer <benny@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifndef __XFSM_DNS_H__
+#define __XFSM_DNS_H__
+
+void xfsm_dns_check (void);
+
+#endif /* !__XFSM_DNS_H__ */
+
diff --git a/xfce4-session/xfsm-error.c b/xfce4-session/xfsm-error.c
new file mode 100644
index 0000000..f4d9c69
--- /dev/null
+++ b/xfce4-session/xfsm-error.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2008 Brian Tarricone <bjt23@cornell.edu>
+ *
+ * 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; version 2 of the License ONLY.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <dbus/dbus-glib.h>
+
+#include <xfce4-session/xfsm-error.h>
+
+
+GQuark
+xfsm_error_get_quark (void)
+{
+ static GQuark xfsm_error_quark = 0;
+
+ if (G_UNLIKELY (xfsm_error_quark == 0))
+ xfsm_error_quark = g_quark_from_static_string ("xfsm-error-quark");
+
+ return xfsm_error_quark;
+}
+
+
+GType
+xfsm_error_get_type (void)
+{
+ static GType xfsm_error_type = 0;
+
+ if (G_UNLIKELY (xfsm_error_type == 0))
+ {
+ static const GEnumValue values[] = {
+ { XFSM_ERROR_BAD_STATE, "XFSM_ERROR_BAD_STATE", "BadState" },
+ { XFSM_ERROR_BAD_VALUE, "XFSM_ERROR_BAD_VALUE", "BadValue" },
+ { XFSM_ERROR_UNSUPPORTED, "XFSM_ERROR_UNSUPPORTED", "Unsupported" },
+ { 0, NULL, NULL },
+ };
+
+ xfsm_error_type = g_enum_register_static ("XfsmError", values);
+ }
+
+ return xfsm_error_type;
+}
+
+void
+xfsm_error_dbus_init (void)
+{
+ dbus_g_error_domain_register (XFSM_ERROR, "org.xfce.Session.Manager",
+ XFSM_TYPE_ERROR);
+}
diff --git a/xfce4-session/xfsm-error.h b/xfce4-session/xfsm-error.h
new file mode 100644
index 0000000..22ff710
--- /dev/null
+++ b/xfce4-session/xfsm-error.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2008 Brian Tarricone <bjt23@cornell.edu>
+ *
+ * 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; version 2 of the License ONLY.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __XFSM_ERRORS_H__
+#define __XFSM_ERRORS_H__
+
+#include <glib-object.h>
+
+#define XFSM_TYPE_ERROR (xfsm_error_get_type ())
+#define XFSM_ERROR (xfsm_error_get_quark ())
+
+#define ERROR_MSG(err) ((err) != NULL ? (err)->message : "Error not set")
+
+G_BEGIN_DECLS
+
+typedef enum
+{
+ XFSM_ERROR_BAD_STATE = 0,
+ XFSM_ERROR_BAD_VALUE,
+ XFSM_ERROR_UNSUPPORTED,
+} XfsmError;
+
+GType xfsm_error_get_type (void) G_GNUC_CONST;
+GQuark xfsm_error_get_quark (void) G_GNUC_CONST;
+
+void xfsm_error_dbus_init (void);
+
+G_END_DECLS
+
+#endif /* !__XFSM_ERRORS_H__ */
diff --git a/xfce4-session/xfsm-fadeout.c b/xfce4-session/xfsm-fadeout.c
new file mode 100644
index 0000000..91af5b6
--- /dev/null
+++ b/xfce4-session/xfsm-fadeout.c
@@ -0,0 +1,139 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2004-2006 Benedikt Meurer <benny@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include <xfce4-session/xfsm-fadeout.h>
+
+
+
+struct _XfsmFadeout
+{
+ GSList *windows;
+};
+
+
+
+XfsmFadeout*
+xfsm_fadeout_new (GdkDisplay *display)
+{
+ GdkWindowAttr attr;
+ XfsmFadeout *fadeout;
+ GdkWindow *root;
+ GdkCursor *cursor;
+ cairo_t *cr;
+ gint width;
+ gint height;
+ gint n;
+ GdkPixbuf *root_pixbuf;
+ GdkPixmap *backbuf;
+ GdkScreen *gdk_screen;
+ GdkWindow *window;
+ GdkColor black = { 0, };
+
+ fadeout = g_slice_new0 (XfsmFadeout);
+
+ cursor = gdk_cursor_new (GDK_WATCH);
+
+ attr.x = 0;
+ attr.y = 0;
+ attr.event_mask = 0;
+ attr.wclass = GDK_INPUT_OUTPUT;
+ attr.window_type = GDK_WINDOW_TEMP;
+ attr.cursor = cursor;
+ attr.override_redirect = TRUE;
+
+ for (n = 0; n < gdk_display_get_n_screens (display); ++n)
+ {
+ gdk_screen = gdk_display_get_screen (display, n);
+
+ root = gdk_screen_get_root_window (gdk_screen);
+ gdk_drawable_get_size (GDK_DRAWABLE (root), &width, &height);
+
+ attr.width = width;
+ attr.height = height;
+ window = gdk_window_new (root, &attr, GDK_WA_X | GDK_WA_Y
+ | GDK_WA_NOREDIR | GDK_WA_CURSOR);
+
+ if (gdk_screen_is_composited (gdk_screen)
+ && gdk_screen_get_rgba_colormap (gdk_screen) != NULL)
+ {
+ /* transparent black window */
+ gdk_window_set_background (window, &black);
+ gdk_window_set_opacity (window, 0.50);
+ }
+ else
+ {
+ /* create background for window */
+ backbuf = gdk_pixmap_new (GDK_DRAWABLE (root), width, height, -1);
+ cr = gdk_cairo_create (GDK_DRAWABLE (backbuf));
+
+ /* make of copy of the root window */
+ root_pixbuf = gdk_pixbuf_get_from_drawable (NULL, GDK_DRAWABLE (root), NULL,
+ 0, 0, 0, 0, width, height);
+ gdk_cairo_set_source_pixbuf (cr, root_pixbuf, 0, 0);
+ cairo_paint (cr);
+ g_object_unref (G_OBJECT (root_pixbuf));
+
+ /* draw black layer */
+ gdk_cairo_set_source_color (cr, &black);
+ cairo_paint_with_alpha (cr, 0.50);
+ cairo_destroy (cr);
+
+ gdk_window_set_back_pixmap (window, backbuf, FALSE);
+ g_object_unref (G_OBJECT (backbuf));
+ }
+
+ fadeout->windows = g_slist_prepend (fadeout->windows, window);
+ }
+
+ /* show all windows all at once */
+ g_slist_foreach (fadeout->windows, (GFunc) gdk_window_show, NULL);
+
+ gdk_cursor_unref (cursor);
+
+ return fadeout;
+}
+
+
+
+void
+xfsm_fadeout_clear (XfsmFadeout *fadeout)
+{
+ if (fadeout != NULL)
+ g_slist_foreach (fadeout->windows, (GFunc) gdk_window_clear, NULL);
+}
+
+
+
+void
+xfsm_fadeout_destroy (XfsmFadeout *fadeout)
+{
+ g_slist_foreach (fadeout->windows, (GFunc) gdk_window_hide, NULL);
+ g_slist_foreach (fadeout->windows, (GFunc) gdk_window_destroy, NULL);
+
+ g_slist_free (fadeout->windows);
+ g_slice_free (XfsmFadeout, fadeout);
+}
diff --git a/xfce4-session/xfsm-fadeout.h b/xfce4-session/xfsm-fadeout.h
new file mode 100644
index 0000000..6cc80fe
--- /dev/null
+++ b/xfce4-session/xfsm-fadeout.h
@@ -0,0 +1,39 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2004 Benedikt Meurer <benny@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifndef __XFSM_FADEOUT_H__
+#define __XFSM_FADEOUT_H__
+
+#include <gdk/gdk.h>
+
+
+G_BEGIN_DECLS;
+
+typedef struct _XfsmFadeout XfsmFadeout;
+
+XfsmFadeout *xfsm_fadeout_new (GdkDisplay *display);
+void xfsm_fadeout_clear (XfsmFadeout *fadeout);
+void xfsm_fadeout_destroy (XfsmFadeout *fadeout);
+
+G_END_DECLS;
+
+
+#endif /* !__XFSM_FADEOUT_H__ */
diff --git a/xfce4-session/xfsm-global.c b/xfce4-session/xfsm-global.c
new file mode 100644
index 0000000..6368a9a
--- /dev/null
+++ b/xfce4-session/xfsm-global.c
@@ -0,0 +1,204 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2008 Brian Tarricone <bjt23@cornell.edu>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STDARG_H
+#include <stdarg.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef HAVE_SYS_TYPE_SH
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <libxfce4util/libxfce4util.h>
+#include <libxfce4ui/libxfce4ui.h>
+
+#include <xfce4-session/xfsm-global.h>
+
+#include <libxfsm/xfsm-util.h>
+
+
+/* global variables */
+gboolean verbose = FALSE;
+XfsmSplashScreen *splash_screen = NULL;
+
+void
+xfsm_failsafe_client_free (FailsafeClient *fclient)
+{
+ if (fclient->command)
+ g_strfreev (fclient->command);
+ g_free (fclient);
+}
+
+
+void
+xfsm_enable_verbose (void)
+{
+ if (!verbose)
+ {
+ verbose = TRUE;
+ printf ("xfce4-session: Session Manager running in verbose mode.\n");
+ }
+}
+
+gboolean
+xfsm_is_verbose_enabled (void)
+{
+ return verbose;
+}
+
+void
+xfsm_verbose_real (const char *func,
+ const char *file,
+ int line,
+ const char *format,
+ ...)
+{
+ static FILE *fp = NULL;
+ gchar *logfile;
+ va_list valist;
+
+ if (G_UNLIKELY (fp == NULL))
+ {
+ logfile = xfce_get_homefile (".xfce4-session.verbose-log", NULL);
+
+ /* rename an existing log file to -log.last */
+ if (logfile && g_file_test (logfile, G_FILE_TEST_EXISTS))
+ {
+ gchar *oldlogfile = g_strdup_printf ("%s.last", logfile);
+ if (oldlogfile)
+ {
+ rename (logfile, oldlogfile);
+ g_free (oldlogfile);
+ }
+ }
+
+ fp = fopen (logfile, "w");
+ g_free (logfile);
+ fprintf(fp, "log file opened\n");
+ }
+
+ fprintf (fp, "TRACE[%s:%d] %s(): ", file, line, func);
+ va_start (valist, format);
+ vfprintf (fp, format, valist);
+ fflush (fp);
+ va_end (valist);
+}
+
+
+gchar *
+xfsm_generate_client_id (SmsConn sms_conn)
+{
+ static char *addr = NULL;
+ static int sequence = 0;
+ char *sms_id;
+ char *id = NULL;
+
+ if (sms_conn != NULL)
+ {
+ sms_id = SmsGenerateClientID (sms_conn);
+ if (sms_id != NULL)
+ {
+ id = g_strdup (sms_id);
+ free (sms_id);
+ }
+ }
+
+ if (id == NULL)
+ {
+ if (addr == NULL)
+ {
+ /*
+ * Faking our IP address, the 0 below is "unknown"
+ * address format (1 would be IP, 2 would be DEC-NET
+ * format). Stolen from KDE :-)
+ */
+ addr = g_strdup_printf ("0%.8x", g_random_int ());
+ }
+
+ id = (char *) g_malloc (50);
+ g_snprintf (id, 50, "1%s%.13ld%.10d%.4d", addr,
+ (long) time (NULL), (int) getpid (), sequence);
+ sequence = (sequence + 1) % 10000;
+ }
+
+ return id;
+}
+
+
+GdkPixbuf *
+xfsm_load_session_preview (const gchar *name)
+{
+ GdkDisplay *display;
+ GdkPixbuf *pb = NULL;
+ gchar *display_name;
+ gchar *filename;
+ gchar *path;
+
+ /* determine thumb file */
+ display = gdk_display_get_default ();
+ display_name = xfsm_gdk_display_get_fullname (display);
+ path = g_strconcat ("sessions/thumbs-", display_name, "/", name, ".png", NULL);
+ filename = xfce_resource_lookup (XFCE_RESOURCE_CACHE, path);
+ g_free (display_name);
+ g_free (path);
+
+ if (filename != NULL)
+ pb = gdk_pixbuf_new_from_file (filename, NULL);
+ g_free (filename);
+
+ return pb;
+}
+
+
+GValue *
+xfsm_g_value_new (GType gtype)
+{
+ GValue *value = g_new0 (GValue, 1);
+ g_value_init (value, gtype);
+ return value;
+}
+
+
+void
+xfsm_g_value_free (GValue *value)
+{
+ if (G_LIKELY (value))
+ {
+ g_value_unset (value);
+ g_free (value);
+ }
+}
+
diff --git a/xfce4-session/xfsm-global.h b/xfce4-session/xfsm-global.h
new file mode 100644
index 0000000..d2e0c29
--- /dev/null
+++ b/xfce4-session/xfsm-global.h
@@ -0,0 +1,75 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifndef __XFSM_GLOBAL_H__
+#define __XFSM_GLOBAL_H__
+
+#include <glib.h>
+
+#include <X11/SM/SMlib.h>
+
+#include <xfce4-session/xfsm-splash-screen.h>
+#include <dbus/dbus.h>
+
+typedef struct _FailsafeClient FailsafeClient;
+struct _FailsafeClient
+{
+ gchar **command;
+ GdkScreen *screen;
+};
+
+void xfsm_failsafe_client_free (FailsafeClient *fclient);
+
+
+#define DEFAULT_SESSION_NAME "Default"
+
+
+extern gboolean verbose;
+extern XfsmSplashScreen *splash_screen;
+
+
+#if defined(G_HAVE_ISO_VARARGS)
+
+#define xfsm_verbose(...)\
+ xfsm_verbose_real (__func__, __FILE__, __LINE__, __VA_ARGS__)
+
+#else
+
+#define xfsm_verbose(...)
+
+#endif
+
+void xfsm_enable_verbose (void);
+gboolean xfsm_is_verbose_enabled (void);
+void xfsm_verbose_real (const char *func,
+ const char *file,
+ int line,
+ const char *format,
+ ...) G_GNUC_PRINTF (4, 5);
+
+gchar *xfsm_generate_client_id (SmsConn sms_conn) G_GNUC_PURE;
+
+GdkPixbuf *xfsm_load_session_preview (const gchar *name);
+
+GValue *xfsm_g_value_new (GType gtype);
+void xfsm_g_value_free (GValue *value);
+
+#endif /* !__XFSM_GLOBAL_H__ */
diff --git a/xfce4-session/xfsm-legacy.c b/xfce4-session/xfsm-legacy.c
new file mode 100644
index 0000000..932aeaf
--- /dev/null
+++ b/xfce4-session/xfsm-legacy.c
@@ -0,0 +1,672 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2004 Benedikt Meurer <benny@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ *
+ * Most of the code in this file is borred from ksmserver, the KDE session
+ * management server.
+ * Copyright (C) 2000 Matthias Ettrich <ettrich@kde.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/* After all, this code is mostly a hack now, one should cleanup the
+ * stuff before 4.2!
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <X11/Xatom.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include <gdk/gdkx.h>
+
+#include <libxfce4ui/libxfce4ui.h>
+
+#include <libwnck/libwnck.h>
+
+#include <xfce4-session/xfsm-global.h>
+#include <xfce4-session/xfsm-legacy.h>
+#include <libxfsm/xfsm-util.h>
+
+
+#ifdef LEGACY_SESSION_MANAGEMENT
+
+#define WM_SAVE_YOURSELF_TIMEOUT 4000
+
+enum
+{
+ SM_ERROR,
+ SM_WMCOMMAND,
+ SM_WMSAVEYOURSELF,
+};
+
+
+typedef struct _SmWindow SmWindow;
+struct _SmWindow
+{
+ gint type;
+ gchar **wm_command;
+ gchar *wm_client_machine;
+ gchar *wm_class1;
+ gchar *wm_class2;
+ Window wid;
+ gint screen_num;
+};
+#define SM_WINDOW(window) ((SmWindow *) (window))
+
+typedef struct
+{
+ gint screen_num;
+ gchar **command;
+} SmRestartApp;
+#define SM_RESTART_APP(a) ((SmRestartApp *) (a))
+
+
+static GList *restart_apps = NULL;
+static GList *window_list = NULL;
+
+
+/* X Atoms */
+static Atom _XA_WM_PROTOCOLS = None;
+static Atom _XA_WM_SAVE_YOURSELF = None;
+static Atom _XA_WM_CLIENT_LEADER = None;
+static Atom _XA_SM_CLIENT_ID = None;
+
+
+static SmWindow*
+sm_window_new (Window wid, gint screen_num, gint type,
+ gchar *wm_class1, gchar *wm_class2)
+{
+ SmWindow *smw;
+
+ smw = g_new0 (SmWindow, 1);
+ smw->wid = wid;
+ smw->type = type;
+ smw->wm_class1 = wm_class1;
+ smw->wm_class2 = wm_class2;
+ smw->screen_num = screen_num;
+
+ return smw;
+}
+
+
+static void
+sm_window_free (SmWindow *window)
+{
+ g_return_if_fail (window != NULL);
+
+ if (window->wm_command != NULL)
+ g_strfreev (window->wm_command);
+ if (window->wm_client_machine != NULL)
+ g_free (window->wm_client_machine);
+ if (window->wm_class1)
+ g_free (window->wm_class1);
+ if (window->wm_class2)
+ g_free (window->wm_class2);
+ g_free (window);
+}
+
+
+static void
+sm_window_list_clear (void)
+{
+ GList *lp;
+
+ for (lp = window_list; lp != NULL; lp = lp->next)
+ sm_window_free (SM_WINDOW (lp->data));
+
+ g_list_free (window_list);
+ window_list = NULL;
+}
+
+
+static gboolean
+sm_window_list_contains (Window window)
+{
+ GList *lp;
+
+ for (lp = window_list; lp != NULL; lp = lp->next)
+ if (SM_WINDOW (lp->data)->wid == window)
+ return TRUE;
+
+ return FALSE;
+}
+
+
+static int
+wins_error_handler (Display *display, XErrorEvent *event)
+{
+ GList *lp;
+ for (lp = window_list; lp != NULL; lp = lp->next)
+ if (SM_WINDOW (lp->data)->wid == event->resourceid)
+ SM_WINDOW (lp->data)->type = SM_ERROR;
+ return 0;
+}
+
+
+static gboolean
+has_xsmp_support (Window window)
+{
+ XTextProperty tp;
+ gboolean has_it = FALSE;
+
+ if (XGetTextProperty (gdk_display, window, &tp, _XA_SM_CLIENT_ID))
+ {
+ if (tp.encoding == XA_STRING && tp.format == 8 && tp.nitems != 0)
+ has_it = TRUE;
+
+ if (tp.value != NULL)
+ XFree ((char *) tp.value);
+ }
+
+ return has_it;
+}
+
+
+static gchar**
+get_wmcommand (Window window)
+{
+ gchar **result = NULL;
+ Status status;
+ char **argv;
+ int argc, i;
+
+ gdk_error_trap_push ();
+ status = XGetCommand (gdk_display, window, &argv, &argc);
+ if (gdk_error_trap_pop ())
+ return NULL;
+
+ if (status && argv && argc > 0)
+ {
+ result = g_new0 (gchar *, argc + 1);
+ for (i = 0; i < argc; ++i)
+ result[i] = g_strdup (argv[i]);
+ XFreeStringList (argv);
+ }
+
+ return result;
+}
+
+
+static gchar*
+get_wmclientmachine (Window window)
+{
+ XTextProperty tp;
+ gchar *result = NULL;
+ Status status;
+
+ gdk_error_trap_push ();
+ status = XGetWMClientMachine (gdk_display, window, &tp);
+ if (gdk_error_trap_pop ())
+ return NULL;
+
+ if (status)
+ {
+ if (tp.encoding == XA_STRING && tp.format == 8 && tp.nitems != 0)
+ result = g_strdup ((char *) tp.value);
+
+ if (tp.value != NULL)
+ XFree ((char *) tp.value);
+ }
+
+ if (result == NULL)
+ result = g_strdup ("localhost");
+
+ return result;
+}
+
+static Window
+get_clientleader (Window window)
+{
+ Atom type;
+ int format, status;
+ unsigned long nitems = 0;
+ unsigned long extra = 0;
+ unsigned char *data = 0;
+ Window result = window;
+
+ status = XGetWindowProperty (gdk_display, window, _XA_WM_CLIENT_LEADER,
+ 0, 10000, FALSE, XA_WINDOW, &type, &format,
+ &nitems, &extra, &data);
+ if (status == Success)
+ {
+ if (data != NULL && nitems > 0)
+ result = *((Window *) data);
+ XFree(data);
+ }
+
+ return result;
+}
+
+#endif
+
+
+void
+xfsm_legacy_perform_session_save (void)
+{
+#ifdef LEGACY_SESSION_MANAGEMENT
+ XErrorHandler old_handler;
+ WnckScreen *screen;
+ GList *windows;
+ GList *lp;
+ Window leader;
+ Display *display;
+ Atom *protocols;
+ int nprotocols;
+ XClassHint class_hint;
+ SmWindow *sm_window;
+ int n, i;
+ int type;
+ gchar *wmclass1;
+ gchar *wmclass2;
+ Window root, window;
+ XEvent ev;
+ int awaiting_replies = 0;
+ GTimer *timer;
+
+ /* clear window list */
+ sm_window_list_clear ();
+
+ /* query X atoms */
+ if (_XA_WM_SAVE_YOURSELF == None)
+ {
+ _XA_SM_CLIENT_ID = XInternAtom (gdk_display, "SM_CLIENT_ID", False);
+ _XA_WM_PROTOCOLS = XInternAtom (gdk_display, "WM_PROTOCOLS", False);
+ _XA_WM_SAVE_YOURSELF = XInternAtom (gdk_display, "WM_SAVE_YOURSELF",
+ False);
+ _XA_WM_CLIENT_LEADER = XInternAtom (gdk_display, "WM_CLIENT_LEADER",
+ False);
+ }
+
+ /* install custom X error handler */
+ old_handler = XSetErrorHandler (wins_error_handler);
+
+ /* query mapped windows on all screens */
+ for (n = 0; n < ScreenCount (gdk_display); ++n)
+ {
+ screen = wnck_screen_get (n);
+ wnck_screen_force_update (screen);
+
+ windows = wnck_screen_get_windows (screen);
+
+ for (lp = windows; lp != NULL; lp = lp->next)
+ {
+ window = wnck_window_get_xid (WNCK_WINDOW (lp->data));
+ leader = get_clientleader (window);
+ if (leader == None || sm_window_list_contains (leader)
+ || has_xsmp_support (window) || has_xsmp_support (leader))
+ {
+ xfsm_verbose ("window has no client leader or supports xspm, skipping\n");
+ continue;
+ }
+
+ type = SM_WMCOMMAND;
+ wmclass1 = NULL;
+ wmclass2 = NULL;
+
+ nprotocols = 0;
+ protocols = NULL;
+
+ if (XGetWMProtocols (gdk_display, leader, &protocols, &nprotocols))
+ {
+ for (i = 0; i < nprotocols; ++i)
+ if (protocols[i] == _XA_WM_SAVE_YOURSELF)
+ {
+ type = SM_WMSAVEYOURSELF;
+ break;
+ }
+ XFree ((void *) protocols);
+ }
+
+ if (XGetClassHint (gdk_display, leader, &class_hint))
+ {
+ wmclass2 = g_strdup (class_hint.res_class);
+ wmclass1 = g_strdup (class_hint.res_name);
+ XFree (class_hint.res_class);
+ XFree (class_hint.res_name);
+ }
+
+ sm_window = sm_window_new (leader, n, type, wmclass1, wmclass2);
+ window_list = g_list_append (window_list, sm_window);
+ }
+ }
+
+ /* open fresh display for sending WM_SAVE_YOURSELF commands */
+ XSync (gdk_display, False);
+ display = XOpenDisplay (DisplayString (gdk_display));
+ if (display == NULL)
+ {
+ XSetErrorHandler (old_handler);
+ return;
+ }
+
+ /* grab keyboard/pointer (XXX - check pointer pos first?) */
+ root = DefaultRootWindow (display);
+ XGrabKeyboard (display, root, False, GrabModeAsync, GrabModeAsync,
+ CurrentTime);
+ XGrabPointer (display, root, False, Button1Mask | Button2Mask | Button3Mask,
+ GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
+ for (lp = window_list; lp != NULL; lp = lp->next)
+ {
+ sm_window = SM_WINDOW (lp->data);
+ if (sm_window->type == SM_WMSAVEYOURSELF)
+ {
+ ++awaiting_replies;
+
+ bzero (&ev, sizeof (ev));
+
+ ev.xclient.type = ClientMessage;
+ ev.xclient.window = sm_window->wid;
+ ev.xclient.message_type = _XA_WM_PROTOCOLS;
+ ev.xclient.format = 32;
+ ev.xclient.data.l[0] = _XA_WM_SAVE_YOURSELF;
+ ev.xclient.data.l[1] = CurrentTime;
+ XSelectInput (display, sm_window->wid,
+ PropertyChangeMask | StructureNotifyMask);
+ XSendEvent (display, sm_window->wid, False, 0, &ev);
+ }
+ }
+
+ /* wait for change in WM_COMMAND with timeout */
+ XFlush (display);
+ timer = g_timer_new ();
+ while (awaiting_replies > 0)
+ {
+ if (XPending (display))
+ {
+ XNextEvent (display, &ev);
+ if (ev.type == UnmapNotify || (ev.type == PropertyNotify
+ && ev.xproperty.atom == XA_WM_COMMAND))
+ {
+ for (lp = window_list; lp != NULL; lp = lp->next)
+ {
+ if (SM_WINDOW (lp->data)->wid == ev.xany.window
+ && SM_WINDOW (lp->data)->type != SM_WMCOMMAND)
+ {
+ --awaiting_replies;
+ if (SM_WINDOW (lp->data)->type != SM_ERROR)
+ SM_WINDOW (lp->data)->type = SM_WMCOMMAND;
+ }
+ }
+ }
+ }
+ else
+ {
+ struct timeval tv;
+ fd_set fds;
+ int msecs;
+ int fd;
+ int ret;
+
+ msecs = (int)(g_timer_elapsed (timer, NULL) * 1000);
+ if (msecs >= WM_SAVE_YOURSELF_TIMEOUT)
+ break;
+
+ fd = ConnectionNumber (display);
+ FD_ZERO (&fds);
+ FD_SET (fd, &fds);
+ tv.tv_sec = (WM_SAVE_YOURSELF_TIMEOUT - msecs) / 1000;
+ tv.tv_usec = ((WM_SAVE_YOURSELF_TIMEOUT - msecs) % 1000) * 1000;
+ ret = select (fd + 1, &fds, NULL, &fds, &tv);
+ if (ret == -1)
+ {
+ perror ("select");
+ }
+ else if (ret == 0)
+ {
+ g_warning ("xfsm_legacy_perform_session_save, select: no data before timeout reached");
+ }
+ }
+ }
+ g_timer_destroy (timer);
+
+ /* Terminate work in new display */
+ XAllowEvents (display, ReplayPointer, CurrentTime);
+ XAllowEvents (display, ReplayKeyboard, CurrentTime);
+ XSync (display, False);
+ XCloseDisplay (display);
+ XSetErrorHandler (old_handler);
+
+ for (lp = window_list; lp != NULL; lp = lp->next)
+ {
+ sm_window = SM_WINDOW (lp->data);
+ if (sm_window->type != SM_ERROR)
+ {
+ sm_window->wm_command = get_wmcommand (sm_window->wid);
+ sm_window->wm_client_machine = get_wmclientmachine (sm_window->wid);
+ if (sm_window->wm_command == NULL || sm_window->wm_client_machine == NULL)
+ sm_window->type = SM_ERROR;
+ }
+ }
+#endif
+}
+
+
+void
+xfsm_legacy_store_session (XfceRc *rc)
+{
+#ifdef LEGACY_SESSION_MANAGEMENT
+ int count = 0;
+ SmWindow *sm_window;
+ GList *lp;
+ gchar buffer[256];
+
+ for (lp = window_list; lp != NULL; lp = lp->next)
+ {
+ sm_window = SM_WINDOW (lp->data);
+ if (sm_window->type != SM_ERROR)
+ {
+ /* xmms is b0rked, surprise, surprise */
+ if ((sm_window->wm_class1 != NULL
+ && strcmp (sm_window->wm_class1, "xmms") == 0)
+ || (sm_window->wm_class2 != NULL
+ && strcmp (sm_window->wm_class2, "xmms") == 0))
+ continue;
+
+ if (sm_window->wm_command == NULL
+ || sm_window->wm_client_machine == NULL)
+ continue;
+
+ if (xfsm_is_verbose_enabled ())
+ {
+ gchar *command = g_strjoinv (" ", sm_window->wm_command);
+ xfsm_verbose ("saving screen %d, command %s, machine %s\n",
+ sm_window->screen_num,
+ command,
+ sm_window->wm_client_machine);
+ g_free (command);
+ }
+
+ g_snprintf (buffer, 256, "Legacy%d_Screen", count);
+ xfce_rc_write_int_entry (rc, buffer, sm_window->screen_num);
+
+ g_snprintf (buffer, 256, "Legacy%d_Command", count);
+ xfce_rc_write_list_entry (rc, buffer, sm_window->wm_command, NULL);
+
+ g_snprintf (buffer, 256, "Legacy%d_ClientMachine", count);
+ xfce_rc_write_entry (rc, buffer, sm_window->wm_client_machine);
+
+ ++count;
+ }
+ }
+
+ xfce_rc_write_int_entry (rc, "LegacyCount", count);
+#endif
+}
+
+
+void
+xfsm_legacy_load_session (XfceRc *rc)
+{
+#ifdef LEGACY_SESSION_MANAGEMENT
+ gchar buffer[256];
+ int count;
+ int i;
+ gchar **command;
+ SmRestartApp *app;
+ int screen_num;
+
+ count = xfce_rc_read_int_entry (rc, "LegacyCount", 0);
+ for (i = 0; i < count; ++i)
+ {
+ g_snprintf (buffer, 256, "Legacy%d_Screen", i);
+ screen_num = xfce_rc_read_int_entry (rc, buffer, 0);
+
+ g_snprintf (buffer, 256, "Legacy%d_Command", i);
+ command = xfce_rc_read_list_entry (rc, buffer, NULL);
+ if (command == NULL)
+ {
+ xfsm_verbose ("legacy command == NULL\n");
+ continue;
+ }
+ else if (xfsm_is_verbose_enabled ())
+ {
+ gchar *dbg_command = g_strjoinv (" ", command);
+ xfsm_verbose ("legacy command %s\n", dbg_command);
+ g_free (dbg_command);
+ }
+
+ app = g_new0 (SmRestartApp, 1);
+ app->screen_num = screen_num;
+ app->command = command;
+
+ restart_apps = g_list_append (restart_apps, app);
+ }
+#endif
+}
+
+
+void
+xfsm_legacy_init (void)
+{
+#ifdef LEGACY_SESSION_MANAGEMENT
+ Atom dt_save_mode;
+ Atom dt_restore_mode;
+ Display *dpy;
+ Window root;
+ int n;
+
+ dpy = gdk_display;
+
+ /* Some CDE apps are broken (thanks again to Craig for the Sun Box :).
+ * Bugfix found on http://bugzilla.gnome.org/long_list.cgi?buglist=81343
+ * and implemented in gnome-session. The following code extends what
+ * gnome does, since it seems to be necessary to set both properties
+ * per screen, not just for the first screen. Anybody with access to
+ * CDE source code to enlighten me?
+ * -- bm, 20040530
+ */
+ dt_save_mode = XInternAtom (dpy, "_DT_SAVE_MODE", False);
+ dt_restore_mode = XInternAtom (dpy, "_DT_RESTORE_MODE", False);
+ for (n = 0; n < ScreenCount (dpy); ++n)
+ {
+ root = RootWindow (dpy, n);
+ XChangeProperty (dpy, root, dt_save_mode, XA_STRING, 8,
+ PropModeReplace, (unsigned char *)"xfce4", sizeof ("xfce4"));
+ XChangeProperty (dpy, root, dt_restore_mode, XA_STRING, 8,
+ PropModeReplace, (unsigned char *)"xfce4", sizeof ("xfce4"));
+ }
+#endif
+}
+
+
+void
+xfsm_legacy_startup (void)
+{
+#ifdef LEGACY_SESSION_MANAGEMENT
+ GdkScreen *screen;
+ GList *lp;
+
+ for (lp = restart_apps; lp != NULL; lp = lp->next)
+ {
+ screen = gdk_display_get_screen (gdk_display_get_default (),
+ SM_RESTART_APP (lp->data)->screen_num);
+ xfsm_start_application (SM_RESTART_APP (lp->data)->command, NULL,
+ screen, NULL, NULL, NULL);
+ g_strfreev (SM_RESTART_APP (lp->data)->command);
+ g_free (lp->data);
+ }
+
+ g_list_free (restart_apps);
+ restart_apps = NULL;
+#endif
+}
+
+
+void
+xfsm_legacy_shutdown (void)
+{
+#ifdef LEGACY_SESSION_MANAGEMENT
+ SmWindow *sm_window;
+ GList *lp;
+
+ gdk_error_trap_push ();
+
+ /* kill 'em all! */
+ for (lp = window_list; lp != NULL; lp = lp->next)
+ {
+ sm_window = SM_WINDOW (lp->data);
+ if (sm_window->wid != None)
+ XKillClient (gdk_display, sm_window->wid);
+ }
+
+ sm_window_list_clear ();
+
+ gdk_flush ();
+
+ gdk_error_trap_pop ();
+#endif
+}
+
+
+
diff --git a/xfce4-session/xfsm-legacy.h b/xfce4-session/xfsm-legacy.h
new file mode 100644
index 0000000..54602af
--- /dev/null
+++ b/xfce4-session/xfsm-legacy.h
@@ -0,0 +1,37 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2004 Benedikt Meurer <benny@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifndef __XFSM_LEGACY_H__
+#define __XFSM_LEGACY_H__
+
+#include <gdk/gdk.h>
+
+#include <libxfce4util/libxfce4util.h>
+
+
+void xfsm_legacy_perform_session_save (void);
+void xfsm_legacy_store_session (XfceRc *rc);
+void xfsm_legacy_load_session (XfceRc *rc);
+void xfsm_legacy_init (void);
+void xfsm_legacy_startup (void);
+void xfsm_legacy_shutdown (void);
+
+#endif /* !__XFSM_LEGACY_H__ */
diff --git a/xfce4-session/xfsm-logout-dialog.c b/xfce4-session/xfsm-logout-dialog.c
new file mode 100644
index 0000000..c86a155
--- /dev/null
+++ b/xfce4-session/xfsm-logout-dialog.c
@@ -0,0 +1,787 @@
+/*-
+ * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2011 Nick Schermer <nick@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ *
+ * Parts of this file where taken from gnome-session/logout.c, which
+ * was written by Owen Taylor <otaylor@redhat.com>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_MATH_H
+#include <math.h>
+#endif
+
+#include <libxfce4util/libxfce4util.h>
+#include <gtk/gtk.h>
+
+#include <libxfsm/xfsm-util.h>
+
+#include <xfce4-session/xfsm-logout-dialog.h>
+#include <xfce4-session/xfsm-fadeout.h>
+#include <xfce4-session/xfsm-global.h>
+#include <xfce4-session/xfsm-legacy.h>
+#include <xfce4-session/xfsm-error.h>
+
+#ifdef GDK_WINDOWING_X11
+#include <X11/Xlib.h>
+#include <gdk/gdkx.h>
+#endif
+
+
+
+#define BORDER 6
+#define SHOTSIZE 64
+
+
+
+static void xfsm_logout_dialog_finalize (GObject *object);
+static GtkWidget *xfsm_logout_dialog_button (const gchar *title,
+ const gchar *icon_name,
+ const gchar *icon_name_fallback,
+ XfsmShutdownType type,
+ XfsmLogoutDialog *dialog);
+
+
+
+enum
+{
+ MODE_LOGOUT_BUTTONS,
+ MODE_SHOW_ERROR,
+ N_MODES
+};
+
+struct _XfsmLogoutDialogClass
+{
+ GtkDialogClass __parent__;
+};
+
+struct _XfsmLogoutDialog
+{
+ GtkDialog __parent__;
+
+ /* set when a button is clicked */
+ XfsmShutdownType type_clicked;
+
+ /* save session checkbox */
+ GtkWidget *save_session;
+
+ /* mode widgets */
+ GtkWidget *box[N_MODES];
+
+ /* dialog buttons */
+ GtkWidget *button_cancel;
+ GtkWidget *button_ok;
+ GtkWidget *button_close;
+
+ /* error label */
+ GtkWidget *error_label;
+
+ /* pm instance */
+ XfsmShutdown *shutdown;
+};
+
+
+
+G_DEFINE_TYPE (XfsmLogoutDialog, xfsm_logout_dialog, GTK_TYPE_DIALOG)
+
+
+
+static void
+xfsm_logout_dialog_class_init (XfsmLogoutDialogClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = xfsm_logout_dialog_finalize;
+}
+
+
+
+static void
+xfsm_logout_dialog_init (XfsmLogoutDialog *dialog)
+{
+ const gchar *username;
+ GtkWidget *label;
+ gchar *label_str;
+ PangoAttrList *attrs;
+ GtkWidget *vbox;
+ GtkWidget *button_vbox;
+ GtkWidget *main_vbox;
+ GtkWidget *hbox;
+ GtkWidget *button;
+ gboolean can_shutdown;
+ gboolean save_session = FALSE;
+ gboolean can_restart;
+ gboolean can_suspend = FALSE;
+ gboolean can_hibernate = FALSE;
+ gboolean auth_suspend = FALSE;
+ gboolean auth_hibernate = FALSE;
+ GError *error = NULL;
+ XfconfChannel *channel;
+ GtkWidget *image;
+ GtkWidget *separator;
+ gboolean upower_not_found = FALSE;
+
+ dialog->type_clicked = XFSM_SHUTDOWN_LOGOUT;
+ dialog->shutdown = xfsm_shutdown_get ();
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);
+ gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
+ gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+
+ /* load xfconf settings */
+ channel = xfsm_open_config ();
+ if (xfsm_shutdown_can_save_session (dialog->shutdown))
+ save_session = xfconf_channel_get_bool (channel, "/general/SaveOnExit", TRUE);
+
+ main_vbox = gtk_vbox_new (FALSE, BORDER);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), main_vbox, TRUE, TRUE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (main_vbox), BORDER);
+ gtk_widget_show (main_vbox);
+
+ /* label showing the users' name */
+ username = g_get_real_name ();
+ if (username == NULL
+ || *username == '\0'
+ || strcmp ("Unknown", username) == 0)
+ username = g_get_user_name ();
+
+ label_str = g_strdup_printf (_("Log out %s"), username);
+ label = gtk_label_new (label_str);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
+ gtk_box_pack_start (GTK_BOX (main_vbox), label, FALSE, TRUE, 0);
+ gtk_widget_show (label);
+ g_free (label_str);
+
+ attrs = pango_attr_list_new ();
+ pango_attr_list_insert (attrs, pango_attr_scale_new (PANGO_SCALE_LARGE));
+ pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
+ gtk_label_set_attributes (GTK_LABEL (label), attrs);
+ pango_attr_list_unref (attrs);
+
+ separator = gtk_hseparator_new ();
+ gtk_box_pack_start (GTK_BOX (main_vbox), separator, FALSE, TRUE, 0);
+ gtk_widget_show (separator);
+
+ /**
+ * Start mode MODE_LOGOUT_BUTTONS
+ **/
+ dialog->box[MODE_LOGOUT_BUTTONS] = vbox = gtk_vbox_new (FALSE, BORDER);
+ gtk_box_pack_start (GTK_BOX (main_vbox), vbox, TRUE, TRUE, 0);
+
+ /**
+ * Cancel
+ **/
+ dialog->button_cancel = gtk_dialog_add_button (GTK_DIALOG (dialog),
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL);
+
+ button_vbox = gtk_vbox_new (TRUE, BORDER);
+ gtk_box_pack_start (GTK_BOX (vbox), button_vbox, FALSE, TRUE, 0);
+ gtk_widget_show (button_vbox);
+
+ /* row for logout/shutdown and reboot */
+ hbox = gtk_hbox_new (TRUE, BORDER);
+ gtk_box_pack_start (GTK_BOX (button_vbox), hbox, FALSE, TRUE, 0);
+ gtk_widget_show (hbox);
+
+ /**
+ * Logout
+ **/
+ button = xfsm_logout_dialog_button (_("_Log Out"), "system-log-out",
+ "xfsm-logout", XFSM_SHUTDOWN_LOGOUT,
+ dialog);
+
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_show (button);
+ gtk_widget_grab_focus (button);
+
+ /**
+ * Reboot
+ **/
+ if (!xfsm_shutdown_can_restart (dialog->shutdown, &can_restart, &error))
+ {
+ g_printerr ("%s: Querying CanRestart failed, %s\n\n",
+ PACKAGE_NAME, ERROR_MSG (error));
+ g_clear_error (&error);
+
+ can_restart = FALSE;
+ }
+
+ button = xfsm_logout_dialog_button (_("_Restart"), "system-reboot",
+ "xfsm-reboot", XFSM_SHUTDOWN_RESTART,
+ dialog);
+
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_set_sensitive (button, can_restart);
+ gtk_widget_show (button);
+
+ /**
+ * Shutdown
+ **/
+ if (!xfsm_shutdown_can_shutdown (dialog->shutdown, &can_shutdown, &error))
+ {
+ g_printerr ("%s: Querying CanShutdown failed. %s\n\n",
+ PACKAGE_NAME, ERROR_MSG (error));
+ g_clear_error (&error);
+
+ can_shutdown = FALSE;
+ }
+
+ button = xfsm_logout_dialog_button (_("Shut _Down"), "system-shutdown",
+ "xfsm-shutdown", XFSM_SHUTDOWN_SHUTDOWN,
+ dialog);
+
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_set_sensitive (button, can_shutdown);
+ gtk_widget_show (button);
+
+ /* new row for suspend/hibernate */
+ hbox = gtk_hbox_new (TRUE, BORDER);
+ gtk_box_pack_start (GTK_BOX (button_vbox), hbox, FALSE, TRUE, 0);
+
+ /**
+ * Suspend
+ *
+ * Hide the button if UPower is not installed or system cannot suspend
+ **/
+ if (xfconf_channel_get_bool (channel, "/shutdown/ShowSuspend", TRUE))
+ {
+ if (xfsm_shutdown_can_suspend (dialog->shutdown, &can_suspend, &auth_suspend, &error))
+ {
+ if (can_suspend)
+ {
+ button = xfsm_logout_dialog_button (_("Sus_pend"), "system-suspend",
+ "xfsm-suspend", XFSM_SHUTDOWN_SUSPEND,
+ dialog);
+
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_set_sensitive (button, auth_suspend);
+ gtk_widget_show (button);
+
+ gtk_widget_show (hbox);
+ }
+ }
+ else
+ {
+ g_printerr ("%s: Querying suspend failed: %s\n\n",
+ PACKAGE_NAME, ERROR_MSG (error));
+ g_clear_error (&error);
+
+ /* don't try hibernate again */
+ upower_not_found = TRUE;
+ }
+ }
+
+ /**
+ * Hibernate
+ *
+ * Hide the button if UPower is not installed or system cannot suspend
+ **/
+ if (!upower_not_found
+ && xfconf_channel_get_bool (channel, "/shutdown/ShowHibernate", TRUE))
+ {
+ if (xfsm_shutdown_can_hibernate (dialog->shutdown, &can_hibernate, &auth_hibernate, &error))
+ {
+ if (can_hibernate)
+ {
+ button = xfsm_logout_dialog_button (_("_Hibernate"), "system-hibernate",
+ "xfsm-hibernate", XFSM_SHUTDOWN_HIBERNATE,
+ dialog);
+
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ gtk_widget_set_sensitive (button, auth_hibernate);
+ gtk_widget_show (button);
+
+ gtk_widget_show (hbox);
+ }
+ }
+ else
+ {
+ g_printerr ("%s: Querying hibernate failed: %s\n\n",
+ PACKAGE_NAME, ERROR_MSG (error));
+ g_clear_error (&error);
+ }
+ }
+
+ /**
+ * Save session
+ **/
+ if (xfsm_shutdown_can_save_session (dialog->shutdown)
+ && !xfconf_channel_get_bool (channel, "/general/AutoSave", FALSE))
+ {
+ dialog->save_session = gtk_check_button_new_with_mnemonic (_("_Save session for future logins"));
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->save_session), save_session);
+ gtk_box_pack_start (GTK_BOX (vbox), dialog->save_session, FALSE, TRUE, BORDER);
+ gtk_widget_show (dialog->save_session);
+ }
+
+ attrs = pango_attr_list_new ();
+ pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
+
+
+ /**
+ * Start mode MODE_SHOW_ERROR
+ **/
+ dialog->box[MODE_SHOW_ERROR] = vbox = gtk_vbox_new (FALSE, BORDER);
+ gtk_box_pack_start (GTK_BOX (main_vbox), vbox, TRUE, TRUE, 0);
+
+ hbox = gtk_hbox_new (FALSE, BORDER * 2);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+ gtk_widget_show (hbox);
+
+ image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_DIALOG);
+ gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
+ gtk_widget_show (image);
+
+ vbox = gtk_vbox_new (FALSE, BORDER);
+ gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
+ gtk_widget_show (vbox);
+
+ label = gtk_label_new (_("An error occurred"));
+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.00, 0.50);
+ gtk_label_set_attributes (GTK_LABEL (label), attrs);
+ gtk_widget_show (label);
+
+ pango_attr_list_unref (attrs);
+}
+
+
+
+static void
+xfsm_logout_dialog_finalize (GObject *object)
+{
+ XfsmLogoutDialog *dialog = XFSM_LOGOUT_DIALOG (object);
+
+ g_object_unref (G_OBJECT (dialog->shutdown));
+
+ (*G_OBJECT_CLASS (xfsm_logout_dialog_parent_class)->finalize) (object);
+}
+
+
+
+static void
+xfsm_logout_dialog_set_mode (XfsmLogoutDialog *dialog,
+ gint mode)
+{
+ gint i;
+
+ for (i = 0; i < N_MODES; i++)
+ gtk_widget_set_visible (dialog->box[i], i == mode);
+
+ gtk_widget_set_visible (dialog->button_cancel, mode != MODE_SHOW_ERROR);
+ gtk_widget_set_visible (dialog->button_close, mode == MODE_SHOW_ERROR);
+}
+
+
+
+static void
+xfsm_logout_dialog_button_clicked (GtkWidget *button,
+ XfsmLogoutDialog *dialog)
+{
+ gint *val;
+
+ val = g_object_get_data (G_OBJECT (button), "shutdown-type");
+ g_assert (val != NULL);
+ dialog->type_clicked = *val;
+
+ gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+}
+
+
+
+static GtkWidget *
+xfsm_logout_dialog_button (const gchar *title,
+ const gchar *icon_name,
+ const gchar *icon_name_fallback,
+ XfsmShutdownType type,
+ XfsmLogoutDialog *dialog)
+{
+ GtkWidget *button;
+ GtkWidget *vbox;
+ GdkPixbuf *pixbuf;
+ GtkWidget *image;
+ GtkWidget *label;
+ static gint icon_size = 0;
+ gint w, h;
+ gint *val;
+ GtkIconTheme *icon_theme;
+
+ g_return_val_if_fail (XFSM_IS_LOGOUT_DIALOG (dialog), NULL);
+
+ val = g_new0 (gint, 1);
+ *val = type;
+
+ button = gtk_button_new ();
+ g_object_set_data_full (G_OBJECT (button), "shutdown-type", val, g_free);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (xfsm_logout_dialog_button_clicked), dialog);
+
+ vbox = gtk_vbox_new (FALSE, BORDER);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), BORDER);
+ gtk_container_add (GTK_CONTAINER (button), vbox);
+ gtk_widget_show (vbox);
+
+ if (G_UNLIKELY (icon_size == 0))
+ {
+ if (gtk_icon_size_lookup (GTK_ICON_SIZE_DND, &w, &h))
+ icon_size = MAX (w, h);
+ else
+ icon_size = 32;
+ }
+
+ icon_theme = gtk_icon_theme_get_for_screen (gtk_window_get_screen (GTK_WINDOW (dialog)));
+ pixbuf = gtk_icon_theme_load_icon (icon_theme, icon_name, icon_size, 0, NULL);
+ if (G_UNLIKELY (pixbuf == NULL))
+ {
+ pixbuf = gtk_icon_theme_load_icon (icon_theme, icon_name_fallback,
+ icon_size, GTK_ICON_LOOKUP_GENERIC_FALLBACK,
+ NULL);
+ }
+
+ image = gtk_image_new_from_pixbuf (pixbuf);
+ gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, FALSE, 0);
+ gtk_widget_show (image);
+
+ label = gtk_label_new_with_mnemonic (title);
+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
+
+ return button;
+}
+
+
+
+static GdkPixbuf *
+xfsm_logout_dialog_screenshot_new (GdkScreen *screen)
+{
+ GdkRectangle rect, screen_rect;
+ GdkWindow *window;
+ GdkPixbuf *screenshot;
+ gint x, y;
+
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+ screen_rect.x = 0;
+ screen_rect.y = 0;
+ screen_rect.width = gdk_screen_get_width (screen);
+ screen_rect.height = gdk_screen_get_height (screen);
+
+ window = gdk_screen_get_root_window (screen);
+ gdk_drawable_get_size (GDK_DRAWABLE (window), &rect.width, &rect.height);
+ gdk_window_get_origin (window, &x, &y);
+
+ rect.x = x;
+ rect.y = y;
+
+ if (!gdk_rectangle_intersect (&rect, &screen_rect, &rect))
+ return NULL;
+
+ screenshot = gdk_pixbuf_get_from_drawable (NULL,
+ GDK_DRAWABLE (window),
+ NULL,
+ 0, 0,
+ 0, 0,
+ rect.width,
+ rect.height);
+
+ gdk_display_beep (gdk_screen_get_display (screen));
+
+ return screenshot;
+}
+
+
+
+static GdkPixbuf *
+exo_gdk_pixbuf_scale_ratio (GdkPixbuf *source,
+ gint dest_size)
+{
+ gdouble wratio;
+ gdouble hratio;
+ gint source_width;
+ gint source_height;
+ gint dest_width;
+ gint dest_height;
+
+ g_return_val_if_fail (GDK_IS_PIXBUF (source), NULL);
+ g_return_val_if_fail (dest_size > 0, NULL);
+
+ source_width = gdk_pixbuf_get_width (source);
+ source_height = gdk_pixbuf_get_height (source);
+
+ wratio = (gdouble) source_width / (gdouble) dest_size;
+ hratio = (gdouble) source_height / (gdouble) dest_size;
+
+ if (hratio > wratio)
+ {
+ dest_width = rint (source_width / hratio);
+ dest_height = dest_size;
+ }
+ else
+ {
+ dest_width = dest_size;
+ dest_height = rint (source_height / wratio);
+ }
+
+ return gdk_pixbuf_scale_simple (source, MAX (dest_width, 1),
+ MAX (dest_height, 1), GDK_INTERP_BILINEAR);
+}
+
+
+
+static void
+xfsm_logout_dialog_screenshot_save (GdkPixbuf *screenshot,
+ GdkScreen *screen,
+ const gchar *session_name)
+{
+ GdkPixbuf *scaled;
+ gchar *path;
+ gchar *display_name;
+ GdkDisplay *dpy;
+ GError *error = NULL;
+ gchar *filename;
+
+ g_return_if_fail (GDK_IS_PIXBUF (screenshot));
+ g_return_if_fail (GDK_IS_SCREEN (screen));
+
+ scaled = exo_gdk_pixbuf_scale_ratio (screenshot, SHOTSIZE);
+ if (G_LIKELY (scaled != NULL))
+ {
+ dpy = gdk_screen_get_display (screen);
+ display_name = xfsm_gdk_display_get_fullname (dpy);
+ path = g_strconcat ("sessions/thumbs-", display_name, "/", session_name, ".png", NULL);
+ filename = xfce_resource_save_location (XFCE_RESOURCE_CACHE, path, TRUE);
+ g_free (display_name);
+ g_free (path);
+
+ if (!filename)
+ {
+ g_warning ("Unable to save screenshot, "
+ "error calling xfce_resource_save_location with %s, "
+ "check your permissions", path);
+ return;
+ }
+
+ if (!gdk_pixbuf_save (scaled, filename, "png", &error, NULL))
+ {
+ g_warning ("Failed to save session screenshot: %s", error->message);
+ g_error_free (error);
+ }
+
+ g_free (filename);
+ g_object_unref (G_OBJECT (scaled));
+ }
+}
+
+
+
+static gint
+xfsm_logout_dialog_run (GtkDialog *dialog,
+ gboolean grab_input)
+{
+ GdkWindow *window;
+ gint ret;
+
+ if (grab_input)
+ {
+ gtk_widget_show_now (GTK_WIDGET (dialog));
+
+ window = gtk_widget_get_window (GTK_WIDGET (dialog));
+ if (gdk_keyboard_grab (window, FALSE, GDK_CURRENT_TIME) != GDK_GRAB_SUCCESS)
+ g_critical ("Failed to grab the keyboard for logout window");
+
+#ifdef GDK_WINDOWING_X11
+ /* force input to the dialog */
+ gdk_error_trap_push ();
+ XSetInputFocus (GDK_DISPLAY (),
+ GDK_WINDOW_XWINDOW (window),
+ RevertToParent, CurrentTime);
+ gdk_error_trap_pop ();
+#endif
+ }
+
+ ret = gtk_dialog_run (dialog);
+
+ if (grab_input)
+ gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+
+ return ret;
+}
+
+
+
+gboolean
+xfsm_logout_dialog (const gchar *session_name,
+ XfsmShutdownType *return_type,
+ gboolean *return_save_session)
+{
+ gint result;
+ GtkWidget *hidden;
+ gboolean a11y;
+ GtkWidget *dialog;
+ GdkScreen *screen;
+ gint monitor;
+ GdkPixbuf *screenshot = NULL;
+ XfsmFadeout *fadeout = NULL;
+ XfsmLogoutDialog *xfsm_dialog;
+ XfconfChannel *channel = xfsm_open_config ();
+ gboolean autosave;
+ XfsmShutdown *shutdown;
+
+ g_return_val_if_fail (return_type != NULL, FALSE);
+ g_return_val_if_fail (return_save_session != NULL, FALSE);
+
+ shutdown = xfsm_shutdown_get ();
+ if (xfsm_shutdown_can_save_session (shutdown))
+ autosave = xfconf_channel_get_bool (channel, "/general/AutoSave", FALSE);
+ else
+ autosave = FALSE;
+ g_object_unref (shutdown);
+
+ /* check if we need to bother the user */
+ if (!xfconf_channel_get_bool (channel, "/general/PromptOnLogout", TRUE))
+ {
+ *return_type = XFSM_SHUTDOWN_LOGOUT;
+ *return_save_session = autosave;
+
+ return TRUE;
+ }
+
+ /* decide on which screen we should show the dialog */
+ screen = xfce_gdk_screen_get_active (&monitor);
+ if (G_UNLIKELY (screen == NULL))
+ {
+ screen = gdk_screen_get_default ();
+ monitor = 0;
+ }
+
+ /* check if accessibility is enabled */
+ hidden = gtk_invisible_new_for_screen (screen);
+ gtk_widget_show (hidden);
+ a11y = GTK_IS_ACCESSIBLE (gtk_widget_get_accessible (hidden));
+
+ if (G_LIKELY (!a11y))
+ {
+ /* wait until we can grab the keyboard, we need this for
+ * the dialog when running it */
+ for (;;)
+ {
+ if (gdk_keyboard_grab (gtk_widget_get_window (hidden), FALSE,
+ GDK_CURRENT_TIME) == GDK_GRAB_SUCCESS)
+ {
+ gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+ break;
+ }
+
+ g_usleep (G_USEC_PER_SEC / 20);
+ }
+
+ /* make a screenshot */
+ if (xfconf_channel_get_bool (channel, "/general/ShowScreenshots", TRUE))
+ screenshot = xfsm_logout_dialog_screenshot_new (screen);
+
+ /* display fadeout */
+ fadeout = xfsm_fadeout_new (gdk_screen_get_display (screen));
+ gdk_flush ();
+
+ dialog = g_object_new (XFSM_TYPE_LOGOUT_DIALOG,
+ "type", GTK_WINDOW_POPUP,
+ "screen", screen, NULL);
+
+ xfsm_window_add_border (GTK_WINDOW (dialog));
+
+ gtk_widget_realize (dialog);
+ gdk_window_set_override_redirect (dialog->window, TRUE);
+ gdk_window_raise (dialog->window);
+ }
+ else
+ {
+ dialog = g_object_new (XFSM_TYPE_LOGOUT_DIALOG,
+ "decorated", !a11y,
+ "screen", screen, NULL);
+
+ gtk_window_set_keep_above (GTK_WINDOW (dialog), TRUE);
+ atk_object_set_role (gtk_widget_get_accessible (dialog), ATK_ROLE_ALERT);
+ }
+
+ gtk_widget_destroy (hidden);
+
+ xfsm_dialog = XFSM_LOGOUT_DIALOG (dialog);
+
+ /* set mode */
+ xfsm_logout_dialog_set_mode (xfsm_dialog, MODE_LOGOUT_BUTTONS);
+
+ result = xfsm_logout_dialog_run (GTK_DIALOG (dialog), !a11y);
+
+ gtk_widget_hide (dialog);
+
+ if (result == GTK_RESPONSE_OK)
+ {
+ /* store autosave state */
+ if (autosave)
+ *return_save_session = TRUE;
+ else if (xfsm_dialog->save_session != NULL)
+ *return_save_session = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (xfsm_dialog->save_session));
+ else
+ *return_save_session = FALSE;
+
+ /* return the clicked action */
+ *return_type = xfsm_dialog->type_clicked;
+ }
+
+ if (fadeout != NULL)
+ xfsm_fadeout_destroy (fadeout);
+
+ gtk_widget_destroy (dialog);
+
+ /* store channel settings if everything worked fine */
+ if (result == GTK_RESPONSE_OK)
+ {
+ xfconf_channel_set_string (channel, "/general/SessionName", session_name);
+ xfconf_channel_set_bool (channel, "/general/SaveOnExit", *return_save_session);
+ }
+
+ /* save the screenshot */
+ if (screenshot != NULL)
+ {
+ if (result == GTK_RESPONSE_OK)
+ xfsm_logout_dialog_screenshot_save (screenshot, screen, session_name);
+ g_object_unref (G_OBJECT (screenshot));
+ }
+
+ return (result == GTK_RESPONSE_OK);
+}
diff --git a/xfce4-session/xfsm-logout-dialog.h b/xfce4-session/xfsm-logout-dialog.h
new file mode 100644
index 0000000..2cb0882
--- /dev/null
+++ b/xfce4-session/xfsm-logout-dialog.h
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2011 Nick Schermer <nick@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifndef __XFSM_LOGOUT_DIALOG_H__
+#define __XFSM_LOGOUT_DIALOG_H__
+
+#include <xfce4-session/xfsm-shutdown.h>
+
+typedef struct _XfsmLogoutDialogClass XfsmLogoutDialogClass;
+typedef struct _XfsmLogoutDialog XfsmLogoutDialog;
+
+#define XFSM_TYPE_LOGOUT_DIALOG (xfsm_logout_dialog_get_type ())
+#define XFSM_LOGOUT_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFSM_TYPE_LOGOUT_DIALOG, XfsmLogoutDialog))
+#define XFSM_LOGOUT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFSM_TYPE_LOGOUT_DIALOG, XfsmLogoutDialogClass))
+#define XFSM_IS_LOGOUT_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFSM_TYPE_LOGOUT_DIALOG))
+#define XFSM_IS_LOGOUT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFSM_TYPE_LOGOUT_DIALOG))
+#define XFSM_LOGOUT_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XFSM_TYPE_LOGOUT_DIALOG, XfsmLogoutDialogClass))
+
+GType xfsm_logout_dialog_get_type (void) G_GNUC_CONST;
+
+gboolean xfsm_logout_dialog (const gchar *session_name,
+ XfsmShutdownType *return_type,
+ gboolean *return_save_session);
+
+#endif
diff --git a/xfce4-session/xfsm-manager-dbus.h b/xfce4-session/xfsm-manager-dbus.h
new file mode 100644
index 0000000..5bfd92c
--- /dev/null
+++ b/xfce4-session/xfsm-manager-dbus.h
@@ -0,0 +1,372 @@
+/* Generated by dbus-binding-tool; do not edit! */
+
+
+#ifndef __dbus_glib_marshal_xfsm_manager_MARSHAL_H__
+#define __dbus_glib_marshal_xfsm_manager_MARSHAL_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#ifdef G_ENABLE_DEBUG
+#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
+#define g_marshal_value_peek_char(v) g_value_get_schar (v)
+#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
+#define g_marshal_value_peek_int(v) g_value_get_int (v)
+#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
+#define g_marshal_value_peek_long(v) g_value_get_long (v)
+#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
+#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
+#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
+#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
+#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
+#define g_marshal_value_peek_float(v) g_value_get_float (v)
+#define g_marshal_value_peek_double(v) g_value_get_double (v)
+#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
+#define g_marshal_value_peek_param(v) g_value_get_param (v)
+#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
+#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
+#define g_marshal_value_peek_object(v) g_value_get_object (v)
+#define g_marshal_value_peek_variant(v) g_value_get_variant (v)
+#else /* !G_ENABLE_DEBUG */
+/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
+ * Do not access GValues directly in your code. Instead, use the
+ * g_value_get_*() functions
+ */
+#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
+#define g_marshal_value_peek_char(v) (v)->data[0].v_int
+#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
+#define g_marshal_value_peek_int(v) (v)->data[0].v_int
+#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
+#define g_marshal_value_peek_long(v) (v)->data[0].v_long
+#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
+#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
+#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
+#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
+#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
+#define g_marshal_value_peek_float(v) (v)->data[0].v_float
+#define g_marshal_value_peek_double(v) (v)->data[0].v_double
+#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer
+#endif /* !G_ENABLE_DEBUG */
+
+
+/* BOOLEAN:POINTER */
+extern void dbus_glib_marshal_xfsm_manager_BOOLEAN__POINTER (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+void
+dbus_glib_marshal_xfsm_manager_BOOLEAN__POINTER (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+{
+ typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER) (gpointer data1,
+ gpointer arg_1,
+ gpointer data2);
+ register GMarshalFunc_BOOLEAN__POINTER callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+ gboolean v_return;
+
+ g_return_if_fail (return_value != NULL);
+ g_return_if_fail (n_param_values == 2);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_BOOLEAN__POINTER) (marshal_data ? marshal_data : cc->callback);
+
+ v_return = callback (data1,
+ g_marshal_value_peek_pointer (param_values + 1),
+ data2);
+
+ g_value_set_boolean (return_value, v_return);
+}
+
+/* BOOLEAN:STRING,POINTER */
+extern void dbus_glib_marshal_xfsm_manager_BOOLEAN__STRING_POINTER (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+void
+dbus_glib_marshal_xfsm_manager_BOOLEAN__STRING_POINTER (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+{
+ typedef gboolean (*GMarshalFunc_BOOLEAN__STRING_POINTER) (gpointer data1,
+ gpointer arg_1,
+ gpointer arg_2,
+ gpointer data2);
+ register GMarshalFunc_BOOLEAN__STRING_POINTER callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+ gboolean v_return;
+
+ g_return_if_fail (return_value != NULL);
+ g_return_if_fail (n_param_values == 3);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_BOOLEAN__STRING_POINTER) (marshal_data ? marshal_data : cc->callback);
+
+ v_return = callback (data1,
+ g_marshal_value_peek_string (param_values + 1),
+ g_marshal_value_peek_pointer (param_values + 2),
+ data2);
+
+ g_value_set_boolean (return_value, v_return);
+}
+
+/* BOOLEAN:POINTER,POINTER */
+extern void dbus_glib_marshal_xfsm_manager_BOOLEAN__POINTER_POINTER (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+void
+dbus_glib_marshal_xfsm_manager_BOOLEAN__POINTER_POINTER (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+{
+ typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER_POINTER) (gpointer data1,
+ gpointer arg_1,
+ gpointer arg_2,
+ gpointer data2);
+ register GMarshalFunc_BOOLEAN__POINTER_POINTER callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+ gboolean v_return;
+
+ g_return_if_fail (return_value != NULL);
+ g_return_if_fail (n_param_values == 3);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_BOOLEAN__POINTER_POINTER) (marshal_data ? marshal_data : cc->callback);
+
+ v_return = callback (data1,
+ g_marshal_value_peek_pointer (param_values + 1),
+ g_marshal_value_peek_pointer (param_values + 2),
+ data2);
+
+ g_value_set_boolean (return_value, v_return);
+}
+
+/* BOOLEAN:BOOLEAN,BOOLEAN,POINTER */
+extern void dbus_glib_marshal_xfsm_manager_BOOLEAN__BOOLEAN_BOOLEAN_POINTER (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+void
+dbus_glib_marshal_xfsm_manager_BOOLEAN__BOOLEAN_BOOLEAN_POINTER (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+{
+ typedef gboolean (*GMarshalFunc_BOOLEAN__BOOLEAN_BOOLEAN_POINTER) (gpointer data1,
+ gboolean arg_1,
+ gboolean arg_2,
+ gpointer arg_3,
+ gpointer data2);
+ register GMarshalFunc_BOOLEAN__BOOLEAN_BOOLEAN_POINTER callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+ gboolean v_return;
+
+ g_return_if_fail (return_value != NULL);
+ g_return_if_fail (n_param_values == 4);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_BOOLEAN__BOOLEAN_BOOLEAN_POINTER) (marshal_data ? marshal_data : cc->callback);
+
+ v_return = callback (data1,
+ g_marshal_value_peek_boolean (param_values + 1),
+ g_marshal_value_peek_boolean (param_values + 2),
+ g_marshal_value_peek_pointer (param_values + 3),
+ data2);
+
+ g_value_set_boolean (return_value, v_return);
+}
+
+/* BOOLEAN:POINTER,POINTER,POINTER,POINTER */
+extern void dbus_glib_marshal_xfsm_manager_BOOLEAN__POINTER_POINTER_POINTER_POINTER (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+void
+dbus_glib_marshal_xfsm_manager_BOOLEAN__POINTER_POINTER_POINTER_POINTER (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+{
+ typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER_POINTER_POINTER_POINTER) (gpointer data1,
+ gpointer arg_1,
+ gpointer arg_2,
+ gpointer arg_3,
+ gpointer arg_4,
+ gpointer data2);
+ register GMarshalFunc_BOOLEAN__POINTER_POINTER_POINTER_POINTER callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+ gboolean v_return;
+
+ g_return_if_fail (return_value != NULL);
+ g_return_if_fail (n_param_values == 5);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_BOOLEAN__POINTER_POINTER_POINTER_POINTER) (marshal_data ? marshal_data : cc->callback);
+
+ v_return = callback (data1,
+ g_marshal_value_peek_pointer (param_values + 1),
+ g_marshal_value_peek_pointer (param_values + 2),
+ g_marshal_value_peek_pointer (param_values + 3),
+ g_marshal_value_peek_pointer (param_values + 4),
+ data2);
+
+ g_value_set_boolean (return_value, v_return);
+}
+
+/* BOOLEAN:BOOLEAN,POINTER */
+extern void dbus_glib_marshal_xfsm_manager_BOOLEAN__BOOLEAN_POINTER (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+void
+dbus_glib_marshal_xfsm_manager_BOOLEAN__BOOLEAN_POINTER (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+{
+ typedef gboolean (*GMarshalFunc_BOOLEAN__BOOLEAN_POINTER) (gpointer data1,
+ gboolean arg_1,
+ gpointer arg_2,
+ gpointer data2);
+ register GMarshalFunc_BOOLEAN__BOOLEAN_POINTER callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+ gboolean v_return;
+
+ g_return_if_fail (return_value != NULL);
+ g_return_if_fail (n_param_values == 3);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_BOOLEAN__BOOLEAN_POINTER) (marshal_data ? marshal_data : cc->callback);
+
+ v_return = callback (data1,
+ g_marshal_value_peek_boolean (param_values + 1),
+ g_marshal_value_peek_pointer (param_values + 2),
+ data2);
+
+ g_value_set_boolean (return_value, v_return);
+}
+
+G_END_DECLS
+
+#endif /* __dbus_glib_marshal_xfsm_manager_MARSHAL_H__ */
+
+#include <dbus/dbus-glib.h>
+static const DBusGMethodInfo dbus_glib_xfsm_manager_methods[] = {
+ { (GCallback) xfsm_manager_dbus_get_info, dbus_glib_marshal_xfsm_manager_BOOLEAN__POINTER_POINTER_POINTER_POINTER, 0 },
+ { (GCallback) xfsm_manager_dbus_list_clients, dbus_glib_marshal_xfsm_manager_BOOLEAN__POINTER_POINTER, 80 },
+ { (GCallback) xfsm_manager_dbus_get_state, dbus_glib_marshal_xfsm_manager_BOOLEAN__POINTER_POINTER, 137 },
+ { (GCallback) xfsm_manager_dbus_checkpoint, dbus_glib_marshal_xfsm_manager_BOOLEAN__STRING_POINTER, 188 },
+ { (GCallback) xfsm_manager_dbus_logout, dbus_glib_marshal_xfsm_manager_BOOLEAN__BOOLEAN_BOOLEAN_POINTER, 244 },
+ { (GCallback) xfsm_manager_dbus_shutdown, dbus_glib_marshal_xfsm_manager_BOOLEAN__BOOLEAN_POINTER, 310 },
+ { (GCallback) xfsm_manager_dbus_can_shutdown, dbus_glib_marshal_xfsm_manager_BOOLEAN__POINTER_POINTER, 362 },
+ { (GCallback) xfsm_manager_dbus_restart, dbus_glib_marshal_xfsm_manager_BOOLEAN__BOOLEAN_POINTER, 423 },
+ { (GCallback) xfsm_manager_dbus_can_restart, dbus_glib_marshal_xfsm_manager_BOOLEAN__POINTER_POINTER, 474 },
+ { (GCallback) xfsm_manager_dbus_suspend, dbus_glib_marshal_xfsm_manager_BOOLEAN__POINTER, 533 },
+ { (GCallback) xfsm_manager_dbus_can_suspend, dbus_glib_marshal_xfsm_manager_BOOLEAN__POINTER_POINTER, 569 },
+ { (GCallback) xfsm_manager_dbus_hibernate, dbus_glib_marshal_xfsm_manager_BOOLEAN__POINTER, 628 },
+ { (GCallback) xfsm_manager_dbus_can_hibernate, dbus_glib_marshal_xfsm_manager_BOOLEAN__POINTER_POINTER, 666 },
+};
+
+const DBusGObjectInfo dbus_glib_xfsm_manager_object_info = { 1,
+ dbus_glib_xfsm_manager_methods,
+ 13,
+"org.xfce.Session.Manager\0GetInfo\0S\0name\0O\0F\0N\0s\0version\0O\0F\0N\0s\0vendor\0O\0F\0N\0s\0\0org.xfce.Session.Manager\0ListClients\0S\0clients\0O\0F\0N\0ao\0\0org.xfce.Session.Manager\0GetState\0S\0state\0O\0F\0N\0u\0\0org.xfce.Session.Manager\0Checkpoint\0S\0session_name\0I\0s\0\0org.xfce.Session.Manager\0Logout\0S\0show_dialog\0I\0b\0allow_save\0I\0b\0\0org.xfce.Session.Manager\0Shutdown\0S\0allow_save\0I\0b\0\0org.xfce.Session.Manager\0CanShutdown\0S\0can_shutdown\0O\0F\0N\0b\0\0org.xfce.Session.Manager\0Restart\0S\0allow_save\0I\0b\0\0org.xfce.Session.Manager\0CanRestart\0S\0can_restart\0O\0F\0N\0b\0\0org.xfce.Session.Manager\0Suspend\0S\0\0org.xfce.Session.Manager\0CanSuspend\0S\0can_suspend\0O\0F\0N\0b\0\0org.xfce.Session.Manager\0Hibernate\0S\0\0org.xfce.Session.Manager\0CanHibernate\0S\0can_hibernate\0O\0F\0N\0b\0\0\0",
+"org.xfce.Session.Manager\0StateChanged\0org.xfce.Session.Manager\0ClientRegistered\0org.xfce.Session.Manager\0ShutdownCancelled\0\0",
+"\0"
+};
+
diff --git a/xfce4-session/xfsm-manager-dbus.xml b/xfce4-session/xfsm-manager-dbus.xml
new file mode 100644
index 0000000..9b0c7c0
--- /dev/null
+++ b/xfce4-session/xfsm-manager-dbus.xml
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ TODO:
+
+ * define errors and list what methods can throw which errors
+ * be sure the states in both GetState() methods make sense,
+ and see if there are others that should be included
+ * should we include the SM client ID string in the ClientRegistered
+ and/or ClientDisconnected() signals?
+ * include a "ShutdownStarted" signal?
+ * extra shutdown type for "safe suspend" aka "s2both"?
+-->
+
+<node name="/org/xfce/SessionManager">
+ <interface name="org.xfce.Session.Manager">
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol"
+ value="xfsm_manager_dbus"/>
+ <annotation name="org.freedesktop.DBus.GLib.ClientCSymbol"
+ value="xfsm_manager_dbus_client"/>
+
+ <!--
+ (String, String, String) org.xfce.Session.Manager.GetInfo()
+
+ Returns:
+
+ @name: The session manager's name.
+ @version: The session manager's version.
+ @vendor: The vendor releasing the session manager.
+ -->
+ <method name="GetInfo">
+ <arg direction="out" name="name" type="s"/>
+ <arg direction="out" name="version" type="s"/>
+ <arg direction="out" name="vendor" type="s"/>
+ </method>
+
+ <!--
+ ObjectPath[] org.xfce.Session.Manager.ListClients()
+
+ Retrieves a list of session clients from the session
+ manager, as a list of D-Bus object paths. These
+ object paths all support the org.xfce.Session.Client
+ interface.
+ -->
+ <method name="ListClients">
+ <arg direction="out" name="clients" type="ao"/>
+ </method>
+
+ <!--
+ Unsigned Int org.xfce.Session.Manager.GetState()
+
+ Queries the session manager for its current operating
+ state. Valid values are:
+ 0 Startup: the session manager is starting up and
+ restoring clients from the previous session.
+ 1 Idle: the session manager has started up and is
+ waiting for client events.
+ 2 Checkpoint: the session manager is saving the
+ client list and instructing clients to save state.
+ 3 Shutdown: the session manager is shutting down.
+ 4 Shutdown Phase 2: the session manager is shutting
+ down and is allowing clients which have requested
+ extra time to save their state to do so.
+ -->
+ <method name="GetState">
+ <arg direction="out" name="state" type="u"/>
+ </method>
+
+ <!--
+ void org.Xfce.Session.Manager.Checkpoint(String session_name)
+
+ @session_name: The name of the session to save. Pass the
+ empty string ("") to use the name of the
+ currently-running session.
+
+ Instructs the session manager to save state and save all
+ client state, without ending the session.
+ -->
+ <method name="Checkpoint">
+ <arg direction="in" name="session_name" type="s"/>
+ </method>
+
+ <!--
+ void org.Xfce.Session.Manager.Logout
+ -->
+ <method name="Logout">
+ <arg direction="in" name="show_dialog" type="b"/>
+ <arg direction="in" name="allow_save" type="b"/>
+ </method>
+
+ <!--
+ void org.Xfce.Session.Manager.Shutdown
+ -->
+ <method name="Shutdown">
+ <arg direction="in" name="allow_save" type="b"/>
+ </method>
+
+ <!--
+ void org.Xfce.Session.Manager.CanShutdown
+ -->
+ <method name="CanShutdown">
+ <arg direction="out" name="can_shutdown" type="b"/>
+ </method>
+
+ <!--
+ void org.Xfce.Session.Manager.Restart
+ -->
+ <method name="Restart">
+ <arg direction="in" name="allow_save" type="b"/>
+ </method>
+
+ <!--
+ void org.Xfce.Session.Manager.CanRestart
+ -->
+ <method name="CanRestart">
+ <arg direction="out" name="can_restart" type="b"/>
+ </method>
+
+ <!--
+ void org.Xfce.Session.Manager.Suspend
+
+ This will possibly be removed in the future
+ -->
+ <method name="Suspend" />
+
+ <!--
+ void org.Xfce.Session.Manager.CanSuspend
+
+ This will possibly be removed in the future
+ -->
+ <method name="CanSuspend">
+ <arg direction="out" name="can_suspend" type="b"/>
+ </method>
+
+ <!--
+ void org.Xfce.Session.Manager.Hibernate
+
+ This will possibly be removed in the future
+ -->
+ <method name="Hibernate" />
+
+ <!--
+ void org.Xfce.Session.Manager.CanHibernate
+
+ This will possibly be removed in the future
+ -->
+ <method name="CanHibernate">
+ <arg direction="out" name="can_hibernate" type="b"/>
+ </method>
+
+ <!--
+ void org.xfce.Session.Manager.StateChanged(Unsigned Int old_state,
+ Unsigned Int new_state)
+
+ @old_state: The SM's previous state.
+ @new_state: The SM's new (current) state.
+
+ Emitted when the session manager's state changes.
+ See GetState() above for valid values for the
+ arguments.
+ -->
+ <signal name="StateChanged">
+ <arg name="old_state" type="u"/>
+ <arg name="new_state" type="u"/>
+ </signal>
+
+ <!--
+ void org.xfce.Session.Manager.ClientRegistered(ObjectPath client)
+
+ @client: A D-Bus object path.
+
+ Emitted when a new client is registered.
+ -->
+ <signal name="ClientRegistered">
+ <arg name="client" type="o"/>
+ </signal>
+
+ <!--
+ void org.xfce.Session.Manager.ShutdownCancelled()
+
+ Emitted when a previously-started shutdown has been
+ cancelled.
+ -->
+ <signal name="ShutdownCancelled"/>
+ </interface>
+</node>
diff --git a/xfce4-session/xfsm-manager.c b/xfce4-session/xfsm-manager.c
new file mode 100644
index 0000000..999e420
--- /dev/null
+++ b/xfce4-session/xfsm-manager.c
@@ -0,0 +1,2178 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/*-
+ * Copyright (c) 2003-2006 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2008 Brian Tarricone <bjt23@cornell.edu>
+ * Copyright (c) 2010 Jannis Pohlmann <jannis@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* unfortunately, glibc doesn't have a wrapper for the ioprio_set ()
+ * syscall, so we have to do it the hard way. also, it seems some
+ * systems don't have <linux/ioprio.h>, so i'll copy the defines here.
+ */
+#ifdef HAVE_ASM_UNISTD_H
+# include <asm/unistd.h>
+# include <sys/syscall.h>
+# ifdef __NR_ioprio_set
+# ifdef HAVE_WORKING_LINUX_IOPRIO_H
+# include <linux/ioprio.h>
+# else /* if !HAVE_WORKING_LINUX_IOPRIO_H */
+# define IOPRIO_CLASS_SHIFT (13)
+# define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1)
+# define IOPRIO_PRIO_VALUE(class, data) (((class) << IOPRIO_CLASS_SHIFT) | data)
+# define IOPRIO_WHO_PROCESS (1)
+# define IOPRIO_CLASS_IDLE (3)
+# endif /* !HAVE_WORKING_LINUX_IOPRIO_H */
+# endif /* __NR_ioprio_set */
+#endif /* HAVE_ASM_UNISTD_H */
+
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include <X11/ICE/ICElib.h>
+#include <X11/SM/SMlib.h>
+
+#include <gdk-pixbuf/gdk-pixdata.h>
+#include <gtk/gtk.h>
+
+#include <libwnck/libwnck.h>
+
+#include <libxfce4ui/libxfce4ui.h>
+
+#include <libxfsm/xfsm-splash-engine.h>
+#include <libxfsm/xfsm-util.h>
+
+#include <xfce4-session/xfsm-manager.h>
+#include <xfce4-session/xfsm-chooser-icon.h>
+#include <xfce4-session/xfsm-chooser.h>
+#include <xfce4-session/xfsm-global.h>
+#include <xfce4-session/xfsm-legacy.h>
+#include <xfce4-session/xfsm-startup.h>
+#include <xfce4-session/xfsm-marshal.h>
+#include <xfce4-session/xfsm-error.h>
+#include <xfce4-session/xfsm-logout-dialog.h>
+
+
+#define DEFAULT_SESSION_NAME "Default"
+
+
+struct _XfsmManager
+{
+ GObject parent;
+
+ XfsmManagerState state;
+
+ XfsmShutdownType shutdown_type;
+ XfsmShutdown *shutdown_helper;
+ gboolean save_session;
+
+ gboolean session_chooser;
+ gchar *session_name;
+ gchar *session_file;
+ gchar *checkpoint_session_name;
+
+ gboolean start_at;
+
+ gboolean compat_gnome;
+ gboolean compat_kde;
+
+ GQueue *starting_properties;
+ GQueue *pending_properties;
+ GQueue *restart_properties;
+ GQueue *running_clients;
+
+ gboolean failsafe_mode;
+ GQueue *failsafe_clients;
+
+ guint die_timeout_id;
+
+ DBusGConnection *session_bus;
+};
+
+typedef struct _XfsmManagerClass
+{
+ GObjectClass parent;
+
+ /*< signals >*/
+ void (*state_changed) (XfsmManager *manager,
+ XfsmManagerState old_state,
+ XfsmManagerState new_state);
+
+ void (*client_registered) (XfsmManager *manager,
+ const gchar *client_object_path);
+
+ void (*shutdown_cancelled) (XfsmManager *manager);
+} XfsmManagerClass;
+
+typedef struct
+{
+ XfsmManager *manager;
+ XfsmClient *client;
+ guint timeout_id;
+} XfsmSaveTimeoutData;
+
+typedef struct
+{
+ XfsmManager *manager;
+ XfsmShutdownType type;
+ gboolean allow_save;
+} ShutdownIdleData;
+
+enum
+{
+ SIG_STATE_CHANGED = 0,
+ SIG_CLIENT_REGISTERED,
+ SIG_SHUTDOWN_CANCELLED,
+ N_SIGS,
+};
+
+
+static void xfsm_manager_finalize (GObject *obj);
+
+static gboolean xfsm_manager_startup (XfsmManager *manager);
+static void xfsm_manager_start_client_save_timeout (XfsmManager *manager,
+ XfsmClient *client);
+static void xfsm_manager_cancel_client_save_timeout (XfsmManager *manager,
+ XfsmClient *client);
+static gboolean xfsm_manager_save_timeout (gpointer user_data);
+static void xfsm_manager_load_settings (XfsmManager *manager,
+ XfconfChannel *channel);
+static gboolean xfsm_manager_load_session (XfsmManager *manager);
+static void xfsm_manager_dbus_class_init (XfsmManagerClass *klass);
+static void xfsm_manager_dbus_init (XfsmManager *manager);
+static void xfsm_manager_dbus_cleanup (XfsmManager *manager);
+
+
+static guint signals[N_SIGS] = { 0, };
+
+
+G_DEFINE_TYPE(XfsmManager, xfsm_manager, G_TYPE_OBJECT)
+
+
+static void
+xfsm_manager_class_init (XfsmManagerClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *)klass;
+
+ gobject_class->finalize = xfsm_manager_finalize;
+
+ signals[SIG_STATE_CHANGED] = g_signal_new ("state-changed",
+ XFSM_TYPE_MANAGER,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (XfsmManagerClass,
+ state_changed),
+ NULL, NULL,
+ xfsm_marshal_VOID__UINT_UINT,
+ G_TYPE_NONE, 2,
+ G_TYPE_UINT, G_TYPE_UINT);
+
+ signals[SIG_CLIENT_REGISTERED] = g_signal_new ("client-registered",
+ XFSM_TYPE_MANAGER,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (XfsmManagerClass,
+ client_registered),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ signals[SIG_SHUTDOWN_CANCELLED] = g_signal_new ("shutdown-cancelled",
+ XFSM_TYPE_MANAGER,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (XfsmManagerClass,
+ shutdown_cancelled),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ xfsm_manager_dbus_class_init (klass);
+}
+
+
+static void
+xfsm_manager_init (XfsmManager *manager)
+{
+ manager->state = XFSM_MANAGER_STARTUP;
+ manager->session_chooser = FALSE;
+ manager->failsafe_mode = TRUE;
+ manager->shutdown_type = XFSM_SHUTDOWN_LOGOUT;
+ manager->shutdown_helper = xfsm_shutdown_get ();
+ manager->save_session = TRUE;
+
+ manager->pending_properties = g_queue_new ();
+ manager->starting_properties = g_queue_new ();
+ manager->restart_properties = g_queue_new ();
+ manager->running_clients = g_queue_new ();
+ manager->failsafe_clients = g_queue_new ();
+}
+
+static void
+xfsm_manager_finalize (GObject *obj)
+{
+ XfsmManager *manager = XFSM_MANAGER(obj);
+
+ xfsm_manager_dbus_cleanup (manager);
+
+ if (manager->die_timeout_id != 0)
+ g_source_remove (manager->die_timeout_id);
+
+ g_object_unref (manager->shutdown_helper);
+
+ g_queue_foreach (manager->pending_properties, (GFunc) xfsm_properties_free, NULL);
+ g_queue_free (manager->pending_properties);
+
+ g_queue_foreach (manager->starting_properties, (GFunc) xfsm_properties_free, NULL);
+ g_queue_free (manager->starting_properties);
+
+ g_queue_foreach (manager->restart_properties, (GFunc) xfsm_properties_free, NULL);
+ g_queue_free (manager->restart_properties);
+
+ g_queue_foreach (manager->running_clients, (GFunc) g_object_unref, NULL);
+ g_queue_free (manager->running_clients);
+
+ g_queue_foreach (manager->failsafe_clients, (GFunc) xfsm_failsafe_client_free, NULL);
+ g_queue_free (manager->failsafe_clients);
+
+ g_free (manager->session_name);
+ g_free (manager->session_file);
+ g_free (manager->checkpoint_session_name);
+
+ G_OBJECT_CLASS (xfsm_manager_parent_class)->finalize (obj);
+}
+
+
+#ifdef G_CAN_INLINE
+static inline void
+#else
+static void
+#endif
+xfsm_manager_set_state (XfsmManager *manager,
+ XfsmManagerState state)
+{
+ XfsmManagerState old_state;
+
+ /* idea here is to use this to set state always so we don't forget
+ * to emit the signal */
+
+ if (state == manager->state)
+ return;
+
+ old_state = manager->state;
+ manager->state = state;
+
+ xfsm_verbose ("\nstate is now %s\n",
+ state == XFSM_MANAGER_STARTUP ? "XFSM_MANAGER_STARTUP" :
+ state == XFSM_MANAGER_IDLE ? "XFSM_MANAGER_IDLE" :
+ state == XFSM_MANAGER_CHECKPOINT ? "XFSM_MANAGER_CHECKPOINT" :
+ state == XFSM_MANAGER_SHUTDOWN ? "XFSM_MANAGER_SHUTDOWN" :
+ state == XFSM_MANAGER_SHUTDOWNPHASE2 ? "XFSM_MANAGER_SHUTDOWNPHASE2" :
+ "unknown");
+
+ g_signal_emit (manager, signals[SIG_STATE_CHANGED], 0, old_state, state);
+}
+
+
+XfsmManager *
+xfsm_manager_new (void)
+{
+ XfsmManager *manager = g_object_new (XFSM_TYPE_MANAGER, NULL);
+
+ xfsm_manager_dbus_init (manager);
+
+ return manager;
+}
+
+
+static gboolean
+xfsm_manager_startup (XfsmManager *manager)
+{
+ xfsm_startup_foreign (manager);
+ g_queue_sort (manager->pending_properties, (GCompareDataFunc) xfsm_properties_compare, NULL);
+ xfsm_startup_begin (manager);
+ return FALSE;
+}
+
+
+static void
+xfsm_manager_restore_active_workspace (XfsmManager *manager,
+ XfceRc *rc)
+{
+ WnckWorkspace *workspace;
+ GdkDisplay *display;
+ WnckScreen *screen;
+ gchar buffer[1024];
+ gint n, m;
+
+ display = gdk_display_get_default ();
+ for (n = 0; n < gdk_display_get_n_screens (display); ++n)
+ {
+ g_snprintf (buffer, 1024, "Screen%d_ActiveWorkspace", n);
+ xfsm_verbose ("Attempting to restore %s\n", buffer);
+ if (!xfce_rc_has_entry (rc, buffer))
+ {
+ xfsm_verbose ("no entry found\n");
+ continue;
+ }
+
+ m = xfce_rc_read_int_entry (rc, buffer, 0);
+
+ screen = wnck_screen_get (n);
+ wnck_screen_force_update (screen);
+
+ if (wnck_screen_get_workspace_count (screen) > m)
+ {
+ workspace = wnck_screen_get_workspace (screen, m);
+ wnck_workspace_activate (workspace, GDK_CURRENT_TIME);
+ }
+ }
+}
+
+
+gboolean
+xfsm_manager_handle_failed_properties (XfsmManager *manager,
+ XfsmProperties *properties)
+{
+ gint restart_style_hint;
+ GError *error = NULL;
+
+ /* Handle apps that failed to start, or died randomly, here */
+
+ xfsm_properties_set_default_child_watch (properties);
+
+ if (properties->restart_attempts_reset_id > 0)
+ {
+ g_source_remove (properties->restart_attempts_reset_id);
+ properties->restart_attempts_reset_id = 0;
+ }
+
+ restart_style_hint = xfsm_properties_get_uchar (properties,
+ SmRestartStyleHint,
+ SmRestartIfRunning);
+
+ if (restart_style_hint == SmRestartAnyway)
+ {
+ xfsm_verbose ("Client id %s died or failed to start, restarting anyway\n", properties->client_id);
+ g_queue_push_tail (manager->restart_properties, properties);
+ }
+ else if (restart_style_hint == SmRestartImmediately)
+ {
+ if (++properties->restart_attempts > MAX_RESTART_ATTEMPTS)
+ {
+ xfsm_verbose ("Client Id = %s, reached maximum attempts [Restart attempts = %d]\n"
+ " Will be re-scheduled for run on next startup\n",
+ properties->client_id, properties->restart_attempts);
+
+ g_queue_push_tail (manager->restart_properties, properties);
+ }
+ else
+ {
+ xfsm_verbose ("Client Id = %s disconnected, restarting\n",
+ properties->client_id);
+
+ if (G_UNLIKELY (!xfsm_startup_start_properties (properties, manager)))
+ {
+ /* this failure has nothing to do with the app itself, so
+ * just add it to restart props */
+ g_queue_push_tail (manager->restart_properties, properties);
+ }
+ else
+ {
+ /* put it back in the starting list */
+ g_queue_push_tail (manager->starting_properties, properties);
+ }
+ }
+ }
+ else
+ {
+ gchar **discard_command;
+
+ /* We get here if a SmRestartNever or SmRestartIfRunning client
+ * has exited. SmRestartNever clients shouldn't have discard
+ * commands, but it can't hurt to run it if it has one for some
+ * reason, and might clean up garbage we don't want. */
+ xfsm_verbose ("Client Id %s exited, removing from session.\n",
+ properties->client_id);
+
+ discard_command = xfsm_properties_get_strv (properties, SmDiscardCommand);
+ if (discard_command != NULL && g_strv_length (discard_command) > 0)
+ {
+ /* Run the SmDiscardCommand after the client exited in any state,
+ * but only if we don't expect the client to be restarted,
+ * whether immediately or in the next session.
+ *
+ * NB: This used to also have the condition that the manager is
+ * in the IDLE state, but this was removed because I can't see
+ * why you'd treat a client that fails during startup any
+ * differently, and this fixes a potential properties leak.
+ *
+ * Unfortunately the spec isn't clear about the usage of the
+ * discard command. Have to check ksmserver/gnome-session, and
+ * come up with consistent behaviour.
+ *
+ * But for now, this work-around fixes the problem of the
+ * ever-growing number of xfwm4 session files when restarting
+ * xfwm4 within a session.
+ */
+ xfsm_verbose ("Client Id = %s: running discard command %s:%d.\n\n",
+ properties->client_id, *discard_command,
+ g_strv_length (discard_command));
+
+ if (!g_spawn_sync (xfsm_properties_get_string (properties, SmCurrentDirectory),
+ discard_command,
+ xfsm_properties_get_strv (properties, SmEnvironment),
+ G_SPAWN_SEARCH_PATH,
+ NULL, NULL,
+ NULL, NULL,
+ NULL, &error))
+ {
+ g_warning ("Failed to running discard command \"%s\": %s",
+ *discard_command, error->message);
+ g_error_free (error);
+ }
+ }
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+static gboolean
+xfsm_manager_choose_session (XfsmManager *manager,
+ XfceRc *rc)
+{
+ XfsmSessionInfo *session;
+ GdkPixbuf *preview_default = NULL;
+ gboolean load = FALSE;
+ GList *sessions = NULL;
+ GList *lp;
+ gchar **groups;
+ gchar *name;
+ gint result;
+ gint n;
+
+ groups = xfce_rc_get_groups (rc);
+ for (n = 0; groups[n] != NULL; ++n)
+ {
+ if (strncmp (groups[n], "Session: ", 9) == 0)
+ {
+ xfce_rc_set_group (rc, groups[n]);
+ session = g_new0 (XfsmSessionInfo, 1);
+ session->name = groups[n] + 9;
+ session->atime = xfce_rc_read_int_entry (rc, "LastAccess", 0);
+ session->preview = xfsm_load_session_preview (session->name);
+
+ if (session->preview == NULL)
+ {
+ if (G_UNLIKELY (preview_default == NULL))
+ {
+ preview_default = gdk_pixbuf_new_from_inline (-1, xfsm_chooser_icon_data,
+ FALSE, NULL);
+ }
+
+ session->preview = GDK_PIXBUF (g_object_ref (preview_default));
+ }
+
+ sessions = g_list_append (sessions, session);
+ }
+ }
+
+ if (preview_default != NULL)
+ g_object_unref (preview_default);
+
+ if (sessions != NULL)
+ {
+ result = xfsm_splash_screen_choose (splash_screen, sessions,
+ manager->session_name, &name);
+
+ if (result == XFSM_CHOOSE_LOGOUT)
+ {
+ xfce_rc_close (rc);
+ exit (EXIT_SUCCESS);
+ }
+ else if (result == XFSM_CHOOSE_LOAD)
+ {
+ load = TRUE;
+ }
+
+ if (manager->session_name != NULL)
+ g_free (manager->session_name);
+ manager->session_name = name;
+
+ for (lp = sessions; lp != NULL; lp = lp->next)
+ {
+ session = (XfsmSessionInfo *) lp->data;
+ g_object_unref (session->preview);
+ g_free (session);
+ }
+
+ g_list_free (sessions);
+ }
+
+ g_strfreev (groups);
+
+ return load;
+}
+
+
+static gboolean
+xfsm_manager_load_session (XfsmManager *manager)
+{
+ XfsmProperties *properties;
+ gchar buffer[1024];
+ XfceRc *rc;
+ gint count;
+
+ if (!g_file_test (manager->session_file, G_FILE_TEST_IS_REGULAR))
+ {
+ g_warning ("xfsm_manager_load_session: Something wrong with %s, Does it exist? Permissions issue?", manager->session_file);
+ return FALSE;
+ }
+
+ rc = xfce_rc_simple_open (manager->session_file, FALSE);
+ if (G_UNLIKELY (rc == NULL))
+ {
+ g_warning ("xfsm_manager_load_session: unable to open %s", manager->session_file);
+ return FALSE;
+ }
+
+ if (manager->session_chooser && !xfsm_manager_choose_session (manager, rc))
+ {
+ g_warning ("xfsm_manager_load_session: failed to choose session");
+ xfce_rc_close (rc);
+ return FALSE;
+ }
+
+ g_snprintf (buffer, 1024, "Session: %s", manager->session_name);
+ xfsm_verbose ("loading %s\n", buffer);
+
+ xfce_rc_set_group (rc, buffer);
+ count = xfce_rc_read_int_entry (rc, "Count", 0);
+ if (G_UNLIKELY (count <= 0))
+ {
+ xfce_rc_close (rc);
+ return FALSE;
+ }
+
+ while (count-- > 0)
+ {
+ g_snprintf (buffer, 1024, "Client%d_", count);
+ properties = xfsm_properties_load (rc, buffer);
+ if (G_UNLIKELY (properties == NULL))
+ {
+ xfsm_verbose ("%s has no properties. Skipping\n", buffer);
+ continue;
+ }
+ if (xfsm_properties_check (properties))
+ g_queue_push_tail (manager->pending_properties, properties);
+ else
+ {
+ xfsm_verbose ("%s has invalid properties. Skipping\n", buffer);
+ xfsm_properties_free (properties);
+ }
+ }
+
+ xfsm_verbose ("Finished loading clients from rc file\n");
+
+ /* load legacy applications */
+ xfsm_legacy_load_session (rc);
+
+ xfce_rc_close (rc);
+
+ return g_queue_peek_head (manager->pending_properties) != NULL;
+}
+
+
+static gboolean
+xfsm_manager_load_failsafe (XfsmManager *manager,
+ XfconfChannel *channel,
+ gchar **error)
+{
+ FailsafeClient *fclient;
+ gchar *failsafe_name;
+ GdkDisplay *display;
+ gchar propbuf[4096];
+ gchar **command;
+ gchar command_entry[256];
+ gchar screen_entry[256];
+ gint count;
+ gint i;
+ gint n_screen;
+
+ failsafe_name = xfconf_channel_get_string (channel, "/general/FailsafeSessionName", NULL);
+ if (G_UNLIKELY (!failsafe_name))
+ {
+ if (error)
+ *error = g_strdup_printf (_("Unable to determine failsafe session name. Possible causes: xfconfd isn't running (D-Bus setup problem); environment variable $XDG_CONFIG_DIRS is set incorrectly (must include \"%s\"), or xfce4-session is installed incorrectly."),
+ SYSCONFDIR);
+ return FALSE;
+ }
+
+ g_snprintf (propbuf, sizeof (propbuf), "/sessions/%s/IsFailsafe",
+ failsafe_name);
+ if (!xfconf_channel_get_bool (channel, propbuf, FALSE))
+ {
+ if (error)
+ {
+ *error = g_strdup_printf (_("The specified failsafe session (\"%s\") is not marked as a failsafe session."),
+ failsafe_name);
+ }
+ g_free (failsafe_name);
+ return FALSE;
+ }
+
+ display = gdk_display_get_default ();
+
+ g_snprintf (propbuf, sizeof (propbuf), "/sessions/%s/Count", failsafe_name);
+ count = xfconf_channel_get_int (channel, propbuf, 0);
+
+ for (i = 0; i < count; ++i)
+ {
+ g_snprintf (command_entry, sizeof (command_entry),
+ "/sessions/%s/Client%d_Command", failsafe_name, i);
+ command = xfconf_channel_get_string_list (channel, command_entry);
+ if (G_UNLIKELY (command == NULL))
+ continue;
+
+ g_snprintf (screen_entry, sizeof (screen_entry),
+ "/sessions/%s/Client%d_PerScreen", failsafe_name, i);
+ if (xfconf_channel_get_bool (channel, screen_entry, FALSE))
+ {
+ for (n_screen = 0; n_screen < gdk_display_get_n_screens (display); ++n_screen)
+ {
+ fclient = g_new0 (FailsafeClient, 1);
+ if (n_screen == 0)
+ fclient->command = command;
+ else
+ fclient->command = g_strdupv (command);
+ fclient->screen = gdk_display_get_screen (display, n_screen);
+ g_queue_push_tail (manager->failsafe_clients, fclient);
+ }
+ }
+ else
+ {
+ fclient = g_new0 (FailsafeClient, 1);
+ fclient->command = command;
+ fclient->screen = gdk_screen_get_default ();
+ g_queue_push_tail (manager->failsafe_clients, fclient);
+ }
+ }
+
+ if (g_queue_peek_head (manager->failsafe_clients) == NULL)
+ {
+ if (error)
+ *error = g_strdup (_("The list of applications in the failsafe session is empty."));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+static void
+xfsm_manager_load_settings (XfsmManager *manager,
+ XfconfChannel *channel)
+{
+ gboolean session_loaded = FALSE;
+
+ manager->session_name = xfconf_channel_get_string (channel,
+ "/general/SessionName",
+ DEFAULT_SESSION_NAME);
+ if (G_UNLIKELY (manager->session_name[0] == '\0'))
+ {
+ g_free (manager->session_name);
+ manager->session_name = g_strdup (DEFAULT_SESSION_NAME);
+ }
+
+ manager->session_chooser = xfconf_channel_get_bool (channel, "/chooser/AlwaysDisplay", FALSE);
+
+ session_loaded = xfsm_manager_load_session (manager);
+
+ if (session_loaded)
+ {
+ xfsm_verbose ("Session \"%s\" loaded successfully.\n\n", manager->session_name);
+ manager->failsafe_mode = FALSE;
+ }
+ else
+ {
+ gchar *errorstr = NULL;
+
+ if (!xfsm_manager_load_failsafe (manager, channel, &errorstr))
+ {
+ if (G_LIKELY (splash_screen != NULL))
+ {
+ xfsm_splash_screen_free (splash_screen);
+ splash_screen = NULL;
+ }
+
+ /* FIXME: migrate this into the splash screen somehow so the
+ * window doesn't look ugly (right now no WM is running, so it
+ * won't have window decorations). */
+ xfce_message_dialog (NULL, _("Session Manager Error"),
+ GTK_STOCK_DIALOG_ERROR,
+ _("Unable to load a failsafe session"),
+ errorstr,
+ GTK_STOCK_QUIT, GTK_RESPONSE_ACCEPT, NULL);
+ g_free (errorstr);
+ exit (EXIT_FAILURE);
+ }
+ manager->failsafe_mode = TRUE;
+ }
+}
+
+
+void
+xfsm_manager_load (XfsmManager *manager,
+ XfconfChannel *channel)
+{
+ gchar *display_name;
+ gchar *resource_name;
+#ifdef HAVE_OS_CYGWIN
+ gchar *s;
+#endif
+
+ manager->compat_gnome = xfconf_channel_get_bool (channel, "/compat/LaunchGNOME", FALSE);
+ manager->compat_kde = xfconf_channel_get_bool (channel, "/compat/LaunchKDE", FALSE);
+ manager->start_at = xfconf_channel_get_bool (channel, "/general/StartAssistiveTechnologies", FALSE);
+
+ display_name = xfsm_gdk_display_get_fullname (gdk_display_get_default ());
+
+#ifdef HAVE_OS_CYGWIN
+ /* rename a colon (:) to a hash (#) under cygwin. windows doesn't like
+ * filenames with a colon... */
+ for (s = display_name; *s != '\0'; ++s)
+ if (*s == ':')
+ *s = '#';
+#endif
+
+ resource_name = g_strconcat ("sessions/xfce4-session-", display_name, NULL);
+ manager->session_file = xfce_resource_save_location (XFCE_RESOURCE_CACHE, resource_name, TRUE);
+ g_free (resource_name);
+ g_free (display_name);
+
+ xfsm_manager_load_settings (manager, channel);
+}
+
+
+gboolean
+xfsm_manager_restart (XfsmManager *manager)
+{
+ GdkPixbuf *preview;
+ unsigned steps;
+
+ g_assert (manager->session_name != NULL);
+
+ /* setup legacy application handling */
+ xfsm_legacy_init ();
+
+ /* tell splash screen that the session is starting now */
+ preview = xfsm_load_session_preview (manager->session_name);
+ if (preview == NULL)
+ preview = gdk_pixbuf_new_from_inline (-1, xfsm_chooser_icon_data, FALSE, NULL);
+ steps = g_queue_get_length (manager->failsafe_mode ? manager->failsafe_clients : manager->pending_properties);
+ xfsm_splash_screen_start (splash_screen, manager->session_name, preview, steps);
+ g_object_unref (preview);
+
+ g_idle_add ((GSourceFunc) xfsm_manager_startup, manager);
+
+ return TRUE;
+}
+
+
+void
+xfsm_manager_signal_startup_done (XfsmManager *manager)
+{
+ gchar buffer[1024];
+ XfceRc *rc;
+
+ xfsm_verbose ("Manager finished startup, entering IDLE mode now\n\n");
+ xfsm_manager_set_state (manager, XFSM_MANAGER_IDLE);
+
+ if (!manager->failsafe_mode)
+ {
+ /* restore active workspace, this has to be done after the
+ * window manager is up, so we do it last.
+ */
+ g_snprintf (buffer, 1024, "Session: %s", manager->session_name);
+ rc = xfce_rc_simple_open (manager->session_file, TRUE);
+ xfce_rc_set_group (rc, buffer);
+ xfsm_manager_restore_active_workspace (manager, rc);
+ xfce_rc_close (rc);
+
+ /* start legacy applications now */
+ xfsm_legacy_startup ();
+ }
+}
+
+
+XfsmClient*
+xfsm_manager_new_client (XfsmManager *manager,
+ SmsConn sms_conn,
+ gchar **error)
+{
+ XfsmClient *client = NULL;
+
+ if (G_UNLIKELY (manager->state != XFSM_MANAGER_IDLE)
+ && G_UNLIKELY (manager->state != XFSM_MANAGER_STARTUP))
+ {
+ if (error != NULL)
+ *error = "We don't accept clients while in CheckPoint/Shutdown state!";
+ return NULL;
+ }
+
+ client = xfsm_client_new (manager, sms_conn);
+ return client;
+}
+
+
+static gboolean
+xfsm_manager_reset_restart_attempts (gpointer data)
+{
+ XfsmProperties *properties = data;
+
+ properties->restart_attempts = 0;
+ properties->restart_attempts_reset_id = 0;
+
+ return FALSE;
+}
+
+
+gboolean
+xfsm_manager_register_client (XfsmManager *manager,
+ XfsmClient *client,
+ const gchar *previous_id)
+{
+ XfsmProperties *properties = NULL;
+ gchar *client_id;
+ GList *lp;
+ SmsConn sms_conn;
+
+ sms_conn = xfsm_client_get_sms_connection (client);
+
+ if (previous_id != NULL)
+ {
+ lp = g_queue_find_custom (manager->starting_properties,
+ previous_id,
+ (GCompareFunc) xfsm_properties_compare_id);
+ if (lp != NULL)
+ {
+ properties = XFSM_PROPERTIES (lp->data);
+ g_queue_delete_link (manager->starting_properties, lp);
+ }
+ else
+ {
+ lp = g_queue_find_custom (manager->pending_properties,
+ previous_id,
+ (GCompareFunc) xfsm_properties_compare_id);
+ if (lp != NULL)
+ {
+ properties = XFSM_PROPERTIES (lp->data);
+ g_queue_delete_link (manager->pending_properties, lp);
+ }
+ }
+
+ /* If previous_id is invalid, the SM will send a BadValue error message
+ * to the client and reverts to register state waiting for another
+ * RegisterClient message.
+ */
+ if (properties == NULL)
+ {
+ xfsm_verbose ("Client Id = %s registering, failed to find matching "
+ "properties\n", previous_id);
+ return FALSE;
+ }
+
+ /* cancel startup timer */
+ if (properties->startup_timeout_id > 0)
+ {
+ g_source_remove (properties->startup_timeout_id);
+ properties->startup_timeout_id = 0;
+ }
+
+ /* cancel the old child watch, and replace it with one that
+ * doesn't really do anything but reap the child */
+ xfsm_properties_set_default_child_watch (properties);
+
+ xfsm_client_set_initial_properties (client, properties);
+
+ /* if we've been restarted, we'll want to reset the restart
+ * attempts counter if the client stays alive for a while */
+ if (properties->restart_attempts > 0 && properties->restart_attempts_reset_id == 0)
+ {
+ properties->restart_attempts_reset_id = g_timeout_add (RESTART_RESET_TIMEOUT,
+ xfsm_manager_reset_restart_attempts,
+ properties);
+ }
+ }
+ else
+ {
+ client_id = xfsm_generate_client_id (sms_conn);
+ properties = xfsm_properties_new (client_id, SmsClientHostName (sms_conn));
+ xfsm_client_set_initial_properties (client, properties);
+ g_free (client_id);
+ }
+
+ g_queue_push_tail (manager->running_clients, client);
+
+ SmsRegisterClientReply (sms_conn, (char *) xfsm_client_get_id (client));
+
+ g_signal_emit (manager, signals[SIG_CLIENT_REGISTERED], 0,
+ xfsm_client_get_object_path (client));
+
+ if (previous_id == NULL)
+ {
+ SmsSaveYourself (sms_conn, SmSaveLocal, False, SmInteractStyleNone, False);
+ xfsm_client_set_state (client, XFSM_CLIENT_SAVINGLOCAL);
+ xfsm_manager_start_client_save_timeout (manager, client);
+ }
+
+ if (previous_id != NULL && manager->state == XFSM_MANAGER_STARTUP)
+ {
+ /* Only continue the startup if the previous_id matched one of
+ * the starting_properties. If there was no match above,
+ * previous_id will be NULL here. We don't need to continue when
+ * in failsafe mode because in that case the failsafe session is
+ * started all at once.
+ */
+ if (g_queue_peek_head (manager->starting_properties) == NULL)
+ xfsm_startup_session_continue (manager);
+ }
+
+ return TRUE;
+}
+
+
+void
+xfsm_manager_start_interact (XfsmManager *manager,
+ XfsmClient *client)
+{
+ /* notify client of interact */
+ SmsInteract (xfsm_client_get_sms_connection (client));
+ xfsm_client_set_state (client, XFSM_CLIENT_INTERACTING);
+
+ /* stop save yourself timeout */
+ xfsm_manager_cancel_client_save_timeout (manager, client);
+}
+
+
+void
+xfsm_manager_interact (XfsmManager *manager,
+ XfsmClient *client,
+ int dialog_type)
+{
+ GList *lp;
+
+ if (G_UNLIKELY (xfsm_client_get_state (client) != XFSM_CLIENT_SAVING))
+ {
+ xfsm_verbose ("Client Id = %s, requested INTERACT, but client is not in SAVING mode\n"
+ " Client will be disconnected now.\n\n",
+ xfsm_client_get_id (client));
+ xfsm_manager_close_connection (manager, client, TRUE);
+ }
+ else if (G_UNLIKELY (manager->state != XFSM_MANAGER_CHECKPOINT)
+ && G_UNLIKELY (manager->state != XFSM_MANAGER_SHUTDOWN))
+ {
+ xfsm_verbose ("Client Id = %s, requested INTERACT, but manager is not in CheckPoint/Shutdown mode\n"
+ " Client will be disconnected now.\n\n",
+ xfsm_client_get_id (client));
+ xfsm_manager_close_connection (manager, client, TRUE);
+ }
+ else
+ {
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
+ {
+ XfsmClient *cl = lp->data;
+ if (xfsm_client_get_state (cl) == XFSM_CLIENT_INTERACTING)
+ {
+ /* a client is already interacting, so new client has to wait */
+ xfsm_client_set_state (client, XFSM_CLIENT_WAITFORINTERACT);
+ xfsm_manager_cancel_client_save_timeout(manager, client);
+ return;
+ }
+ }
+
+ xfsm_manager_start_interact (manager, client);
+ }
+}
+
+
+void
+xfsm_manager_interact_done (XfsmManager *manager,
+ XfsmClient *client,
+ gboolean cancel_shutdown)
+{
+ GList *lp;
+
+ if (G_UNLIKELY (xfsm_client_get_state (client) != XFSM_CLIENT_INTERACTING))
+ {
+ xfsm_verbose ("Client Id = %s, send INTERACT DONE, but client is not in INTERACTING state\n"
+ " Client will be disconnected now.\n\n",
+ xfsm_client_get_id (client));
+ xfsm_manager_close_connection (manager, client, TRUE);
+ return;
+ }
+ else if (G_UNLIKELY (manager->state != XFSM_MANAGER_CHECKPOINT)
+ && G_UNLIKELY (manager->state != XFSM_MANAGER_SHUTDOWN))
+ {
+ xfsm_verbose ("Client Id = %s, send INTERACT DONE, but manager is not in CheckPoint/Shutdown state\n"
+ " Client will be disconnected now.\n\n",
+ xfsm_client_get_id (client));
+ xfsm_manager_close_connection (manager, client, TRUE);
+ return;
+ }
+
+ xfsm_client_set_state (client, XFSM_CLIENT_SAVING);
+
+ /* Setting the cancel-shutdown field to True indicates that the user
+ * has requested that the entire shutdown be cancelled. Cancel-
+ * shutdown may only be True if the corresponding SaveYourself
+ * message specified True for the shutdown field and Any or Error
+ * for the interact-style field. Otherwise, cancel-shutdown must be
+ * False.
+ */
+ if (cancel_shutdown && manager->state == XFSM_MANAGER_SHUTDOWN)
+ {
+ /* we go into checkpoint state from here... */
+ xfsm_manager_set_state (manager, XFSM_MANAGER_CHECKPOINT);
+
+ /* If a shutdown is in progress, the user may have the option
+ * of cancelling the shutdown. If the shutdown is cancelled
+ * (specified in the "Interact Done" message), the session
+ * manager should send a "Shutdown Cancelled" message to each
+ * client that requested to interact.
+ */
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
+ {
+ XfsmClient *cl = lp->data;
+ if (xfsm_client_get_state (cl) != XFSM_CLIENT_WAITFORINTERACT)
+ continue;
+
+ /* reset all clients that are waiting for interact */
+ xfsm_client_set_state (client, XFSM_CLIENT_SAVING);
+ SmsShutdownCancelled (xfsm_client_get_sms_connection (cl));
+ }
+
+ g_signal_emit (manager, signals[SIG_SHUTDOWN_CANCELLED], 0);
+ }
+ else
+ {
+ /* let next client interact */
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
+ {
+ XfsmClient *cl = lp->data;
+ if (xfsm_client_get_state (cl) == XFSM_CLIENT_WAITFORINTERACT)
+ {
+ xfsm_manager_start_interact (manager, cl);
+ break;
+ }
+ }
+ }
+
+ /* restart save yourself timeout for client */
+ xfsm_manager_start_client_save_timeout (manager, client);
+}
+
+
+static void
+xfsm_manager_save_yourself_global (XfsmManager *manager,
+ gint save_type,
+ gboolean shutdown,
+ gint interact_style,
+ gboolean fast,
+ XfsmShutdownType shutdown_type,
+ gboolean allow_shutdown_save)
+{
+ gboolean shutdown_save = allow_shutdown_save;
+ GList *lp;
+ GError *error = NULL;
+
+ xfsm_verbose ("entering");
+
+ if (shutdown)
+ {
+ if (!fast && shutdown_type == XFSM_SHUTDOWN_ASK)
+ {
+ /* if we're not specifying fast shutdown, and we're ok with
+ * prompting then ask the user what to do */
+ if (!xfsm_logout_dialog (manager->session_name, &manager->shutdown_type, &shutdown_save))
+ return;
+
+ /* |allow_shutdown_save| is ignored if we prompt the user. i think
+ * this is the right thing to do. */
+ }
+
+ /* update shutdown type if we didn't prompt the user */
+ if (shutdown_type != XFSM_SHUTDOWN_ASK)
+ manager->shutdown_type = shutdown_type;
+
+ /* we only save the session and quit if we're actually shutting down;
+ * suspend and hibernate will (if successful) return us to
+ * exactly the same state, so there's no need to save session */
+ if (manager->shutdown_type == XFSM_SHUTDOWN_SUSPEND
+ || manager->shutdown_type == XFSM_SHUTDOWN_HIBERNATE)
+ {
+ if (!xfsm_shutdown_try_type (manager->shutdown_helper,
+ manager->shutdown_type,
+ &error))
+ {
+ xfce_message_dialog (NULL, _("Shutdown Failed"),
+ GTK_STOCK_DIALOG_ERROR,
+ manager->shutdown_type == XFSM_SHUTDOWN_SUSPEND
+ ? _("Failed to suspend session")
+ : _("Failed to hibernate session"),
+ error->message,
+ GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT,
+ NULL);
+ g_error_free (error);
+ }
+
+ /* at this point, either we failed to suspend/hibernate, or we
+ * successfully suspended/hibernated, and we've been woken back
+ * up, so return control to the user */
+ return;
+ }
+ }
+
+ /* don't save the session if shutting down without save */
+ manager->save_session = !shutdown || shutdown_save;
+
+ if (save_type == SmSaveBoth && !manager->save_session)
+ {
+ /* saving the session, so clients should
+ * (prompt to) save the user data only */
+ save_type = SmSaveGlobal;
+ }
+
+ xfsm_manager_set_state (manager,
+ shutdown
+ ? XFSM_MANAGER_SHUTDOWN
+ : XFSM_MANAGER_CHECKPOINT);
+
+ /* handle legacy applications first! */
+ if (manager->save_session)
+ xfsm_legacy_perform_session_save ();
+
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
+ {
+ XfsmClient *client = lp->data;
+ XfsmProperties *properties = xfsm_client_get_properties (client);
+ const gchar *program;
+
+ /* xterm's session management is broken, so we won't
+ * send a SAVE YOURSELF to xterms */
+ program = xfsm_properties_get_string (properties, SmProgram);
+ if (program != NULL && strcasecmp (program, "xterm") == 0)
+ continue;
+
+ if (xfsm_client_get_state (client) != XFSM_CLIENT_SAVINGLOCAL)
+ {
+ SmsSaveYourself (xfsm_client_get_sms_connection (client), save_type, shutdown,
+ interact_style, fast);
+ }
+
+ xfsm_client_set_state (client, XFSM_CLIENT_SAVING);
+ xfsm_manager_start_client_save_timeout (manager, client);
+ }
+}
+
+
+void
+xfsm_manager_save_yourself (XfsmManager *manager,
+ XfsmClient *client,
+ gint save_type,
+ gboolean shutdown,
+ gint interact_style,
+ gboolean fast,
+ gboolean global)
+{
+ xfsm_verbose ("entering");
+
+ if (G_UNLIKELY (xfsm_client_get_state (client) != XFSM_CLIENT_IDLE))
+ {
+
+
+ xfsm_verbose ("Client Id = %s, requested SAVE YOURSELF, but client is not in IDLE mode.\n"
+ " Client will be nuked now.\n\n",
+ xfsm_client_get_id (client));
+ xfsm_manager_close_connection (manager, client, TRUE);
+ return;
+ }
+ else if (G_UNLIKELY (manager->state != XFSM_MANAGER_IDLE))
+ {
+ xfsm_verbose ("Client Id = %s, requested SAVE YOURSELF, but manager is not in IDLE mode.\n"
+ " Client will be nuked now.\n\n",
+ xfsm_client_get_id (client));
+ xfsm_manager_close_connection (manager, client, TRUE);
+ return;
+ }
+
+ if (!global)
+ {
+ /* client requests a local checkpoint. We slightly ignore
+ * shutdown here, since it does not make sense for a local
+ * checkpoint.
+ */
+ SmsSaveYourself (xfsm_client_get_sms_connection (client), save_type, FALSE, interact_style, fast);
+ xfsm_client_set_state (client, XFSM_CLIENT_SAVINGLOCAL);
+ xfsm_manager_start_client_save_timeout (manager, client);
+ }
+ else
+ xfsm_manager_save_yourself_global (manager, save_type, shutdown, interact_style, fast, XFSM_SHUTDOWN_ASK, TRUE);
+}
+
+
+void
+xfsm_manager_save_yourself_phase2 (XfsmManager *manager,
+ XfsmClient *client)
+{
+ xfsm_verbose ("entering");
+
+ if (manager->state != XFSM_MANAGER_CHECKPOINT && manager->state != XFSM_MANAGER_SHUTDOWN)
+ {
+ SmsSaveYourselfPhase2 (xfsm_client_get_sms_connection (client));
+ xfsm_client_set_state (client, XFSM_CLIENT_SAVINGLOCAL);
+ xfsm_manager_start_client_save_timeout (manager, client);
+ }
+ else
+ {
+ xfsm_client_set_state (client, XFSM_CLIENT_WAITFORPHASE2);
+ xfsm_manager_cancel_client_save_timeout (manager, client);
+
+ if (!xfsm_manager_check_clients_saving (manager))
+ xfsm_manager_maybe_enter_phase2 (manager);
+ }
+}
+
+
+void
+xfsm_manager_save_yourself_done (XfsmManager *manager,
+ XfsmClient *client,
+ gboolean success)
+{
+ xfsm_verbose ("entering");
+
+ /* In xfsm_manager_interact_done we send SmsShutdownCancelled to clients in
+ XFSM_CLIENT_WAITFORINTERACT state. They respond with SmcSaveYourselfDone
+ (xsmp_shutdown_cancelled in libxfce4ui library) so we allow it here. */
+ if (xfsm_client_get_state (client) != XFSM_CLIENT_SAVING &&
+ xfsm_client_get_state (client) != XFSM_CLIENT_SAVINGLOCAL &&
+ xfsm_client_get_state (client) != XFSM_CLIENT_WAITFORINTERACT)
+ {
+ xfsm_verbose ("Client Id = %s send SAVE YOURSELF DONE, while not being "
+ "in save mode. Prepare to be nuked!\n",
+ xfsm_client_get_id (client));
+
+ xfsm_manager_close_connection (manager, client, TRUE);
+ }
+
+ /* remove client save timeout, as client responded in time */
+ xfsm_manager_cancel_client_save_timeout (manager, client);
+
+ if (xfsm_client_get_state (client) == XFSM_CLIENT_SAVINGLOCAL)
+ {
+ /* client completed local SaveYourself */
+ xfsm_client_set_state (client, XFSM_CLIENT_IDLE);
+ SmsSaveComplete (xfsm_client_get_sms_connection (client));
+ }
+ else if (manager->state != XFSM_MANAGER_CHECKPOINT && manager->state != XFSM_MANAGER_SHUTDOWN)
+ {
+ xfsm_verbose ("Client Id = %s, send SAVE YOURSELF DONE, but manager is not in CheckPoint/Shutdown mode.\n"
+ " Client will be nuked now.\n\n",
+ xfsm_client_get_id (client));
+ xfsm_manager_close_connection (manager, client, TRUE);
+ }
+ else
+ {
+ xfsm_client_set_state (client, XFSM_CLIENT_SAVEDONE);
+ xfsm_manager_complete_saveyourself (manager);
+ }
+}
+
+
+void
+xfsm_manager_close_connection (XfsmManager *manager,
+ XfsmClient *client,
+ gboolean cleanup)
+{
+ IceConn ice_conn;
+ GList *lp;
+
+ xfsm_client_set_state (client, XFSM_CLIENT_DISCONNECTED);
+ xfsm_manager_cancel_client_save_timeout (manager, client);
+
+ if (cleanup)
+ {
+ SmsConn sms_conn = xfsm_client_get_sms_connection (client);
+ ice_conn = SmsGetIceConnection (sms_conn);
+ SmsCleanUp (sms_conn);
+ IceSetShutdownNegotiation (ice_conn, False);
+ IceCloseConnection (ice_conn);
+ }
+
+ if (manager->state == XFSM_MANAGER_SHUTDOWNPHASE2)
+ {
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
+ {
+ XfsmClient *cl = lp->data;
+ if (xfsm_client_get_state (cl) != XFSM_CLIENT_DISCONNECTED)
+ return;
+ }
+
+ /* all clients finished the DIE phase in time */
+ if (manager->die_timeout_id)
+ {
+ g_source_remove (manager->die_timeout_id);
+ manager->die_timeout_id = 0;
+ }
+ gtk_main_quit ();
+ }
+ else if (manager->state == XFSM_MANAGER_SHUTDOWN || manager->state == XFSM_MANAGER_CHECKPOINT)
+ {
+ xfsm_verbose ("Client Id = %s, closed connection in checkpoint state\n"
+ " Session manager will show NO MERCY\n\n",
+ xfsm_client_get_id (client));
+
+ /* stupid client disconnected in CheckPoint state, prepare to be nuked! */
+ g_queue_remove (manager->running_clients, client);
+ g_object_unref (client);
+ xfsm_manager_complete_saveyourself (manager);
+ }
+ else
+ {
+ XfsmProperties *properties = xfsm_client_steal_properties (client);
+
+ if (properties != NULL)
+ {
+ if (xfsm_properties_check (properties))
+ {
+ if (xfsm_manager_handle_failed_properties (manager, properties) == FALSE)
+ xfsm_properties_free (properties);
+ }
+ else
+ xfsm_properties_free (properties);
+ }
+
+ /* regardless of the restart style hint, the current instance of
+ * the client is gone, so remove it from the client list and free it. */
+ g_queue_remove (manager->running_clients, client);
+ g_object_unref (client);
+ }
+}
+
+
+void
+xfsm_manager_close_connection_by_ice_conn (XfsmManager *manager,
+ IceConn ice_conn)
+{
+ GList *lp;
+
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
+ {
+ XfsmClient *client = lp->data;
+ if (SmsGetIceConnection (xfsm_client_get_sms_connection (client)) == ice_conn)
+ {
+ xfsm_manager_close_connection (manager, client, FALSE);
+ break;
+ }
+ }
+
+ /* be sure to close the Ice connection in any case */
+ IceSetShutdownNegotiation (ice_conn, False);
+ IceCloseConnection (ice_conn);
+}
+
+
+gboolean
+xfsm_manager_terminate_client (XfsmManager *manager,
+ XfsmClient *client,
+ GError **error)
+{
+ if (manager->state != XFSM_MANAGER_IDLE
+ || xfsm_client_get_state (client) != XFSM_CLIENT_IDLE)
+ {
+ if (error)
+ {
+ g_set_error (error, XFSM_ERROR, XFSM_ERROR_BAD_STATE,
+ _("Can only terminate clients when in the idle state"));
+ }
+ return FALSE;
+ }
+
+ SmsDie (xfsm_client_get_sms_connection (client));
+
+ return TRUE;
+}
+
+
+void
+xfsm_manager_perform_shutdown (XfsmManager *manager)
+{
+ GList *lp;
+
+ xfsm_verbose ("entering");
+
+ /* send SmDie message to all clients */
+ xfsm_manager_set_state (manager, XFSM_MANAGER_SHUTDOWNPHASE2);
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
+ {
+ XfsmClient *client = lp->data;
+ SmsDie (xfsm_client_get_sms_connection (client));
+ }
+
+ /* check for SmRestartAnyway clients that have already quit and
+ * set a ShutdownCommand */
+ for (lp = g_queue_peek_nth_link (manager->restart_properties, 0);
+ lp;
+ lp = lp->next)
+ {
+ XfsmProperties *properties = lp->data;
+ gint restart_style_hint;
+ gchar **shutdown_command;
+
+ restart_style_hint = xfsm_properties_get_uchar (properties,
+ SmRestartStyleHint,
+ SmRestartIfRunning);
+ shutdown_command = xfsm_properties_get_strv (properties, SmShutdownCommand);
+
+ if (restart_style_hint == SmRestartAnyway && shutdown_command != NULL)
+ {
+ xfsm_verbose ("Client Id = %s, quit already, running shutdown command.\n\n",
+ properties->client_id);
+
+ g_spawn_sync (xfsm_properties_get_string (properties, SmCurrentDirectory),
+ shutdown_command,
+ xfsm_properties_get_strv (properties, SmEnvironment),
+ G_SPAWN_SEARCH_PATH,
+ NULL, NULL,
+ NULL, NULL,
+ NULL, NULL);
+ }
+ }
+
+ /* give all clients the chance to close the connection */
+ manager->die_timeout_id = g_timeout_add (DIE_TIMEOUT,
+ (GSourceFunc) gtk_main_quit,
+ NULL);
+}
+
+
+gboolean
+xfsm_manager_check_clients_saving (XfsmManager *manager)
+{
+ GList *lp;
+
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
+ {
+ XfsmClient *client = lp->data;
+ XfsmClientState state = xfsm_client_get_state (client);
+ switch (state)
+ {
+ case XFSM_CLIENT_SAVING:
+ case XFSM_CLIENT_WAITFORINTERACT:
+ case XFSM_CLIENT_INTERACTING:
+ return TRUE;
+ default:
+ break;
+ }
+ }
+
+ return FALSE;
+}
+
+
+gboolean
+xfsm_manager_maybe_enter_phase2 (XfsmManager *manager)
+{
+ gboolean entered_phase2 = FALSE;
+ GList *lp;
+
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
+ {
+ XfsmClient *client = lp->data;
+
+ if (xfsm_client_get_state (client) == XFSM_CLIENT_WAITFORPHASE2)
+ {
+ entered_phase2 = TRUE;
+ SmsSaveYourselfPhase2 (xfsm_client_get_sms_connection (client));
+ xfsm_client_set_state (client, XFSM_CLIENT_SAVING);
+ xfsm_manager_start_client_save_timeout (manager, client);
+
+ xfsm_verbose ("Client Id = %s enters SAVE YOURSELF PHASE2.\n\n",
+ xfsm_client_get_id (client));
+ }
+ }
+
+ return entered_phase2;
+}
+
+
+void
+xfsm_manager_complete_saveyourself (XfsmManager *manager)
+{
+ GList *lp;
+
+ /* Check if still clients in SAVING state or if we have to enter PHASE2
+ * now. In either case, SaveYourself cannot be completed in this run.
+ */
+ if (xfsm_manager_check_clients_saving (manager) || xfsm_manager_maybe_enter_phase2 (manager))
+ return;
+
+ xfsm_verbose ("Manager finished SAVE YOURSELF, session data will be stored now.\n\n");
+
+ /* all clients done, store session data */
+ if (manager->save_session)
+ xfsm_manager_store_session (manager);
+
+ if (manager->state == XFSM_MANAGER_CHECKPOINT)
+ {
+ /* reset all clients to idle state */
+ xfsm_manager_set_state (manager, XFSM_MANAGER_IDLE);
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
+ {
+ XfsmClient *client = lp->data;
+ xfsm_client_set_state (client, XFSM_CLIENT_IDLE);
+ SmsSaveComplete (xfsm_client_get_sms_connection (client));
+ }
+ }
+ else
+ {
+ /* shutdown the session */
+ xfsm_manager_perform_shutdown (manager);
+ }
+}
+
+
+static gboolean
+xfsm_manager_save_timeout (gpointer user_data)
+{
+ XfsmSaveTimeoutData *stdata = user_data;
+
+ xfsm_verbose ("Client id = %s, received SAVE TIMEOUT\n"
+ " Client will be disconnected now.\n\n",
+ xfsm_client_get_id (stdata->client));
+
+ /* returning FALSE below will free the data */
+ g_object_steal_data (G_OBJECT (stdata->client), "--save-timeout-id");
+
+ xfsm_manager_close_connection (stdata->manager, stdata->client, TRUE);
+
+ return FALSE;
+}
+
+
+static void
+xfsm_manager_start_client_save_timeout (XfsmManager *manager,
+ XfsmClient *client)
+{
+ XfsmSaveTimeoutData *sdata = g_new(XfsmSaveTimeoutData, 1);
+
+ sdata->manager = manager;
+ sdata->client = client;
+ /* |sdata| will get freed when the source gets removed */
+ sdata->timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT, SAVE_TIMEOUT,
+ xfsm_manager_save_timeout,
+ sdata, (GDestroyNotify) g_free);
+ /* ... or, if the object gets destroyed first, the source will get
+ * removed and will free |sdata| for us. also, if there's a pending
+ * timer, this call will clear it. */
+ g_object_set_data_full (G_OBJECT (client), "--save-timeout-id",
+ GUINT_TO_POINTER (sdata->timeout_id),
+ (GDestroyNotify) g_source_remove);
+}
+
+
+static void
+xfsm_manager_cancel_client_save_timeout (XfsmManager *manager,
+ XfsmClient *client)
+{
+ /* clearing out the data will call g_source_remove(), which will free it */
+ g_object_set_data (G_OBJECT (client), "--save-timeout-id", NULL);
+}
+
+
+void
+xfsm_manager_store_session (XfsmManager *manager)
+{
+ WnckWorkspace *workspace;
+ GdkDisplay *display;
+ WnckScreen *screen;
+ XfceRc *rc;
+ GList *lp;
+ gchar prefix[64];
+ gchar *backup;
+ gchar *group;
+ gint count = 0;
+ gint n, m;
+
+ /* open file for writing, creates it if it doesn't exist */
+ rc = xfce_rc_simple_open (manager->session_file, FALSE);
+ if (G_UNLIKELY (rc == NULL))
+ {
+ fprintf (stderr,
+ "xfce4-session: Unable to open session file %s for "
+ "writing. Session data will not be stored. Please check "
+ "your installation.\n",
+ manager->session_file);
+ return;
+ }
+
+ /* backup the old session file first */
+ if (g_file_test (manager->session_file, G_FILE_TEST_IS_REGULAR))
+ {
+ backup = g_strconcat (manager->session_file, ".bak", NULL);
+ unlink (backup);
+ if (link (manager->session_file, backup))
+ g_warning ("Failed to create session file backup");
+ g_free (backup);
+ }
+
+ if (manager->state == XFSM_MANAGER_CHECKPOINT && manager->checkpoint_session_name != NULL)
+ group = g_strconcat ("Session: ", manager->checkpoint_session_name, NULL);
+ else
+ group = g_strconcat ("Session: ", manager->session_name, NULL);
+ xfce_rc_delete_group (rc, group, TRUE);
+ xfce_rc_set_group (rc, group);
+ g_free (group);
+
+ for (lp = g_queue_peek_nth_link (manager->restart_properties, 0);
+ lp;
+ lp = lp->next)
+ {
+ XfsmProperties *properties = lp->data;
+ g_snprintf (prefix, 64, "Client%d_", count);
+ xfsm_properties_store (properties, rc, prefix);
+ ++count;
+ }
+
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
+ {
+ XfsmClient *client = lp->data;
+ XfsmProperties *properties = xfsm_client_get_properties (client);
+ gint restart_style_hint;
+
+ if (properties == NULL || !xfsm_properties_check (xfsm_client_get_properties (client)))
+ continue;
+ restart_style_hint = xfsm_properties_get_uchar (properties,
+ SmRestartStyleHint,
+ SmRestartIfRunning);
+ if (restart_style_hint == SmRestartNever)
+ continue;
+
+ g_snprintf (prefix, 64, "Client%d_", count);
+ xfsm_properties_store (xfsm_client_get_properties (client), rc, prefix);
+ ++count;
+ }
+
+ xfce_rc_write_int_entry (rc, "Count", count);
+
+ /* store legacy applications state */
+ xfsm_legacy_store_session (rc);
+
+ /* store current workspace numbers */
+ display = gdk_display_get_default ();
+ for (n = 0; n < gdk_display_get_n_screens (display); ++n)
+ {
+ screen = wnck_screen_get (n);
+ wnck_screen_force_update (screen);
+
+ workspace = wnck_screen_get_active_workspace (screen);
+ m = wnck_workspace_get_number (workspace);
+
+ g_snprintf (prefix, 64, "Screen%d_ActiveWorkspace", n);
+ xfce_rc_write_int_entry (rc, prefix, m);
+ }
+
+ /* remember time */
+ xfce_rc_write_int_entry (rc, "LastAccess", time (NULL));
+
+ xfce_rc_close (rc);
+
+ g_free (manager->checkpoint_session_name);
+ manager->checkpoint_session_name = NULL;
+}
+
+
+XfsmShutdownType
+xfsm_manager_get_shutdown_type (XfsmManager *manager)
+{
+ return manager->shutdown_type;
+}
+
+
+XfsmManagerState
+xfsm_manager_get_state (XfsmManager *manager)
+{
+ return manager->state;
+}
+
+
+GQueue *
+xfsm_manager_get_queue (XfsmManager *manager,
+ XfsmManagerQueueType q_type)
+{
+ switch(q_type)
+ {
+ case XFSM_MANAGER_QUEUE_PENDING_PROPS:
+ return manager->pending_properties;
+ case XFSM_MANAGER_QUEUE_STARTING_PROPS:
+ return manager->starting_properties;
+ case XFSM_MANAGER_QUEUE_RESTART_PROPS:
+ return manager->restart_properties;
+ case XFSM_MANAGER_QUEUE_RUNNING_CLIENTS:
+ return manager->running_clients;
+ case XFSM_MANAGER_QUEUE_FAILSAFE_CLIENTS:
+ return manager->failsafe_clients;
+ default:
+ g_warning ("Requested invalid queue type %d", (gint)q_type);
+ return NULL;
+ }
+}
+
+
+gboolean
+xfsm_manager_get_use_failsafe_mode (XfsmManager *manager)
+{
+ return manager->failsafe_mode;
+}
+
+
+gboolean
+xfsm_manager_get_compat_startup (XfsmManager *manager,
+ XfsmManagerCompatType type)
+{
+ switch (type)
+ {
+ case XFSM_MANAGER_COMPAT_GNOME:
+ return manager->compat_gnome;
+ case XFSM_MANAGER_COMPAT_KDE:
+ return manager->compat_kde;
+ default:
+ g_warning ("Invalid compat startup type %d", type);
+ return FALSE;
+ }
+}
+
+
+gboolean
+xfsm_manager_get_start_at (XfsmManager *manager)
+{
+ return manager->start_at;
+}
+
+
+/*
+ * dbus server impl
+ */
+
+static DBusHandlerResult xfsm_manager_watch_dbus_disconnect (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data);
+
+static gboolean xfsm_manager_dbus_get_info (XfsmManager *manager,
+ gchar **OUT_name,
+ gchar **OUT_version,
+ gchar **OUT_vendor,
+ GError **error);
+static gboolean xfsm_manager_dbus_list_clients (XfsmManager *manager,
+ GPtrArray **OUT_clients,
+ GError **error);
+static gboolean xfsm_manager_dbus_get_state (XfsmManager *manager,
+ guint *OUT_state,
+ GError **error);
+static gboolean xfsm_manager_dbus_checkpoint (XfsmManager *manager,
+ const gchar *session_name,
+ GError **error);
+static gboolean xfsm_manager_dbus_logout (XfsmManager *manager,
+ gboolean show_dialog,
+ gboolean allow_save,
+ GError **error);
+static gboolean xfsm_manager_dbus_shutdown (XfsmManager *manager,
+ gboolean allow_save,
+ GError **error);
+static gboolean xfsm_manager_dbus_can_shutdown (XfsmManager *manager,
+ gboolean *can_shutdown,
+ GError **error);
+static gboolean xfsm_manager_dbus_restart (XfsmManager *manager,
+ gboolean allow_save,
+ GError **error);
+static gboolean xfsm_manager_dbus_can_restart (XfsmManager *manager,
+ gboolean *can_restart,
+ GError **error);
+static gboolean xfsm_manager_dbus_suspend (XfsmManager *manager,
+ GError **error);
+static gboolean xfsm_manager_dbus_can_suspend (XfsmManager *manager,
+ gboolean *can_suspend,
+ GError **error);
+static gboolean xfsm_manager_dbus_hibernate (XfsmManager *manager,
+ GError **error);
+static gboolean xfsm_manager_dbus_can_hibernate (XfsmManager *manager,
+ gboolean *can_hibernate,
+ GError **error);
+
+
+/* eader needs the above fwd decls */
+#include <xfce4-session/xfsm-manager-dbus.h>
+
+
+static void
+xfsm_manager_dbus_class_init (XfsmManagerClass *klass)
+{
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
+ &dbus_glib_xfsm_manager_object_info);
+}
+
+
+static void
+xfsm_manager_dbus_init (XfsmManager *manager)
+{
+ GError *error = NULL;
+ DBusConnection *connection;
+
+ manager->session_bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+
+ if (G_UNLIKELY (!manager->session_bus))
+ {
+ g_critical ("Unable to contact D-Bus session bus: %s", error ? error->message : "Unknown error");
+ if (error)
+ g_error_free (error);
+ return;
+ }
+
+ connection = dbus_g_connection_get_connection (manager->session_bus);
+ dbus_connection_set_exit_on_disconnect (connection, FALSE);
+
+ dbus_g_connection_register_g_object (manager->session_bus,
+ "/org/xfce/SessionManager",
+ G_OBJECT (manager));
+
+ dbus_connection_add_filter (dbus_g_connection_get_connection (manager->session_bus),
+ xfsm_manager_watch_dbus_disconnect,
+ manager, NULL);
+}
+
+
+static void
+xfsm_manager_dbus_cleanup (XfsmManager *manager)
+{
+ if (G_LIKELY (manager->session_bus))
+ {
+ dbus_connection_remove_filter (dbus_g_connection_get_connection (manager->session_bus),
+ xfsm_manager_watch_dbus_disconnect,
+ manager);
+ dbus_g_connection_unref (manager->session_bus);
+ manager->session_bus = NULL;
+ }
+}
+
+
+static DBusHandlerResult
+xfsm_manager_watch_dbus_disconnect (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data)
+{
+ if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected"))
+ {
+ g_message ("Got disconnected from D-Bus. Unless this happened during "
+ "session shutdown, this is probably a bad thing.");
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+
+static gboolean
+xfsm_manager_dbus_get_info (XfsmManager *manager,
+ gchar **OUT_name,
+ gchar **OUT_version,
+ gchar **OUT_vendor,
+ GError **error)
+{
+ *OUT_name = g_strdup (PACKAGE);
+ *OUT_version = g_strdup (VERSION);
+ *OUT_vendor = g_strdup ("Xfce");
+
+ return TRUE;
+}
+
+
+static gboolean
+xfsm_manager_dbus_list_clients (XfsmManager *manager,
+ GPtrArray **OUT_clients,
+ GError **error)
+{
+ GList *lp;
+
+ *OUT_clients = g_ptr_array_sized_new (g_queue_get_length (manager->running_clients));
+
+ for (lp = g_queue_peek_nth_link (manager->running_clients, 0);
+ lp;
+ lp = lp->next)
+ {
+ XfsmClient *client = XFSM_CLIENT (lp->data);
+ gchar *object_path = g_strdup (xfsm_client_get_object_path (client));
+ g_ptr_array_add (*OUT_clients, object_path);
+ }
+
+ return TRUE;
+}
+
+
+static gboolean
+xfsm_manager_dbus_get_state (XfsmManager *manager,
+ guint *OUT_state,
+ GError **error)
+{
+ *OUT_state = manager->state;
+ return TRUE;
+}
+
+
+static gboolean
+xfsm_manager_dbus_checkpoint_idled (gpointer data)
+{
+ XfsmManager *manager = XFSM_MANAGER (data);
+
+ xfsm_manager_save_yourself_global (manager, SmSaveBoth, FALSE,
+ SmInteractStyleNone, FALSE,
+ XFSM_SHUTDOWN_ASK, TRUE);
+
+ return FALSE;
+}
+
+
+static gboolean
+xfsm_manager_dbus_checkpoint (XfsmManager *manager,
+ const gchar *session_name,
+ GError **error)
+{
+ if (manager->state != XFSM_MANAGER_IDLE)
+ {
+ g_set_error (error, XFSM_ERROR, XFSM_ERROR_BAD_STATE,
+ _("Session manager must be in idle state when requesting a checkpoint"));
+ return FALSE;
+ }
+
+ g_free (manager->checkpoint_session_name);
+ if (session_name[0] != '\0')
+ manager->checkpoint_session_name = g_strdup (session_name);
+ else
+ manager->checkpoint_session_name = NULL;
+
+ /* idle so the dbus call returns in the client */
+ g_idle_add (xfsm_manager_dbus_checkpoint_idled, manager);
+
+ return TRUE;
+}
+
+
+static gboolean
+xfsm_manager_dbus_shutdown_idled (gpointer data)
+{
+ ShutdownIdleData *idata = data;
+
+ xfsm_manager_save_yourself_global (idata->manager, SmSaveBoth, TRUE,
+ SmInteractStyleAny, FALSE,
+ idata->type, idata->allow_save);
+
+ return FALSE;
+}
+
+
+static gboolean
+xfsm_manager_save_yourself_dbus (XfsmManager *manager,
+ XfsmShutdownType type,
+ gboolean allow_save,
+ GError **error)
+{
+ ShutdownIdleData *idata;
+
+ if (manager->state != XFSM_MANAGER_IDLE)
+ {
+ g_set_error (error, XFSM_ERROR, XFSM_ERROR_BAD_STATE,
+ _("Session manager must be in idle state when requesting a shutdown"));
+ return FALSE;
+ }
+
+ idata = g_new (ShutdownIdleData, 1);
+ idata->manager = manager;
+ idata->type = type;
+ idata->allow_save = allow_save;
+ g_idle_add_full (G_PRIORITY_DEFAULT, xfsm_manager_dbus_shutdown_idled,
+ idata, (GDestroyNotify) g_free);
+
+ return TRUE;
+}
+
+
+static gboolean
+xfsm_manager_dbus_logout (XfsmManager *manager,
+ gboolean show_dialog,
+ gboolean allow_save,
+ GError **error)
+{
+ XfsmShutdownType type;
+
+ g_return_val_if_fail (XFSM_IS_MANAGER (manager), FALSE);
+
+ type = show_dialog ? XFSM_SHUTDOWN_ASK : XFSM_SHUTDOWN_LOGOUT;
+ return xfsm_manager_save_yourself_dbus (manager, type,
+ allow_save, error);
+}
+
+
+static gboolean
+xfsm_manager_dbus_shutdown (XfsmManager *manager,
+ gboolean allow_save,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_MANAGER (manager), FALSE);
+ return xfsm_manager_save_yourself_dbus (manager, XFSM_SHUTDOWN_SHUTDOWN,
+ allow_save, error);
+}
+
+
+static gboolean
+xfsm_manager_dbus_can_shutdown (XfsmManager *manager,
+ gboolean *can_shutdown,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_MANAGER (manager), FALSE);
+ return xfsm_shutdown_can_shutdown (manager->shutdown_helper,
+ can_shutdown, error);
+}
+
+
+static gboolean
+xfsm_manager_dbus_restart (XfsmManager *manager,
+ gboolean allow_save,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_MANAGER (manager), FALSE);
+ return xfsm_manager_save_yourself_dbus (manager, XFSM_SHUTDOWN_RESTART,
+ allow_save, error);
+}
+
+
+static gboolean
+xfsm_manager_dbus_can_restart (XfsmManager *manager,
+ gboolean *can_restart,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_MANAGER (manager), FALSE);
+ return xfsm_shutdown_can_restart (manager->shutdown_helper,
+ can_restart, error);
+}
+
+
+static gboolean
+xfsm_manager_dbus_suspend (XfsmManager *manager,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_MANAGER (manager), FALSE);
+ return xfsm_shutdown_try_suspend (manager->shutdown_helper, error);
+}
+
+
+static gboolean
+xfsm_manager_dbus_can_suspend (XfsmManager *manager,
+ gboolean *can_suspend,
+ GError **error)
+{
+ gboolean retval;
+ gboolean auth_suspend;
+
+ g_return_val_if_fail (XFSM_IS_MANAGER (manager), FALSE);
+ retval = xfsm_shutdown_can_suspend (manager->shutdown_helper,
+ can_suspend, &auth_suspend, error);
+
+ if (!auth_suspend)
+ *can_suspend = FALSE;
+
+ return retval;
+}
+
+static gboolean
+xfsm_manager_dbus_hibernate (XfsmManager *manager,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_MANAGER (manager), FALSE);
+ return xfsm_shutdown_try_hibernate (manager->shutdown_helper, error);
+}
+
+
+static gboolean
+xfsm_manager_dbus_can_hibernate (XfsmManager *manager,
+ gboolean *can_hibernate,
+ GError **error)
+{
+ gboolean retval;
+ gboolean auth_hibernate;
+
+ g_return_val_if_fail (XFSM_IS_MANAGER (manager), FALSE);
+ retval = xfsm_shutdown_can_hibernate (manager->shutdown_helper,
+ can_hibernate, &auth_hibernate, error);
+
+ if (!auth_hibernate)
+ *can_hibernate = FALSE;
+
+ return retval;
+}
diff --git a/xfce4-session/xfsm-manager.h b/xfce4-session/xfsm-manager.h
new file mode 100644
index 0000000..521bacc
--- /dev/null
+++ b/xfce4-session/xfsm-manager.h
@@ -0,0 +1,161 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2003-2006 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2008 Brian Tarricone <bjt23@cornell.edu>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifndef __XFSM_MANAGER_H__
+#define __XFSM_MANAGER_H__
+
+#include <glib-object.h>
+
+#include <xfconf/xfconf.h>
+#include <libxfce4util/libxfce4util.h>
+
+#include <xfce4-session/xfsm-client.h>
+#include <xfce4-session/xfsm-global.h>
+#include <xfce4-session/xfsm-shutdown.h>
+
+G_BEGIN_DECLS
+
+#define XFSM_TYPE_MANAGER (xfsm_manager_get_type())
+#define XFSM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XFSM_TYPE_MANAGER, XfsmManager))
+#define XFSM_IS_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XFSM_TYPE_MANAGER))
+
+#define DIE_TIMEOUT ( 7 * 1000)
+#define SAVE_TIMEOUT ( 60 * 1000)
+#define STARTUP_TIMEOUT ( 8 * 1000)
+#define RESTART_RESET_TIMEOUT (5 * 60 * 1000)
+
+typedef enum
+{
+ XFSM_MANAGER_STARTUP,
+ XFSM_MANAGER_IDLE,
+ XFSM_MANAGER_CHECKPOINT,
+ XFSM_MANAGER_SHUTDOWN,
+ XFSM_MANAGER_SHUTDOWNPHASE2,
+} XfsmManagerState;
+
+typedef enum
+{
+ XFSM_MANAGER_QUEUE_PENDING_PROPS = 0,
+ XFSM_MANAGER_QUEUE_STARTING_PROPS,
+ XFSM_MANAGER_QUEUE_RESTART_PROPS,
+ XFSM_MANAGER_QUEUE_RUNNING_CLIENTS,
+ XFSM_MANAGER_QUEUE_FAILSAFE_CLIENTS,
+} XfsmManagerQueueType;
+
+typedef enum
+{
+ XFSM_MANAGER_COMPAT_GNOME = 0,
+ XFSM_MANAGER_COMPAT_KDE,
+} XfsmManagerCompatType;
+
+typedef struct _XfsmManager XfsmManager;
+
+GType xfsm_manager_get_type (void) G_GNUC_CONST;
+
+XfsmManager *xfsm_manager_new (void);
+
+void xfsm_manager_load (XfsmManager *manager,
+ XfconfChannel *channel);
+
+gboolean xfsm_manager_restart (XfsmManager *manager);
+
+/* call when startup is finished */
+void xfsm_manager_signal_startup_done (XfsmManager *manager);
+
+/* call for each client that fails */
+gboolean xfsm_manager_handle_failed_properties (XfsmManager *manager,
+ XfsmProperties *properties);
+
+XfsmClient* xfsm_manager_new_client (XfsmManager *manager,
+ SmsConn sms_conn,
+ gchar **error);
+
+gboolean xfsm_manager_register_client (XfsmManager *manager,
+ XfsmClient *client,
+ const gchar *previous_id);
+
+void xfsm_manager_start_interact (XfsmManager *manager,
+ XfsmClient *client);
+
+void xfsm_manager_interact (XfsmManager *manager,
+ XfsmClient *client,
+ gint dialog_type);
+
+void xfsm_manager_interact_done (XfsmManager *manager,
+ XfsmClient *client,
+ gboolean cancel_shutdown);
+
+void xfsm_manager_save_yourself (XfsmManager *manager,
+ XfsmClient *client,
+ gint save_type,
+ gboolean shutdown,
+ gint interact_style,
+ gboolean fast,
+ gboolean global);
+
+void xfsm_manager_save_yourself_phase2 (XfsmManager *manager,
+ XfsmClient *client);
+
+void xfsm_manager_save_yourself_done (XfsmManager *manager,
+ XfsmClient *client,
+ gboolean success);
+
+void xfsm_manager_close_connection (XfsmManager *manager,
+ XfsmClient *client,
+ gboolean cleanup);
+
+void xfsm_manager_close_connection_by_ice_conn (XfsmManager *manager,
+ IceConn ice_conn);
+
+gboolean xfsm_manager_check_clients_saving (XfsmManager *manager);
+
+gboolean xfsm_manager_maybe_enter_phase2 (XfsmManager *manager);
+
+gboolean xfsm_manager_terminate_client (XfsmManager *manager,
+ XfsmClient *client,
+ GError **error);
+
+void xfsm_manager_perform_shutdown (XfsmManager *manager);
+
+gboolean xfsm_manager_run_command (XfsmManager *manager,
+ const XfsmProperties *properties,
+ const gchar *command);
+
+void xfsm_manager_store_session (XfsmManager *manager);
+
+void xfsm_manager_complete_saveyourself (XfsmManager *manager);
+
+XfsmShutdownType xfsm_manager_get_shutdown_type (XfsmManager *manager);
+
+XfsmManagerState xfsm_manager_get_state (XfsmManager *manager);
+
+GQueue *xfsm_manager_get_queue (XfsmManager *manager,
+ XfsmManagerQueueType q_type);
+
+gboolean xfsm_manager_get_use_failsafe_mode (XfsmManager *manager);
+
+gboolean xfsm_manager_get_compat_startup (XfsmManager *manager,
+ XfsmManagerCompatType type);
+
+gboolean xfsm_manager_get_start_at (XfsmManager *manager);
+
+#endif /* !__XFSM_MANAGER_H__ */
diff --git a/xfce4-session/xfsm-marshal.c b/xfce4-session/xfsm-marshal.c
new file mode 100644
index 0000000..bcce878
--- /dev/null
+++ b/xfce4-session/xfsm-marshal.c
@@ -0,0 +1,126 @@
+#include <xfce4-session/xfsm-marshal.h>
+
+#include <glib-object.h>
+
+
+#ifdef G_ENABLE_DEBUG
+#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
+#define g_marshal_value_peek_char(v) g_value_get_schar (v)
+#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
+#define g_marshal_value_peek_int(v) g_value_get_int (v)
+#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
+#define g_marshal_value_peek_long(v) g_value_get_long (v)
+#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
+#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
+#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
+#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
+#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
+#define g_marshal_value_peek_float(v) g_value_get_float (v)
+#define g_marshal_value_peek_double(v) g_value_get_double (v)
+#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
+#define g_marshal_value_peek_param(v) g_value_get_param (v)
+#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
+#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
+#define g_marshal_value_peek_object(v) g_value_get_object (v)
+#define g_marshal_value_peek_variant(v) g_value_get_variant (v)
+#else /* !G_ENABLE_DEBUG */
+/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
+ * Do not access GValues directly in your code. Instead, use the
+ * g_value_get_*() functions
+ */
+#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
+#define g_marshal_value_peek_char(v) (v)->data[0].v_int
+#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
+#define g_marshal_value_peek_int(v) (v)->data[0].v_int
+#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
+#define g_marshal_value_peek_long(v) (v)->data[0].v_long
+#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
+#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
+#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
+#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
+#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
+#define g_marshal_value_peek_float(v) (v)->data[0].v_float
+#define g_marshal_value_peek_double(v) (v)->data[0].v_double
+#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer
+#endif /* !G_ENABLE_DEBUG */
+
+
+/* VOID:UINT,UINT (xfsm-marshal.list:1) */
+void
+xfsm_marshal_VOID__UINT_UINT (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+{
+ typedef void (*GMarshalFunc_VOID__UINT_UINT) (gpointer data1,
+ guint arg_1,
+ guint arg_2,
+ gpointer data2);
+ register GMarshalFunc_VOID__UINT_UINT callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+
+ g_return_if_fail (n_param_values == 3);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_VOID__UINT_UINT) (marshal_data ? marshal_data : cc->callback);
+
+ callback (data1,
+ g_marshal_value_peek_uint (param_values + 1),
+ g_marshal_value_peek_uint (param_values + 2),
+ data2);
+}
+
+/* VOID:STRING,BOXED (xfsm-marshal.list:2) */
+void
+xfsm_marshal_VOID__STRING_BOXED (GClosure *closure,
+ GValue *return_value G_GNUC_UNUSED,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint G_GNUC_UNUSED,
+ gpointer marshal_data)
+{
+ typedef void (*GMarshalFunc_VOID__STRING_BOXED) (gpointer data1,
+ gpointer arg_1,
+ gpointer arg_2,
+ gpointer data2);
+ register GMarshalFunc_VOID__STRING_BOXED callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+
+ g_return_if_fail (n_param_values == 3);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_VOID__STRING_BOXED) (marshal_data ? marshal_data : cc->callback);
+
+ callback (data1,
+ g_marshal_value_peek_string (param_values + 1),
+ g_marshal_value_peek_boxed (param_values + 2),
+ data2);
+}
+
diff --git a/xfce4-session/xfsm-marshal.h b/xfce4-session/xfsm-marshal.h
new file mode 100644
index 0000000..636816a
--- /dev/null
+++ b/xfce4-session/xfsm-marshal.h
@@ -0,0 +1,28 @@
+
+#ifndef __xfsm_marshal_MARSHAL_H__
+#define __xfsm_marshal_MARSHAL_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/* VOID:UINT,UINT (xfsm-marshal.list:1) */
+G_GNUC_INTERNAL void xfsm_marshal_VOID__UINT_UINT (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+
+/* VOID:STRING,BOXED (xfsm-marshal.list:2) */
+G_GNUC_INTERNAL void xfsm_marshal_VOID__STRING_BOXED (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+
+G_END_DECLS
+
+#endif /* __xfsm_marshal_MARSHAL_H__ */
+
diff --git a/xfce4-session/xfsm-marshal.list b/xfce4-session/xfsm-marshal.list
new file mode 100644
index 0000000..15ef959
--- /dev/null
+++ b/xfce4-session/xfsm-marshal.list
@@ -0,0 +1,2 @@
+VOID:UINT,UINT
+VOID:STRING,BOXED
diff --git a/xfce4-session/xfsm-properties.c b/xfce4-session/xfsm-properties.c
new file mode 100644
index 0000000..e9c943c
--- /dev/null
+++ b/xfce4-session/xfsm-properties.c
@@ -0,0 +1,726 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2008 Brian Tarricone <bjt23@cornell.edu>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include <libxfsm/xfsm-util.h>
+
+#include <xfce4-session/xfsm-global.h>
+#include <xfce4-session/xfsm-properties.h>
+
+
+/* local prototypes */
+static SmProp* strv_to_property (const gchar *name,
+ gchar **argv) G_GNUC_PURE;
+static SmProp* str_to_property (const gchar *name,
+ const gchar *value) G_GNUC_PURE;
+static SmProp* int_to_property (const gchar *name,
+ gint value) G_GNUC_PURE;
+
+/* these three structs hold lists of properties that we save in
+ * and load from the session file */
+static const struct
+{
+ const gchar *name;
+ const gchar *xsmp_name;
+} strv_properties[] = {
+ { "CloneCommand", SmCloneCommand },
+ { "DiscardCommand", SmDiscardCommand },
+ { "Environment", SmEnvironment },
+ { "ResignCommand", SmResignCommand },
+ { "RestartCommand", SmRestartCommand },
+ { "ShutdownCommand", SmShutdownCommand },
+ { NULL, NULL }
+};
+
+static const struct
+{
+ const gchar *name;
+ const gchar *xsmp_name;
+} str_properties[] = {
+ { "CurrentDirectory", SmCurrentDirectory },
+ { "DesktopFile", GsmDesktopFile },
+ { "Program", SmProgram },
+ { "UserId", SmUserID },
+ { NULL, NULL }
+};
+
+static const struct
+{
+ const gchar *name;
+ const gchar *xsmp_name;
+ const guchar default_value;
+} uchar_properties[] = {
+ { "Priority", GsmPriority, 50 },
+ { "RestartStyleHint", SmRestartStyleHint, SmRestartIfRunning },
+ { NULL, NULL, 0 }
+};
+
+
+#ifndef HAVE_STRDUP
+static char*
+strdup (const char *s)
+{
+ char *t;
+
+ t = (char *) malloc (strlen (s) + 1);
+ if (t != NULL)
+ strcpy (t, s);
+
+ return t;
+}
+#endif
+
+
+static gchar*
+compose (gchar *buffer,
+ gsize length,
+ const gchar *prefix,
+ const gchar *suffix)
+{
+ g_strlcpy (buffer, prefix, length);
+ g_strlcat (buffer, suffix, length);
+ return buffer;
+}
+
+
+static SmProp*
+strv_to_property (const gchar *name,
+ gchar **argv)
+{
+ SmProp *prop;
+ gint argc;
+
+ prop = (SmProp *) malloc (sizeof (*prop));
+ prop->name = strdup (name);
+ prop->type = strdup (SmLISTofARRAY8);
+
+ for (argc = 0; argv[argc] != NULL; ++argc)
+ ;
+
+ prop->num_vals = argc;
+ prop->vals = (SmPropValue *) malloc (argc * sizeof (SmPropValue));
+
+ while (argc-- > 0)
+ {
+ prop->vals[argc].length = strlen (argv[argc]) + 1;
+ prop->vals[argc].value = strdup (argv[argc]);
+ }
+
+ return prop;
+}
+
+
+static SmProp*
+str_to_property (const gchar *name,
+ const gchar *value)
+{
+ SmProp *prop;
+
+ prop = (SmProp *) malloc (sizeof (*prop));
+ prop->name = strdup (name);
+ prop->type = strdup (SmARRAY8);
+ prop->num_vals = 1;
+ prop->vals = (SmPropValue *) malloc (sizeof (SmPropValue));
+ prop->vals[0].length = strlen (value) + 1;
+ prop->vals[0].value = strdup (value);
+
+ return prop;
+}
+
+
+static SmProp*
+int_to_property (const gchar *name,
+ gint value)
+{
+ SmProp *prop;
+ gint8 *p;
+
+ p = (gint8 *) malloc (1);
+ p[0] = (gint8) value;
+
+ prop = (SmProp *) malloc (sizeof (*prop));
+ prop->name = strdup (name);
+ prop->type = strdup (SmCARD8);
+ prop->num_vals = 1;
+ prop->vals = (SmPropValue *) malloc (sizeof (SmPropValue));
+ prop->vals[0].length = 1;
+ prop->vals[0].value = p;
+
+ return prop;
+}
+
+
+XfsmProperties*
+xfsm_properties_new (const gchar *client_id,
+ const gchar *hostname)
+{
+ XfsmProperties *properties;
+
+ properties = g_slice_new0 (XfsmProperties);
+ properties->client_id = g_strdup (client_id);
+ properties->hostname = g_strdup (hostname);
+ properties->pid = -1;
+
+ properties->sm_properties = g_tree_new_full ((GCompareDataFunc) strcmp,
+ NULL,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) xfsm_g_value_free);
+
+ return properties;
+}
+
+
+static gboolean
+xfsm_properties_extract_foreach (gpointer key,
+ gpointer value,
+ gpointer data)
+{
+ const gchar *prop_name = key;
+ const GValue *prop_value = value;
+ SmProp ***pp = data;
+
+ if (G_VALUE_HOLDS (prop_value, G_TYPE_STRV))
+ **pp++ = strv_to_property (prop_name, g_value_get_boxed (prop_value));
+ else if (G_VALUE_HOLDS_STRING (prop_value))
+ **pp++ = str_to_property (prop_name, g_value_get_string (prop_value));
+ else if (G_VALUE_HOLDS_UCHAR (prop_value))
+ **pp++ = int_to_property (prop_name, g_value_get_uchar (prop_value));
+ else {
+ g_warning ("Unhandled property \"%s\" with type \"%s\"", prop_name,
+ g_type_name (G_VALUE_TYPE (prop_value)));
+ }
+
+ return FALSE;
+}
+
+void
+xfsm_properties_extract (XfsmProperties *properties,
+ gint *num_props,
+ SmProp ***props)
+{
+ SmProp **pp;
+
+ g_return_if_fail (num_props != NULL);
+ g_return_if_fail (props != NULL);
+
+ *props = pp = (SmProp **) malloc (sizeof (SmProp *) * g_tree_nnodes (properties->sm_properties));
+
+ g_tree_foreach (properties->sm_properties,
+ xfsm_properties_extract_foreach,
+ &pp);
+
+ *num_props = pp - *props;
+}
+
+
+XfsmProperties *
+xfsm_properties_load (XfceRc *rc,
+ const gchar *prefix)
+{
+#define ENTRY(name) (compose(buffer, 256, prefix, (name)))
+
+ XfsmProperties *properties;
+ const gchar *client_id;
+ const gchar *hostname;
+ GValue *value;
+ const gchar *value_str;
+ gchar **value_strv;
+ gint value_int;
+ gchar buffer[256];
+ gint i;
+
+ client_id = xfce_rc_read_entry (rc, ENTRY ("ClientId"), NULL);
+ if (client_id == NULL)
+ {
+ g_warning ("Session data broken, stored client is missing a client id. "
+ "Skipping client.");
+ return NULL;
+ }
+
+ hostname = xfce_rc_read_entry (rc, ENTRY ("Hostname"), NULL);
+ if (hostname == NULL)
+ {
+ g_warning ("Session data broken, stored client is missing a hostname. "
+ "Skipping client.");
+ return NULL;
+ }
+
+ xfsm_verbose ("Loading properties for client %s\n", client_id);
+
+ properties = xfsm_properties_new (client_id, hostname);
+
+ for (i = 0; strv_properties[i].name; ++i)
+ {
+ value_strv = xfce_rc_read_list_entry (rc, ENTRY (strv_properties[i].name), NULL);
+ if (value_strv)
+ {
+ xfsm_verbose ("-> Set strv (%s)\n", strv_properties[i].xsmp_name);
+ /* don't use _set_strv() to avoid a realloc of the whole strv */
+ value = xfsm_g_value_new (G_TYPE_STRV);
+ g_value_take_boxed (value, value_strv);
+ g_tree_replace (properties->sm_properties,
+ g_strdup (strv_properties[i].xsmp_name),
+ value);
+ }
+ }
+
+ for (i = 0; str_properties[i].name; ++i)
+ {
+ value_str = xfce_rc_read_entry (rc, ENTRY (str_properties[i].name), NULL);
+ if (value_str)
+ xfsm_properties_set_string (properties, str_properties[i].xsmp_name, value_str);
+ }
+
+ for (i = 0; uchar_properties[i].name; ++i)
+ {
+ value_int = xfce_rc_read_int_entry (rc, ENTRY (uchar_properties[i].name),
+ uchar_properties[i].default_value);
+ xfsm_properties_set_uchar (properties, uchar_properties[i].xsmp_name, value_int);
+ }
+
+ if (!xfsm_properties_check (properties))
+ {
+ xfsm_properties_free (properties);
+ return NULL;
+ }
+
+ return properties;
+
+#undef ENTRY
+}
+
+
+void
+xfsm_properties_store (XfsmProperties *properties,
+ XfceRc *rc,
+ const gchar *prefix)
+{
+#define ENTRY(name) (compose(buffer, 256, prefix, (name)))
+
+ GValue *value;
+ gint i;
+ gchar buffer[256];
+
+ xfce_rc_write_entry (rc, ENTRY ("ClientId"), properties->client_id);
+ xfce_rc_write_entry (rc, ENTRY ("Hostname"), properties->hostname);
+
+ for (i = 0; strv_properties[i].name; ++i)
+ {
+ value = g_tree_lookup (properties->sm_properties, strv_properties[i].xsmp_name);
+ if (value)
+ {
+ xfce_rc_write_list_entry (rc, ENTRY (strv_properties[i].name),
+ g_value_get_boxed (value), NULL);
+ }
+ }
+
+ for (i = 0; str_properties[i].name; ++i)
+ {
+ value = g_tree_lookup (properties->sm_properties, str_properties[i].xsmp_name);
+ if (value)
+ {
+ xfce_rc_write_entry (rc, ENTRY (str_properties[i].name),
+ g_value_get_string (value));
+ }
+ }
+
+ for (i = 0; uchar_properties[i].name; ++i)
+ {
+ value = g_tree_lookup (properties->sm_properties, uchar_properties[i].xsmp_name);
+ if (value)
+ {
+ xfce_rc_write_int_entry (rc, ENTRY (uchar_properties[i].name),
+ g_value_get_uchar (value));
+ }
+ }
+
+#undef ENTRY
+}
+
+
+gint
+xfsm_properties_compare (const XfsmProperties *a,
+ const XfsmProperties *b)
+{
+ GValue *va, *vb;
+ gint ia = 50, ib = 50;
+
+ va = g_tree_lookup (a->sm_properties, GsmPriority);
+ if (va)
+ ia = g_value_get_uchar (va);
+
+ vb = g_tree_lookup (b->sm_properties, GsmPriority);
+ if (vb)
+ ib = g_value_get_uchar (vb);
+
+ return ia - ib;
+}
+
+
+gint
+xfsm_properties_compare_id (const XfsmProperties *properties,
+ const gchar *client_id)
+{
+ return strcmp (properties->client_id, client_id);
+}
+
+
+gboolean
+xfsm_properties_check (const XfsmProperties *properties)
+{
+ g_return_val_if_fail (properties != NULL, FALSE);
+
+ return properties->client_id != NULL
+ && properties->hostname != NULL
+ && g_tree_lookup (properties->sm_properties, SmProgram) != NULL
+ && g_tree_lookup (properties->sm_properties, SmRestartCommand) != NULL;
+}
+
+
+const gchar *
+xfsm_properties_get_string (XfsmProperties *properties,
+ const gchar *property_name)
+{
+ GValue *value;
+
+ g_return_val_if_fail (properties != NULL, NULL);
+ g_return_val_if_fail (property_name != NULL, NULL);
+
+ value = g_tree_lookup (properties->sm_properties, property_name);
+
+ if (G_LIKELY (value && G_VALUE_HOLDS_STRING (value)))
+ return g_value_get_string (value);
+
+ return NULL;
+}
+
+
+gchar **
+xfsm_properties_get_strv (XfsmProperties *properties,
+ const gchar *property_name)
+{
+ GValue *value;
+
+ g_return_val_if_fail (properties != NULL, NULL);
+ g_return_val_if_fail (property_name != NULL, NULL);
+
+ value = g_tree_lookup (properties->sm_properties, property_name);
+
+ if (G_LIKELY (value && G_VALUE_HOLDS (value, G_TYPE_STRV)))
+ return g_value_get_boxed (value);
+
+ return NULL;
+}
+
+
+guchar
+xfsm_properties_get_uchar (XfsmProperties *properties,
+ const gchar *property_name,
+ guchar default_value)
+{
+ GValue *value;
+
+ g_return_val_if_fail (properties != NULL, default_value);
+ g_return_val_if_fail (property_name != NULL, default_value);
+
+ value = g_tree_lookup (properties->sm_properties, property_name);
+
+ if (G_LIKELY (value && G_VALUE_HOLDS_UCHAR (value)))
+ return g_value_get_uchar (value);
+
+ return default_value;
+}
+
+
+const GValue *
+xfsm_properties_get (XfsmProperties *properties,
+ const gchar *property_name)
+{
+ g_return_val_if_fail (properties != NULL, NULL);
+ g_return_val_if_fail (property_name != NULL, NULL);
+
+ return g_tree_lookup (properties->sm_properties, property_name);
+}
+
+
+void
+xfsm_properties_set_string (XfsmProperties *properties,
+ const gchar *property_name,
+ const gchar *property_value)
+{
+ GValue *value;
+
+ g_return_if_fail (properties != NULL);
+ g_return_if_fail (property_name != NULL);
+ g_return_if_fail (property_value != NULL);
+
+ xfsm_verbose ("-> Set string (%s, %s)\n", property_name, property_value);
+
+ value = g_tree_lookup (properties->sm_properties, property_name);
+ if (value)
+ {
+ if (!G_VALUE_HOLDS_STRING (value))
+ {
+ g_value_unset (value);
+ g_value_init (value, G_TYPE_STRING);
+ }
+ g_value_set_string (value, property_value);
+ }
+ else
+ {
+ value = xfsm_g_value_new (G_TYPE_STRING);
+ g_value_set_string (value, property_value);
+ g_tree_replace (properties->sm_properties,
+ g_strdup (property_name),
+ value);
+ }
+}
+
+
+void
+xfsm_properties_set_strv (XfsmProperties *properties,
+ const gchar *property_name,
+ gchar **property_value)
+{
+ GValue *value;
+
+ g_return_if_fail (properties != NULL);
+ g_return_if_fail (property_name != NULL);
+ g_return_if_fail (property_value != NULL);
+
+ xfsm_verbose ("-> Set strv (%s)\n", property_name);
+
+ value = g_tree_lookup (properties->sm_properties, property_name);
+ if (value)
+ {
+ if (!G_VALUE_HOLDS (value, G_TYPE_STRV))
+ {
+ g_value_unset (value);
+ g_value_init (value, G_TYPE_STRV);
+ }
+ g_value_set_boxed (value, property_value);
+ }
+ else
+ {
+ value = xfsm_g_value_new (G_TYPE_STRV);
+ g_value_set_boxed (value, property_value);
+ g_tree_replace (properties->sm_properties,
+ g_strdup (property_name),
+ value);
+ }
+}
+
+void
+xfsm_properties_set_uchar (XfsmProperties *properties,
+ const gchar *property_name,
+ guchar property_value)
+{
+ GValue *value;
+
+ g_return_if_fail (properties != NULL);
+ g_return_if_fail (property_name != NULL);
+
+ xfsm_verbose ("-> Set uchar (%s, %d)\n", property_name, property_value);
+
+ value = g_tree_lookup (properties->sm_properties, property_name);
+ if (value)
+ {
+ if (!G_VALUE_HOLDS_UCHAR (value))
+ {
+ g_value_unset (value);
+ g_value_init (value, G_TYPE_UCHAR);
+ }
+ g_value_set_uchar (value, property_value);
+ }
+ else
+ {
+ value = xfsm_g_value_new (G_TYPE_UCHAR);
+ g_value_set_uchar (value, property_value);
+ g_tree_replace (properties->sm_properties,
+ g_strdup (property_name),
+ value);
+ }
+}
+
+
+gboolean
+xfsm_properties_set (XfsmProperties *properties,
+ const gchar *property_name,
+ const GValue *property_value)
+{
+ GValue *new_value;
+
+ g_return_val_if_fail (properties != NULL, FALSE);
+ g_return_val_if_fail (property_name != NULL, FALSE);
+ g_return_val_if_fail (property_value != NULL, FALSE);
+
+ if (!G_VALUE_HOLDS (property_value, G_TYPE_STRV)
+ && !G_VALUE_HOLDS_STRING (property_value)
+ && !G_VALUE_HOLDS_UCHAR (property_value))
+ {
+ g_warning ("Unhandled property \"%s\" of type \"%s\"", property_name,
+ g_type_name (G_VALUE_TYPE (property_value)));
+ return FALSE;
+ }
+
+ xfsm_verbose ("-> Set (%s)\n", property_name);
+
+ new_value = xfsm_g_value_new (G_VALUE_TYPE (property_value));
+ g_value_copy (property_value, new_value);
+
+ g_tree_replace (properties->sm_properties, g_strdup (property_name), new_value);
+
+ return TRUE;
+}
+
+gboolean
+xfsm_properties_set_from_smprop (XfsmProperties *properties,
+ const SmProp *sm_prop)
+{
+ GValue *value;
+ gchar **value_strv;
+ guchar value_uchar;
+ gint n;
+
+ g_return_val_if_fail (properties != NULL, FALSE);
+ g_return_val_if_fail (sm_prop != NULL, FALSE);
+
+ if (!strcmp (sm_prop->type, SmLISTofARRAY8))
+ {
+ if (G_UNLIKELY (!sm_prop->num_vals || !sm_prop->vals))
+ return FALSE;
+
+ value_strv = g_new0 (gchar *, sm_prop->num_vals + 1);
+ for (n = 0; n < sm_prop->num_vals; ++n)
+ value_strv[n] = g_strdup ((const gchar *) sm_prop->vals[n].value);
+
+ xfsm_verbose ("-> Set strv (%s)\n", sm_prop->name);
+
+ /* don't use _set_strv() to avoid a realloc of the whole strv */
+ value = g_tree_lookup (properties->sm_properties, sm_prop->name);
+ if (value)
+ {
+ if (!G_VALUE_HOLDS (value, G_TYPE_STRV))
+ {
+ g_value_unset (value);
+ g_value_init (value, G_TYPE_STRV);
+ }
+ g_value_take_boxed (value, value_strv);
+ }
+ else
+ {
+ value = xfsm_g_value_new (G_TYPE_STRV);
+ g_value_take_boxed (value, value_strv);
+ g_tree_replace (properties->sm_properties,
+ g_strdup (sm_prop->name),
+ value);
+ }
+ }
+ else if (!strcmp (sm_prop->type, SmARRAY8))
+ {
+ if (G_UNLIKELY (!sm_prop->vals[0].value))
+ return FALSE;
+
+ xfsm_properties_set_string (properties, sm_prop->name, sm_prop->vals[0].value);
+ }
+ else if (!strcmp (sm_prop->type, SmCARD8))
+ {
+ value_uchar = *(guchar *)(sm_prop->vals[0].value);
+ xfsm_properties_set_uchar (properties, sm_prop->name, value_uchar);
+ }
+ else
+ {
+ g_warning ("Unhandled SMProp type: \"%s\"", sm_prop->type);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+gboolean
+xfsm_properties_remove (XfsmProperties *properties,
+ const gchar *property_name)
+{
+ g_return_val_if_fail (properties != NULL, FALSE);
+ g_return_val_if_fail (property_name != NULL, FALSE);
+
+ xfsm_verbose ("-> Removing (%s)\n", property_name);
+
+ return g_tree_remove (properties->sm_properties, property_name);
+}
+
+
+void
+xfsm_properties_set_default_child_watch (XfsmProperties *properties)
+{
+ if (properties->child_watch_id > 0)
+ {
+ g_source_remove (properties->child_watch_id);
+ properties->child_watch_id = 0;
+ }
+
+ if (properties->pid != -1)
+ {
+ /* if the PID is still open, we need to close it,
+ * or it will become a zombie when it quits */
+ g_child_watch_add (properties->pid,
+ (GChildWatchFunc) g_spawn_close_pid,
+ NULL);
+ properties->pid = -1;
+ }
+}
+
+void
+xfsm_properties_free (XfsmProperties *properties)
+{
+ g_return_if_fail (properties != NULL);
+
+ xfsm_properties_set_default_child_watch (properties);
+
+ if (properties->restart_attempts_reset_id > 0)
+ g_source_remove (properties->restart_attempts_reset_id);
+ if (properties->startup_timeout_id > 0)
+ g_source_remove (properties->startup_timeout_id);
+
+ if (properties->client_id != NULL)
+ g_free (properties->client_id);
+ if (properties->hostname != NULL)
+ g_free (properties->hostname);
+
+ g_tree_destroy (properties->sm_properties);
+
+ g_slice_free (XfsmProperties, properties);
+}
diff --git a/xfce4-session/xfsm-properties.h b/xfce4-session/xfsm-properties.h
new file mode 100644
index 0000000..6fe00e7
--- /dev/null
+++ b/xfce4-session/xfsm-properties.h
@@ -0,0 +1,110 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifndef __XFSM_PROPERTIES_H__
+#define __XFSM_PROPERTIES_H__
+
+#include <X11/SM/SMlib.h>
+
+#include <libxfce4util/libxfce4util.h>
+
+/* GNOME compatibility */
+#define GsmPriority "_GSM_Priority"
+#define GsmDesktopFile "_GSM_DesktopFile"
+
+#define MAX_RESTART_ATTEMPTS 5
+
+typedef struct _XfsmProperties XfsmProperties;
+
+struct _XfsmProperties
+{
+ guint restart_attempts;
+ guint restart_attempts_reset_id;
+
+ guint startup_timeout_id;
+
+ GPid pid;
+ guint child_watch_id;
+
+ gchar *client_id;
+ gchar *hostname;
+
+ GTree *sm_properties;
+};
+
+
+#define XFSM_PROPERTIES(p) ((XfsmProperties *) (p))
+
+
+XfsmProperties *xfsm_properties_new (const gchar *client_id,
+ const gchar *hostname) G_GNUC_PURE;
+void xfsm_properties_free (XfsmProperties *properties);
+
+void xfsm_properties_extract (XfsmProperties *properties,
+ gint *num_props,
+ SmProp ***props);
+void xfsm_properties_store (XfsmProperties *properties,
+ XfceRc *rc,
+ const gchar *prefix);
+
+XfsmProperties* xfsm_properties_load (XfceRc *rc, const gchar *prefix);
+
+gboolean xfsm_properties_check (const XfsmProperties *properties) G_GNUC_CONST;
+
+const gchar *xfsm_properties_get_string (XfsmProperties *properties,
+ const gchar *property_name);
+gchar **xfsm_properties_get_strv (XfsmProperties *properties,
+ const gchar *property_name);
+guchar xfsm_properties_get_uchar (XfsmProperties *properties,
+ const gchar *property_name,
+ guchar default_value);
+
+const GValue *xfsm_properties_get (XfsmProperties *properties,
+ const gchar *property_name);
+
+void xfsm_properties_set_string (XfsmProperties *properties,
+ const gchar *property_name,
+ const gchar *property_value);
+void xfsm_properties_set_strv (XfsmProperties *properties,
+ const gchar *property_name,
+ gchar **property_value);
+void xfsm_properties_set_uchar (XfsmProperties *properties,
+ const gchar *property_name,
+ guchar property_value);
+
+gboolean xfsm_properties_set (XfsmProperties *properties,
+ const gchar *property_name,
+ const GValue *property_value);
+gboolean xfsm_properties_set_from_smprop (XfsmProperties *properties,
+ const SmProp *sm_prop);
+
+gboolean xfsm_properties_remove (XfsmProperties *properties,
+ const gchar *property_name);
+
+void xfsm_properties_set_default_child_watch (XfsmProperties *properties);
+
+gint xfsm_properties_compare (const XfsmProperties *a,
+ const XfsmProperties *b) G_GNUC_CONST;
+
+gint xfsm_properties_compare_id (const XfsmProperties *properties,
+ const gchar *client_id);
+
+#endif /* !__XFSM_PROPERTIES_H__ */
diff --git a/xfce4-session/xfsm-shutdown-fallback.c b/xfce4-session/xfsm-shutdown-fallback.c
new file mode 100644
index 0000000..24437e8
--- /dev/null
+++ b/xfce4-session/xfsm-shutdown-fallback.c
@@ -0,0 +1,371 @@
+/*-
+ * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2011 Nick Schermer <nick@xfce.org>
+ * Copyright (c) 2014 Xfce Development Team <xfce4-dev@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ *
+ * Parts of this file where taken from gnome-session/logout.c, which
+ * was written by Owen Taylor <otaylor@redhat.com>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#ifdef HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <libxfce4util/libxfce4util.h>
+#include <gtk/gtk.h>
+#ifdef HAVE_UPOWER
+#include <upower.h>
+#endif
+#ifdef HAVE_POLKIT
+#include <polkit/polkit.h>
+#endif
+
+#include <libxfsm/xfsm-util.h>
+#include <xfce4-session/xfsm-shutdown-fallback.h>
+
+
+
+#define POLKIT_AUTH_SHUTDOWN_XFSM "org.xfce.session.xfsm-shutdown-helper"
+#define POLKIT_AUTH_RESTART_XFSM "org.xfce.session.xfsm-shutdown-helper"
+#define POLKIT_AUTH_SUSPEND_XFSM "org.xfce.session.xfsm-shutdown-helper"
+#define POLKIT_AUTH_HIBERNATE_XFSM "org.xfce.session.xfsm-shutdown-helper"
+
+
+
+
+#ifdef BACKEND_TYPE_FREEBSD
+static gchar *
+get_string_sysctl (GError **err, const gchar *format, ...)
+{
+ va_list args;
+ gchar *name;
+ size_t value_len;
+ gchar *str = NULL;
+
+ g_return_val_if_fail(format != NULL, FALSE);
+
+ va_start (args, format);
+ name = g_strdup_vprintf (format, args);
+ va_end (args);
+
+ if (sysctlbyname (name, NULL, &value_len, NULL, 0) == 0) {
+ str = g_new (char, value_len + 1);
+ if (sysctlbyname (name, str, &value_len, NULL, 0) == 0)
+ str[value_len] = 0;
+ else {
+ g_free (str);
+ str = NULL;
+ }
+ }
+
+ if (!str)
+ g_set_error (err, 0, 0, "%s", g_strerror(errno));
+
+ g_free(name);
+ return str;
+}
+
+
+
+static gboolean
+freebsd_supports_sleep_state (const gchar *state)
+{
+ gboolean ret = FALSE;
+ gchar *sleep_states;
+
+ sleep_states = get_string_sysctl (NULL, "hw.acpi.supported_sleep_state");
+ if (sleep_states != NULL)
+ {
+ if (strstr (sleep_states, state) != NULL)
+ ret = TRUE;
+ }
+
+ g_free (sleep_states);
+
+ return ret;
+}
+#endif /* BACKEND_TYPE_FREEBSD */
+
+
+
+#ifdef BACKEND_TYPE_LINUX
+static gboolean
+linux_supports_sleep_state (const gchar *state)
+{
+ gboolean ret = FALSE;
+ gchar *command;
+ GError *error = NULL;
+ gint exit_status;
+
+ /* run script from pm-utils */
+ command = g_strdup_printf ("/usr/bin/pm-is-supported --%s", state);
+
+ ret = g_spawn_command_line_sync (command, NULL, NULL, &exit_status, &error);
+ if (!ret)
+ {
+ g_warning ("failed to run script: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+ ret = (WIFEXITED(exit_status) && (WEXITSTATUS(exit_status) == EXIT_SUCCESS));
+
+out:
+ g_free (command);
+
+ return ret;
+}
+#endif /* BACKEND_TYPE_LINUX */
+
+
+
+static gboolean
+xfsm_shutdown_fallback_check_auth (const gchar *action_id)
+{
+ gboolean auth_result = FALSE;
+#ifdef HAVE_POLKIT
+ GDBusConnection *bus;
+ PolkitAuthority *polkit;
+ PolkitAuthorizationResult *polkit_result;
+ PolkitSubject *polkit_subject;
+
+ bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL);
+ polkit = polkit_authority_get_sync (NULL, NULL);
+ if (polkit != NULL && bus != NULL)
+ {
+ polkit_subject = polkit_system_bus_name_new (g_dbus_connection_get_unique_name (bus));
+ polkit_result = polkit_authority_check_authorization_sync (polkit,
+ polkit_subject,
+ action_id,
+ NULL,
+ POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE,
+ NULL,
+ NULL);
+ if (polkit_result != NULL)
+ {
+ auth_result = polkit_authorization_result_get_is_authorized (polkit_result);
+ g_object_unref (polkit_result);
+ }
+
+ g_object_unref (polkit);
+ g_object_unref (bus);
+ }
+#endif /* HAVE_POLKIT */
+
+ return auth_result;
+}
+
+
+
+static gboolean
+lock_screen (GError **error)
+{
+ XfconfChannel *channel;
+ gboolean ret = TRUE;
+
+ channel = xfsm_open_config ();
+ if (xfconf_channel_get_bool (channel, "/shutdown/LockScreen", FALSE))
+ ret = g_spawn_command_line_async ("xflock4", error);
+
+ if (ret)
+ {
+ /* sleep 2 seconds so locking has time to startup */
+ g_usleep (G_USEC_PER_SEC * 2);
+ }
+
+ return ret;
+}
+
+
+
+/**
+ * xfsm_shutdown_fallback_try_action:
+ * @type: The @XfsmShutdownType action to perform (shutdown, suspend, etc).
+ * @error: Returns a @GError if an error was encountered.
+ *
+ * Performs the @XfsmShutdownType action requested.
+ *
+ * Return value: Returns FALSE if an invalid @XfsmShutdownType action was
+ * requested. Otherwise returns the status of the pkexec
+ * call to the helper command.
+ **/
+gboolean
+xfsm_shutdown_fallback_try_action (XfsmShutdownType type,
+ GError **error)
+{
+ const gchar *action;
+ gboolean ret;
+ gint exit_status = 0;
+ gchar *command = NULL;
+
+ if (type == XFSM_SHUTDOWN_SHUTDOWN)
+ action = "shutdown";
+ if (type == XFSM_SHUTDOWN_RESTART)
+ action = "restart";
+ else if (type == XFSM_SHUTDOWN_SUSPEND)
+ {
+ action = "suspend";
+ /* On suspend we try to lock the screen */
+ if (!lock_screen (error))
+ return FALSE;
+ }
+ else if (type == XFSM_SHUTDOWN_HIBERNATE)
+ {
+ action = "hibernate";
+ /* On hibernate we try to lock the screen */
+ if (!lock_screen (error))
+ return FALSE;
+ }
+ else
+ return FALSE;
+
+ command = g_strdup_printf ("pkexec " XFSM_SHUTDOWN_HELPER_CMD " --%s", action);
+ ret = g_spawn_command_line_sync (command, NULL, NULL, &exit_status, error);
+
+ g_free (command);
+ return ret;
+}
+
+
+
+/**
+ * xfsm_shutdown_fallback_can_suspend:
+ *
+ * Return value: Returns whether the *system* is capable suspending.
+ **/
+gboolean
+xfsm_shutdown_fallback_can_suspend (void)
+{
+#ifdef BACKEND_TYPE_FREEBSD
+ return freebsd_supports_sleep_state ("S3");
+#endif
+#ifdef BACKEND_TYPE_LINUX
+ return linux_supports_sleep_state ("suspend");
+#endif
+#ifdef BACKEND_TYPE_OPENBSD
+ return TRUE;
+#endif
+
+ return FALSE;
+}
+
+
+
+/**
+ * xfsm_shutdown_fallback_can_hibernate:
+ *
+ * Return value: Returns whether the *system* is capable hibernating.
+ **/
+gboolean
+xfsm_shutdown_fallback_can_hibernate (void)
+{
+#ifdef BACKEND_TYPE_FREEBSD
+ return freebsd_supports_sleep_state ("S4");
+#endif
+#ifdef BACKEND_TYPE_LINUX
+ return linux_supports_sleep_state ("hibernate");
+#endif
+#ifdef BACKEND_TYPE_OPENBSD
+ return TRUE;
+#endif
+
+ return FALSE;
+}
+
+
+
+/**
+ * xfsm_shutdown_fallback_auth_shutdown:
+ *
+ * Return value: Returns whether the user is authorized to perform a shutdown.
+ **/
+gboolean
+xfsm_shutdown_fallback_auth_shutdown (void)
+{
+ return xfsm_shutdown_fallback_check_auth (POLKIT_AUTH_SHUTDOWN_XFSM);
+}
+
+
+
+/**
+ * xfsm_shutdown_fallback_auth_restart:
+ *
+ * Return value: Returns whether the user is authorized to perform a restart.
+ **/
+gboolean
+xfsm_shutdown_fallback_auth_restart (void)
+{
+ return xfsm_shutdown_fallback_check_auth (POLKIT_AUTH_RESTART_XFSM);
+}
+
+
+
+/**
+ * xfsm_shutdown_fallback_auth_suspend:
+ *
+ * Return value: Returns whether the user is authorized to perform a suspend.
+ **/
+gboolean
+xfsm_shutdown_fallback_auth_suspend (void)
+{
+ return xfsm_shutdown_fallback_check_auth (POLKIT_AUTH_SUSPEND_XFSM);
+}
+
+
+
+/**
+ * xfsm_shutdown_fallback_auth_hibernate:
+ *
+ * Return value: Returns whether the user is authorized to perform a hibernate.
+ **/
+gboolean
+xfsm_shutdown_fallback_auth_hibernate (void)
+{
+ return xfsm_shutdown_fallback_check_auth (POLKIT_AUTH_HIBERNATE_XFSM);
+}
diff --git a/xfce4-session/xfsm-shutdown-fallback.h b/xfce4-session/xfsm-shutdown-fallback.h
new file mode 100644
index 0000000..e4909e7
--- /dev/null
+++ b/xfce4-session/xfsm-shutdown-fallback.h
@@ -0,0 +1,39 @@
+/*-
+ * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2011 Nick Schermer <nick@xfce.org>
+ * Copyright (c) 2014 Xfce Development Team <xfce4-dev@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifndef __XFSM_SHUTDOWN_FALLBACK_H__
+#define __XFSM_SHUTDOWN_FALLBACK_H__
+
+#include <xfce4-session/xfsm-shutdown.h>
+
+gboolean xfsm_shutdown_fallback_auth_shutdown (void);
+gboolean xfsm_shutdown_fallback_auth_restart (void);
+gboolean xfsm_shutdown_fallback_auth_suspend (void);
+gboolean xfsm_shutdown_fallback_auth_hibernate (void);
+
+gboolean xfsm_shutdown_fallback_can_suspend (void);
+gboolean xfsm_shutdown_fallback_can_hibernate (void);
+
+gboolean xfsm_shutdown_fallback_try_action (XfsmShutdownType type,
+ GError **error);
+
+#endif /* !__XFSM_SHUTDOWN_FALLBACK_H__ */
diff --git a/xfce4-session/xfsm-shutdown.c b/xfce4-session/xfsm-shutdown.c
new file mode 100644
index 0000000..d8209f2
--- /dev/null
+++ b/xfce4-session/xfsm-shutdown.c
@@ -0,0 +1,509 @@
+/*-
+ * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2011 Nick Schermer <nick@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ *
+ * Parts of this file where taken from gnome-session/logout.c, which
+ * was written by Owen Taylor <otaylor@redhat.com>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#ifdef HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <libxfce4util/libxfce4util.h>
+#include <gtk/gtk.h>
+#ifdef HAVE_UPOWER
+#include <upower.h>
+#endif
+#ifdef HAVE_POLKIT
+#include <polkit/polkit.h>
+#endif
+
+#include <libxfsm/xfsm-util.h>
+
+#include <xfce4-session/xfsm-shutdown.h>
+#include <xfce4-session/xfsm-compat-gnome.h>
+#include <xfce4-session/xfsm-compat-kde.h>
+#include <xfce4-session/xfsm-consolekit.h>
+#include <xfce4-session/xfsm-fadeout.h>
+#include <xfce4-session/xfsm-global.h>
+#include <xfce4-session/xfsm-legacy.h>
+#include <xfce4-session/xfsm-upower.h>
+#include <xfce4-session/xfsm-systemd.h>
+#include <xfce4-session/xfsm-shutdown-fallback.h>
+
+
+
+static void xfsm_shutdown_finalize (GObject *object);
+
+
+
+struct _XfsmShutdownClass
+{
+ GObjectClass __parent__;
+};
+
+
+struct _XfsmShutdown
+{
+ GObject __parent__;
+
+ XfsmSystemd *systemd;
+ XfsmConsolekit *consolekit;
+ XfsmUPower *upower;
+
+ /* kiosk settings */
+ gboolean kiosk_can_shutdown;
+ gboolean kiosk_can_save_session;
+};
+
+
+
+G_DEFINE_TYPE (XfsmShutdown, xfsm_shutdown, G_TYPE_OBJECT)
+
+
+
+static void
+xfsm_shutdown_class_init (XfsmShutdownClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = xfsm_shutdown_finalize;
+}
+
+
+
+static void
+xfsm_shutdown_init (XfsmShutdown *shutdown)
+{
+ XfceKiosk *kiosk;
+
+ shutdown->consolekit = NULL;
+ shutdown->systemd = NULL;
+ shutdown->upower = NULL;
+ if (LOGIND_RUNNING())
+ shutdown->systemd = xfsm_systemd_get ();
+ else
+ shutdown->consolekit = xfsm_consolekit_get ();
+
+#ifdef HAVE_UPOWER
+#if !UP_CHECK_VERSION(0, 99, 0)
+ shutdown->upower = xfsm_upower_get ();
+#endif /* UP_CHECK_VERSION */
+#endif /* HAVE_UPOWER */
+
+ /* check kiosk */
+ kiosk = xfce_kiosk_new ("xfce4-session");
+ shutdown->kiosk_can_shutdown = xfce_kiosk_query (kiosk, "Shutdown");
+ shutdown->kiosk_can_save_session = xfce_kiosk_query (kiosk, "SaveSession");
+ xfce_kiosk_free (kiosk);
+}
+
+
+
+static void
+xfsm_shutdown_finalize (GObject *object)
+{
+ XfsmShutdown *shutdown = XFSM_SHUTDOWN (object);
+
+ if (shutdown->systemd != NULL)
+ g_object_unref (G_OBJECT (shutdown->systemd));
+
+ if (shutdown->consolekit != NULL)
+ g_object_unref (G_OBJECT (shutdown->consolekit));
+ g_object_unref (G_OBJECT (shutdown->upower));
+
+ (*G_OBJECT_CLASS (xfsm_shutdown_parent_class)->finalize) (object);
+}
+
+
+
+static gboolean
+xfsm_shutdown_kiosk_can_shutdown (XfsmShutdown *shutdown,
+ GError **error)
+{
+ if (!shutdown->kiosk_can_shutdown)
+ {
+ g_set_error_literal (error, 1, 0, _("Shutdown is blocked by the kiosk settings"));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+
+XfsmShutdown *
+xfsm_shutdown_get (void)
+{
+ static XfsmShutdown *object = NULL;
+
+ if (G_LIKELY (object != NULL))
+ {
+ g_object_ref (G_OBJECT (object));
+ }
+ else
+ {
+ object = g_object_new (XFSM_TYPE_SHUTDOWN, NULL);
+ g_object_add_weak_pointer (G_OBJECT (object), (gpointer) &object);
+ }
+
+ return object;
+}
+
+
+
+gboolean
+xfsm_shutdown_try_type (XfsmShutdown *shutdown,
+ XfsmShutdownType type,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
+
+ switch (type)
+ {
+ case XFSM_SHUTDOWN_SHUTDOWN:
+ return xfsm_shutdown_try_shutdown (shutdown, error);
+
+ case XFSM_SHUTDOWN_RESTART:
+ return xfsm_shutdown_try_restart (shutdown, error);
+
+ case XFSM_SHUTDOWN_SUSPEND:
+ return xfsm_shutdown_try_suspend (shutdown, error);
+
+ case XFSM_SHUTDOWN_HIBERNATE:
+ return xfsm_shutdown_try_hibernate (shutdown, error);
+
+ default:
+ g_set_error (error, 1, 0, _("Unknown shutdown method %d"), type);
+ break;
+ }
+
+ return FALSE;
+}
+
+
+
+
+gboolean
+xfsm_shutdown_try_restart (XfsmShutdown *shutdown,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
+
+ if (!xfsm_shutdown_kiosk_can_shutdown (shutdown, error))
+ return FALSE;
+
+ if (shutdown->systemd != NULL)
+ {
+ if (xfsm_systemd_try_restart (shutdown->systemd, NULL))
+ {
+ return TRUE;
+ }
+ }
+ else if (shutdown->consolekit != NULL)
+ {
+ if (xfsm_consolekit_try_restart (shutdown->consolekit, NULL))
+ {
+ return TRUE;
+ }
+ }
+
+ return xfsm_shutdown_fallback_try_action (XFSM_SHUTDOWN_RESTART, error);
+}
+
+
+
+gboolean
+xfsm_shutdown_try_shutdown (XfsmShutdown *shutdown,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
+
+ if (!xfsm_shutdown_kiosk_can_shutdown (shutdown, error))
+ return FALSE;
+
+ if (shutdown->systemd != NULL)
+ {
+ if (xfsm_systemd_try_shutdown (shutdown->systemd, NULL))
+ {
+ return TRUE;
+ }
+ }
+ else if (shutdown->consolekit != NULL)
+ {
+ if (xfsm_consolekit_try_shutdown (shutdown->consolekit, NULL))
+ {
+ return TRUE;
+ }
+ }
+
+ return xfsm_shutdown_fallback_try_action (XFSM_SHUTDOWN_SHUTDOWN, error);
+}
+
+
+
+typedef gboolean (*SleepFunc) (gpointer object, GError **);
+
+static gboolean
+try_sleep_method (gpointer object,
+ SleepFunc func)
+{
+ if (object == NULL)
+ return FALSE;
+
+ return func (object, NULL);
+}
+
+
+
+gboolean
+xfsm_shutdown_try_suspend (XfsmShutdown *shutdown,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
+
+ /* Try each way to suspend - it will handle NULL.
+ * In the future the upower code can go away once everyone is
+ * running upower 0.99.0+
+ */
+
+ if (try_sleep_method (shutdown->systemd, (SleepFunc)xfsm_systemd_try_suspend))
+ return TRUE;
+
+ if (try_sleep_method (shutdown->upower, (SleepFunc)xfsm_upower_try_suspend))
+ return TRUE;
+
+ if (try_sleep_method (shutdown->consolekit, (SleepFunc)xfsm_consolekit_try_suspend))
+ return TRUE;
+
+ return xfsm_shutdown_fallback_try_action (XFSM_SHUTDOWN_SUSPEND, error);
+}
+
+
+
+gboolean
+xfsm_shutdown_try_hibernate (XfsmShutdown *shutdown,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
+
+ /* Try each way to hibernate - it will handle NULL.
+ * In the future the upower code can go away once everyone is
+ * running upower 0.99.0+
+ */
+
+ if (try_sleep_method (shutdown->systemd, (SleepFunc)xfsm_systemd_try_hibernate))
+ return TRUE;
+
+ if (try_sleep_method (shutdown->upower, (SleepFunc)xfsm_upower_try_hibernate))
+ return TRUE;
+
+ if (try_sleep_method (shutdown->consolekit, (SleepFunc)xfsm_consolekit_try_hibernate))
+ return TRUE;
+
+ return xfsm_shutdown_fallback_try_action (XFSM_SHUTDOWN_HIBERNATE, error);
+}
+
+
+
+gboolean
+xfsm_shutdown_can_restart (XfsmShutdown *shutdown,
+ gboolean *can_restart,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
+
+ if (!xfsm_shutdown_kiosk_can_shutdown (shutdown, NULL))
+ {
+ *can_restart = FALSE;
+ return TRUE;
+ }
+
+ if (shutdown->systemd != NULL)
+ {
+ if (xfsm_systemd_can_restart (shutdown->systemd, can_restart, error))
+ return TRUE;
+ }
+ else if (shutdown->consolekit != NULL)
+ {
+ if (xfsm_consolekit_can_restart (shutdown->consolekit, can_restart, error))
+ return TRUE;
+ }
+
+ *can_restart = xfsm_shutdown_fallback_auth_restart ();
+ return TRUE;
+}
+
+
+
+gboolean
+xfsm_shutdown_can_shutdown (XfsmShutdown *shutdown,
+ gboolean *can_shutdown,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
+
+ if (!xfsm_shutdown_kiosk_can_shutdown (shutdown, NULL))
+ {
+ *can_shutdown = FALSE;
+ return TRUE;
+ }
+
+ if (shutdown->systemd != NULL)
+ {
+ if (xfsm_systemd_can_shutdown (shutdown->systemd, can_shutdown, error))
+ return TRUE;
+ }
+ else if (shutdown->consolekit != NULL)
+ {
+ if (xfsm_consolekit_can_shutdown (shutdown->consolekit, can_shutdown, error))
+ return TRUE;
+ }
+
+ *can_shutdown = xfsm_shutdown_fallback_auth_shutdown ();
+ return TRUE;
+}
+
+
+
+gboolean
+xfsm_shutdown_can_suspend (XfsmShutdown *shutdown,
+ gboolean *can_suspend,
+ gboolean *auth_suspend,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
+
+ if (!xfsm_shutdown_kiosk_can_shutdown (shutdown, NULL))
+ {
+ *can_suspend = FALSE;
+ return TRUE;
+ }
+
+ if (shutdown->systemd != NULL)
+ {
+ if (xfsm_systemd_can_suspend (shutdown->systemd, can_suspend, auth_suspend, NULL))
+ {
+ return TRUE;
+ }
+ }
+ else if (shutdown->upower != NULL)
+ {
+ if (xfsm_upower_can_suspend (shutdown->upower, can_suspend, auth_suspend, NULL))
+ {
+ return TRUE;
+ }
+ }
+ else if (shutdown->consolekit != NULL)
+ {
+ if (xfsm_consolekit_can_suspend (shutdown->consolekit, can_suspend, auth_suspend, NULL))
+ {
+ return TRUE;
+ }
+ }
+
+ *can_suspend = xfsm_shutdown_fallback_can_suspend ();
+ *auth_suspend = xfsm_shutdown_fallback_auth_suspend ();
+ return TRUE;
+}
+
+
+
+gboolean
+xfsm_shutdown_can_hibernate (XfsmShutdown *shutdown,
+ gboolean *can_hibernate,
+ gboolean *auth_hibernate,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
+
+ if (!xfsm_shutdown_kiosk_can_shutdown (shutdown, NULL))
+ {
+ *can_hibernate = FALSE;
+ return TRUE;
+ }
+
+ if (shutdown->systemd != NULL)
+ {
+ if (xfsm_systemd_can_hibernate (shutdown->systemd, can_hibernate, auth_hibernate, NULL))
+ {
+ return TRUE;
+ }
+ }
+ else if (shutdown->upower != NULL)
+ {
+ if (xfsm_upower_can_hibernate (shutdown->upower, can_hibernate, auth_hibernate, NULL))
+ {
+ return TRUE;
+ }
+ }
+ else if (shutdown->consolekit != NULL)
+ {
+ if (xfsm_consolekit_can_hibernate (shutdown->consolekit, can_hibernate, auth_hibernate, NULL))
+ {
+ return TRUE;
+ }
+ }
+
+ *can_hibernate = xfsm_shutdown_fallback_can_hibernate ();
+ *auth_hibernate = xfsm_shutdown_fallback_auth_hibernate ();
+ return TRUE;
+}
+
+
+
+gboolean
+xfsm_shutdown_can_save_session (XfsmShutdown *shutdown)
+{
+ g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
+ return shutdown->kiosk_can_save_session;
+}
diff --git a/xfce4-session/xfsm-shutdown.h b/xfce4-session/xfsm-shutdown.h
new file mode 100644
index 0000000..eac26bf
--- /dev/null
+++ b/xfce4-session/xfsm-shutdown.h
@@ -0,0 +1,101 @@
+/*-
+ * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2011 Nick Schermer <nick@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifndef __XFSM_SHUTDOWN_H__
+#define __XFSM_SHUTDOWN_H__
+
+typedef struct _XfsmShutdownClass XfsmShutdownClass;
+typedef struct _XfsmShutdown XfsmShutdown;
+
+#define XFSM_TYPE_SHUTDOWN (xfsm_shutdown_get_type ())
+#define XFSM_SHUTDOWN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFSM_TYPE_SHUTDOWN, XfsmShutdown))
+#define XFSM_SHUTDOWN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFSM_TYPE_SHUTDOWN, XfsmShutdownClass))
+#define XFSM_IS_SHUTDOWN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFSM_TYPE_SHUTDOWN))
+#define XFSM_IS_SHUTDOWN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFSM_TYPE_SHUTDOWN))
+#define XFSM_SHUTDOWN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XFSM_TYPE_SHUTDOWN, XfsmShutdownClass))
+
+typedef enum
+{
+ XFSM_SHUTDOWN_ASK = 0,
+ XFSM_SHUTDOWN_LOGOUT,
+ XFSM_SHUTDOWN_SHUTDOWN,
+ XFSM_SHUTDOWN_RESTART,
+ XFSM_SHUTDOWN_SUSPEND,
+ XFSM_SHUTDOWN_HIBERNATE,
+}
+XfsmShutdownType;
+
+typedef enum
+{
+ PASSWORD_RETRY,
+ PASSWORD_SUCCEED,
+ PASSWORD_FAILED
+}
+XfsmPassState;
+
+GType xfsm_shutdown_get_type (void) G_GNUC_CONST;
+
+XfsmShutdown *xfsm_shutdown_get (void);
+
+gboolean xfsm_shutdown_password_require (XfsmShutdown *shutdown,
+ XfsmShutdownType type);
+
+XfsmPassState xfsm_shutdown_password_send (XfsmShutdown *shutdown,
+ XfsmShutdownType type,
+ const gchar *password);
+
+gboolean xfsm_shutdown_try_type (XfsmShutdown *shutdown,
+ XfsmShutdownType type,
+ GError **error);
+
+gboolean xfsm_shutdown_try_restart (XfsmShutdown *shutdown,
+ GError **error);
+
+gboolean xfsm_shutdown_try_shutdown (XfsmShutdown *shutdown,
+ GError **error);
+
+gboolean xfsm_shutdown_try_suspend (XfsmShutdown *shutdown,
+ GError **error);
+
+gboolean xfsm_shutdown_try_hibernate (XfsmShutdown *shutdown,
+ GError **error);
+
+gboolean xfsm_shutdown_can_restart (XfsmShutdown *shutdown,
+ gboolean *can_restart,
+ GError **error);
+
+gboolean xfsm_shutdown_can_shutdown (XfsmShutdown *shutdown,
+ gboolean *can_shutdown,
+ GError **error);
+
+gboolean xfsm_shutdown_can_suspend (XfsmShutdown *shutdown,
+ gboolean *can_suspend,
+ gboolean *auth_suspend,
+ GError **error);
+
+gboolean xfsm_shutdown_can_hibernate (XfsmShutdown *shutdown,
+ gboolean *can_hibernate,
+ gboolean *auth_hibernate,
+ GError **error);
+
+gboolean xfsm_shutdown_can_save_session (XfsmShutdown *shutdown);
+
+#endif /* !__XFSM_SHUTDOWN_H__ */
diff --git a/xfce4-session/xfsm-splash-screen.c b/xfce4-session/xfsm-splash-screen.c
new file mode 100644
index 0000000..89ca5da
--- /dev/null
+++ b/xfce4-session/xfsm-splash-screen.c
@@ -0,0 +1,305 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2003-2006 Benedikt Meurer <benny@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <gmodule.h>
+
+#include <xfconf/xfconf.h>
+#include <libxfce4util/libxfce4util.h>
+#include <libxfce4ui/libxfce4ui.h>
+
+#include <libxfsm/xfsm-splash-engine.h>
+#include <libxfsm/xfsm-util.h>
+
+#include <xfce4-session/xfsm-chooser.h>
+#include <xfce4-session/xfsm-splash-screen.h>
+
+
+struct _XfsmSplashScreen
+{
+ XfsmSplashEngine engine;
+ GModule *module;
+};
+
+
+static void xfsm_splash_screen_load (XfsmSplashScreen *splash,
+ const gchar *engine);
+
+
+XfsmSplashScreen*
+xfsm_splash_screen_new (GdkDisplay *display,
+ const gchar *engine)
+{
+ XfsmSplashScreen *splash;
+ XfsmSplashRc *splash_rc;
+ GdkScreen *screen;
+ gchar name[128];
+ int monitor;
+ XfconfChannel *channel;
+
+ /* locate monitor with pointer */
+ screen = xfce_gdk_screen_get_active (&monitor);
+
+ if (G_UNLIKELY (screen == NULL) || (gdk_screen_get_display (screen) != display))
+ {
+ screen = gdk_display_get_screen (display, 0);
+ monitor = 0;
+ }
+
+ /* initialize the screen struct */
+ splash = g_new0 (XfsmSplashScreen, 1);
+ splash->engine.display = display;
+ splash->engine.primary_screen = screen;
+ splash->engine.primary_monitor = monitor;
+
+ /* load and setup the engine */
+ if (G_LIKELY (engine != NULL && *engine != '\0'))
+ {
+ xfsm_splash_screen_load (splash, engine);
+ if (G_LIKELY (splash->engine.setup != NULL))
+ {
+ g_snprintf (name, sizeof(name), "/splash/engines/%s", engine);
+ channel = xfconf_channel_new_with_property_base ("xfce4-session",
+ name);
+ splash_rc = xfsm_splash_rc_new (channel);
+ g_object_unref (channel);
+ splash->engine.setup (&splash->engine, splash_rc);
+ xfsm_splash_rc_free (splash_rc);
+
+ gdk_flush ();
+ }
+ }
+
+ return splash;
+}
+
+
+void
+xfsm_splash_screen_start (XfsmSplashScreen *splash,
+ const gchar *name,
+ GdkPixbuf *preview,
+ unsigned steps)
+{
+ if (G_LIKELY (splash->engine.start != NULL))
+ {
+ splash->engine.start (&splash->engine, name, preview, steps);
+ gdk_flush ();
+ }
+}
+
+
+void
+xfsm_splash_screen_next (XfsmSplashScreen *splash,
+ const gchar *text)
+{
+ if (G_LIKELY (splash->engine.next != NULL))
+ {
+ splash->engine.next (&splash->engine, text);
+ gdk_flush ();
+ }
+}
+
+
+int
+xfsm_splash_screen_run (XfsmSplashScreen *splash,
+ GtkWidget *dialog)
+{
+ int result;
+
+ if (G_LIKELY (splash->engine.run != NULL))
+ {
+ result = splash->engine.run (&splash->engine, dialog);
+ }
+ else
+ {
+ gtk_window_set_screen (GTK_WINDOW (dialog), splash->engine.primary_screen);
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
+
+ result = gtk_dialog_run (GTK_DIALOG (dialog));
+ }
+
+ return result;
+}
+
+
+int
+xfsm_splash_screen_choose (XfsmSplashScreen *splash,
+ GList *sessions,
+ const gchar *default_session,
+ gchar **name_return)
+{
+ GtkWidget *chooser;
+ GtkWidget *label;
+ GtkWidget *dialog;
+ GtkWidget *entry;
+ gchar title[256];
+ int result;
+
+ g_assert (default_session != NULL);
+
+ if (splash->engine.choose != NULL)
+ {
+ result = splash->engine.choose (&splash->engine,
+ sessions,
+ default_session,
+ name_return);
+ }
+ else
+ {
+again:
+ xfsm_splash_screen_next (splash, _("Choose session"));
+
+ chooser = g_object_new (XFSM_TYPE_CHOOSER,
+ "screen", splash->engine.primary_screen,
+ "type", GTK_WINDOW_POPUP,
+ NULL);
+ xfsm_window_add_border (GTK_WINDOW (chooser));
+ xfsm_chooser_set_sessions (XFSM_CHOOSER (chooser),
+ sessions, default_session);
+ result = xfsm_splash_screen_run (splash, chooser);
+
+ if (result == XFSM_RESPONSE_LOAD)
+ {
+ if (name_return != NULL)
+ *name_return = xfsm_chooser_get_session (XFSM_CHOOSER (chooser));
+ result = XFSM_CHOOSE_LOAD;
+ }
+ else if (result == XFSM_RESPONSE_NEW)
+ {
+ result = XFSM_CHOOSE_NEW;
+ }
+ else
+ {
+ result = XFSM_CHOOSE_LOGOUT;
+ }
+
+ gtk_widget_destroy (chooser);
+
+ if (result == XFSM_CHOOSE_NEW)
+ {
+ xfsm_splash_screen_next (splash, _("Choose session name"));
+
+ dialog = gtk_dialog_new_with_buttons (NULL,
+ NULL,
+ GTK_DIALOG_NO_SEPARATOR,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK,
+ GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog),
+ GTK_RESPONSE_OK);
+
+ g_snprintf (title, 256, "<big>%s</big>",
+ _("Choose a name for the new session:"));
+ label = gtk_label_new (title);
+ gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+ label, TRUE, TRUE, 6);
+ gtk_widget_show (label);
+
+ entry = gtk_entry_new ();
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+ entry, TRUE, TRUE, 6);
+ gtk_widget_show (entry);
+
+ xfsm_window_add_border (GTK_WINDOW (dialog));
+
+again1:
+ result = xfsm_splash_screen_run (splash, dialog);
+
+ if (result != GTK_RESPONSE_OK)
+ {
+ gtk_widget_destroy (dialog);
+ goto again;
+ }
+
+ if (name_return != NULL)
+ {
+ *name_return = gtk_editable_get_chars (GTK_EDITABLE (entry),
+ 0, -1);
+ if (strlen (*name_return) == 0)
+ {
+ g_free (*name_return);
+ goto again1;
+ }
+ }
+
+ gtk_widget_destroy (dialog);
+ result = XFSM_CHOOSE_NEW;
+ }
+ }
+
+ return result;
+}
+
+
+void
+xfsm_splash_screen_free (XfsmSplashScreen *splash)
+{
+ if (G_LIKELY (splash->engine.destroy != NULL))
+ splash->engine.destroy (&splash->engine);
+ if (G_LIKELY (splash->module != NULL))
+ g_module_close (splash->module);
+ g_free (splash);
+}
+
+
+static void
+xfsm_splash_screen_load (XfsmSplashScreen *splash,
+ const gchar *engine)
+{
+ void (*init) (XfsmSplashEngine *engine);
+ gchar *filename;
+
+ filename = g_module_build_path (LIBDIR "/xfce4/session/splash-engines", engine);
+ splash->module = g_module_open (filename, G_MODULE_BIND_LOCAL);
+ g_free (filename);
+
+ if (G_LIKELY (splash->module != NULL))
+ {
+ if (g_module_symbol (splash->module, "engine_init", (gpointer)&init))
+ {
+ init (&splash->engine);
+ }
+ else
+ {
+ g_module_close (splash->module);
+ splash->module = NULL;
+ }
+ }
+ else
+ {
+ g_warning ("Unable to load engine \"%s\": %s", engine, g_module_error ());
+ }
+}
+
+
diff --git a/xfce4-session/xfsm-splash-screen.h b/xfce4-session/xfsm-splash-screen.h
new file mode 100644
index 0000000..f68c5d4
--- /dev/null
+++ b/xfce4-session/xfsm-splash-screen.h
@@ -0,0 +1,58 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifndef __XFSM_SPLASH_SCREEN_H__
+#define __XFSM_SPLASH_SCREEN_H__
+
+#include <gtk/gtk.h>
+
+#include <libxfce4util/libxfce4util.h>
+
+
+G_BEGIN_DECLS;
+
+typedef struct _XfsmSplashScreen XfsmSplashScreen;
+
+XfsmSplashScreen *xfsm_splash_screen_new (GdkDisplay *display,
+ const gchar *engine);
+
+void xfsm_splash_screen_start (XfsmSplashScreen *splash,
+ const gchar *name,
+ GdkPixbuf *preview,
+ unsigned steps);
+
+void xfsm_splash_screen_next (XfsmSplashScreen *splash,
+ const gchar *text);
+
+int xfsm_splash_screen_run (XfsmSplashScreen *splash,
+ GtkWidget *dialog);
+
+int xfsm_splash_screen_choose (XfsmSplashScreen *splash,
+ GList *sessions,
+ const gchar *default_session,
+ gchar **name_return);
+
+void xfsm_splash_screen_free (XfsmSplashScreen *splash);
+
+G_END_DECLS;
+
+
+#endif /* !__XFSM_SPLASH_SCREEN_H__ */
diff --git a/xfce4-session/xfsm-startup.c b/xfce4-session/xfsm-startup.c
new file mode 100644
index 0000000..76eef86
--- /dev/null
+++ b/xfce4-session/xfsm-startup.c
@@ -0,0 +1,1187 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2003-2006 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2008 Brian Tarricone <bjt23@cornell.edu>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#include <glib/gstdio.h>
+#include <gdk/gdkx.h>
+#include <libxfce4ui/libxfce4ui.h>
+
+#include <libxfsm/xfsm-util.h>
+
+#include <xfce4-session/xfsm-compat-gnome.h>
+#include <xfce4-session/xfsm-compat-kde.h>
+#include <xfce4-session/xfsm-global.h>
+#include <xfce4-session/xfsm-manager.h>
+#include <xfce4-session/xfsm-splash-screen.h>
+
+#include <xfce4-session/xfsm-startup.h>
+
+
+typedef struct
+{
+ XfsmManager *manager;
+ XfsmProperties *properties;
+} XfsmStartupData;
+
+static void xfsm_startup_failsafe (XfsmManager *manager);
+
+static gboolean xfsm_startup_session_next_prio_group (XfsmManager *manager);
+
+static void xfsm_startup_data_free (XfsmStartupData *sdata);
+static void xfsm_startup_child_watch (GPid pid,
+ gint status,
+ gpointer user_data);
+static gboolean xfsm_startup_timeout (gpointer data);
+
+static void xfsm_startup_handle_failed_startup (XfsmProperties *properties,
+ XfsmManager *manager);
+
+
+static pid_t running_sshagent = -1;
+static pid_t running_gpgagent = -1;
+static gboolean gpgagent_ssh_enabled = FALSE;
+
+
+
+static pid_t
+xfsm_gpg_agent_pid (const gchar *gpg_agent_info)
+{
+ pid_t pid = -1;
+ gchar **fields;
+
+ if (gpg_agent_info == NULL || *gpg_agent_info == '\0')
+ return -1;
+
+ fields = g_strsplit (gpg_agent_info, ":", 3);
+ if (fields != NULL)
+ {
+ /* second field of GPG_AGENT_INFO is a PID */
+ pid = atoi (fields[1]);
+ g_strfreev (fields);
+ }
+
+ return pid;
+}
+
+
+
+static pid_t
+xfsm_ssh_agent_pid (const gchar *ssh_agent_pid)
+{
+ if (ssh_agent_pid == NULL || *ssh_agent_pid == '\0')
+ return -1;
+
+ return atoi (ssh_agent_pid);
+}
+
+
+
+static pid_t
+xfsm_startup_init_agent (const gchar *cmd,
+ const gchar *agent)
+{
+ gchar *cmdoutput = NULL;
+ GError *error = NULL;
+ gchar **lines;
+ guint i;
+ gchar *p, *t;
+ gchar *variable, *value;
+ pid_t pid = -1;
+
+ if (g_spawn_command_line_sync (cmd, &cmdoutput, NULL, NULL, &error))
+ {
+ if (G_UNLIKELY (cmdoutput == NULL))
+ {
+ g_message ("%s returned no variables to stdout", agent);
+ return -1;
+ }
+
+ lines = g_strsplit (cmdoutput, "\n", -1);
+ g_assert (lines != NULL);
+ for (i = 0; lines[i] != NULL; i++)
+ {
+ p = strchr (lines[i], '=');
+ if (G_UNLIKELY (p == NULL))
+ continue;
+ t = strchr (p + 1, ';');
+ if (G_UNLIKELY (t == NULL))
+ continue;
+
+ variable = g_strndup (lines[i], p - lines[i]);
+ value = g_strndup (p + 1, t - p - 1);
+
+ /* try to get agent pid from the variable */
+ if (pid <= 0)
+ {
+ if (g_strcmp0 (variable, "SSH_AGENT_PID") == 0)
+ pid = xfsm_ssh_agent_pid (value);
+ else if (g_strcmp0 (variable, "GPG_AGENT_INFO") == 0)
+ pid = xfsm_gpg_agent_pid (value);
+ }
+
+ g_setenv (variable, value, TRUE);
+
+ g_free (variable);
+ g_free (value);
+ }
+ g_strfreev (lines);
+ }
+ else
+ {
+ g_warning ("Failed to spawn %s: %s", agent, error->message);
+ g_error_free (error);
+
+ return -1;
+ }
+
+ g_free (cmdoutput);
+
+ if (pid <= 0)
+ g_warning ("%s returned no PID in the variables", agent);
+
+ return pid;
+}
+
+
+
+void
+xfsm_startup_init (XfconfChannel *channel)
+{
+ gchar *ssh_agent;
+ gchar *ssh_agent_path = NULL;
+ gchar *gpg_agent_path = NULL;
+ gchar *cmd;
+ pid_t agentpid;
+ gboolean gnome_keyring_found;
+
+ /* if GNOME compatibility is enabled and gnome-keyring-daemon
+ * is found, skip the gpg/ssh agent startup and wait for
+ * gnome-keyring, which is probably what the user wants */
+ if (xfconf_channel_get_bool (channel, "/compat/LaunchGNOME", FALSE))
+ {
+ cmd = g_find_program_in_path ("gnome-keyring-daemon");
+ gnome_keyring_found = (cmd != NULL);
+ g_free (cmd);
+
+ if (gnome_keyring_found)
+ {
+ g_print ("xfce4-session: %s\n",
+ "GNOME compatibility is enabled and gnome-keyring-daemon is "
+ "found on the system. Skipping gpg/ssh-agent startup.");
+ return;
+ }
+ }
+
+ if (xfconf_channel_get_bool (channel, "/startup/gpg-agent/enabled", TRUE))
+ {
+ gpg_agent_path = g_find_program_in_path ("gpg-agent");
+ if (gpg_agent_path == NULL)
+ g_printerr ("xfce4-session: %s\n",
+ "No GPG agent found");
+ }
+
+ if (xfconf_channel_get_bool (channel, "/startup/ssh-agent/enabled", TRUE))
+ {
+ ssh_agent = xfconf_channel_get_string (channel, "/startup/ssh-agent/type", NULL);
+
+ if (ssh_agent == NULL
+ || g_strcmp0 (ssh_agent, "ssh-agent") == 0)
+ {
+ ssh_agent_path = g_find_program_in_path ("ssh-agent");
+ if (ssh_agent_path == NULL)
+ g_printerr ("xfce4-session: %s\n",
+ "No SSH authentication agent found");
+ }
+ else if (g_strcmp0 (ssh_agent, "gpg-agent") == 0)
+ {
+ if (gpg_agent_path != NULL)
+ gpgagent_ssh_enabled = TRUE;
+ else
+ g_printerr ("xfce4-session: %s\n", "gpg-agent is configured as SSH agent, "
+ "but gpg-agent is disabled or not found");
+ }
+ else
+ {
+ g_message ("Unknown SSH authentication agent \"%s\" set", ssh_agent);
+ }
+ g_free (ssh_agent);
+ }
+
+ if (G_LIKELY (ssh_agent_path != NULL || gpgagent_ssh_enabled))
+ {
+ agentpid = xfsm_ssh_agent_pid (g_getenv ("SSH_AGENT_PID"));
+
+ /* check if the pid is still responding (ie not stale) */
+ if (agentpid > 0 && kill (agentpid, 0) == 0)
+ {
+ g_message ("SSH authentication agent is already running");
+
+ gpgagent_ssh_enabled = FALSE;
+ g_free (ssh_agent_path);
+ ssh_agent_path = NULL;
+ }
+ else
+ {
+ g_unsetenv ("SSH_AGENT_PID");
+ g_unsetenv ("SSH_AUTH_SOCK");
+ }
+
+ if (ssh_agent_path != NULL)
+ {
+ cmd = g_strdup_printf ("%s -s", ssh_agent_path);
+ /* keep this around for shutdown */
+ running_sshagent = xfsm_startup_init_agent (cmd, "ssh-agent");
+ g_free (cmd);
+ g_free (ssh_agent_path);
+ }
+ }
+
+ if (G_LIKELY (gpg_agent_path != NULL))
+ {
+ agentpid = xfsm_gpg_agent_pid (g_getenv ("GPG_AGENT_INFO"));
+
+ /* check if the pid is still responding (ie not stale) */
+ if (agentpid > 0 && kill (agentpid, 0) == 0)
+ {
+ g_message ("GPG agent is already running");
+ }
+ else
+ {
+ gchar *envfile;
+
+ g_unsetenv ("GPG_AGENT_INFO");
+
+ envfile = xfce_resource_save_location (XFCE_RESOURCE_CACHE, "gpg-agent-info", FALSE);
+
+ if (gpgagent_ssh_enabled)
+ {
+ cmd = g_strdup_printf ("%s --sh --daemon --enable-ssh-support "
+ "--write-env-file '%s'", gpg_agent_path, envfile);
+ }
+ else
+ {
+ cmd = g_strdup_printf ("%s --sh --daemon --write-env-file '%s'", gpg_agent_path, envfile);
+ }
+
+ /* keep this around for shutdown */
+ running_gpgagent = xfsm_startup_init_agent (cmd, "gpg-agent");
+
+ g_free (cmd);
+ g_free (envfile);
+ }
+
+ g_free (gpg_agent_path);
+ }
+}
+
+
+
+void
+xfsm_startup_shutdown (void)
+{
+ if (running_sshagent > 0)
+ {
+ if (kill (running_sshagent, SIGTERM) == 0)
+ {
+ /* make sure the env values are unset */
+ g_unsetenv ("SSH_AGENT_PID");
+ g_unsetenv ("SSH_AUTH_SOCK");
+ }
+ else
+ {
+ g_warning ("Failed to kill ssh-agent with pid %d", running_sshagent);
+ }
+ }
+
+ if (running_gpgagent > 0)
+ {
+ gchar *envfile;
+ if (kill (running_gpgagent, SIGINT) == 0)
+ {
+ /* make sure the env values are unset */
+ g_unsetenv ("GPG_AGENT_INFO");
+ if (gpgagent_ssh_enabled)
+ {
+ g_unsetenv ("SSH_AGENT_PID");
+ g_unsetenv ("SSH_AUTH_SOCK");
+ }
+ }
+ else
+ {
+ g_warning ("Failed to kill gpg-agent with pid %d", running_gpgagent);
+ }
+
+ /* drop the info file from gpg-agent */
+ envfile = xfce_resource_lookup (XFCE_RESOURCE_CACHE, "gpg-agent-info");
+ if (G_LIKELY (envfile != NULL))
+ g_unlink (envfile);
+ g_free (envfile);
+ }
+}
+
+
+
+static gboolean
+destroy_splash (gpointer user_data)
+{
+ if (G_LIKELY (splash_screen != NULL))
+ {
+ xfsm_splash_screen_free (splash_screen);
+ splash_screen = NULL;
+ }
+
+ return FALSE;
+}
+
+
+static const gchar*
+figure_app_name (const gchar *program_path)
+{
+ static char progbuf[256];
+ gchar *prog;
+
+ prog = g_path_get_basename (program_path);
+
+ /* Xfce applications */
+ if (strcmp (prog, "xfce4-mixer") == 0)
+ return _("Starting the Volume Controller");
+ else if (strcmp (prog, "xfce4-panel") == 0)
+ return _("Starting the Panel");
+ else if (strcmp (prog, "xfdesktop") == 0)
+ return _("Starting the Desktop Manager");
+ else if (strcmp (prog, "xftaskbar4") == 0)
+ return _("Starting the Taskbar");
+ else if (strcmp (prog, "xfwm4") == 0)
+ return _("Starting the Window Manager");
+
+ /* Gnome applications */
+ if (strcmp (prog, "gnome-terminal") == 0)
+ return _("Starting the Gnome Terminal Emulator");
+
+ /* KDE applications */
+ if (strcmp (prog, "kate") == 0)
+ return _("Starting the KDE Advanced Text Editor");
+ else if (strcmp (prog, "klipper") == 0)
+ return _("Starting the KDE Clipboard Manager");
+ else if (strcmp (prog, "kmail") == 0)
+ return _("Starting the KDE Mail Reader");
+ else if (strcmp (prog, "knews") == 0)
+ return _("Starting the KDE News Reader");
+ else if (strcmp (prog, "konqueror") == 0)
+ return _("Starting the Konqueror");
+ else if (strcmp (prog, "konsole") == 0)
+ return _("Starting the KDE Terminal Emulator");
+
+ /* 3rd party applications */
+ if (strcmp (prog, "beep-media-player") == 0)
+ return _("Starting the Beep Media Player");
+ else if (strncmp (prog, "gimp", 4) == 0)
+ return _("Starting The Gimp");
+ else if (strcmp (prog, "gvim") == 0)
+ return _("Starting the VI Improved Editor");
+ else if (strcmp (prog, "smproxy") == 0)
+ return _("Starting the Session Management Proxy");
+ else if (strcmp (prog, "xchat") == 0 || strcmp (prog, "xchat2") == 0)
+ return _("Starting the X-Chat IRC Client");
+ else if (strcmp (prog, "xmms") == 0)
+ return _("Starting the X Multimedia System");
+ else if (strcmp (prog, "xterm") == 0)
+ return _("Starting the X Terminal Emulator");
+
+ g_snprintf (progbuf, 256, _("Starting %s"), prog);
+
+ return progbuf;
+}
+
+
+
+static gboolean
+xfsm_check_valid_exec (const gchar *exec)
+{
+ gboolean result = TRUE;
+ gchar *tmp;
+ gchar *p;
+
+ if (*exec == '/')
+ {
+ result = (access (exec, X_OK) == 0);
+ }
+ else
+ {
+ tmp = g_strdup (exec);
+ p = strchr (tmp, ' ');
+ if (G_UNLIKELY (p != NULL))
+ *p = '\0';
+
+ p = g_find_program_in_path (tmp);
+ g_free (tmp);
+
+ if (G_UNLIKELY (p == NULL))
+ {
+ result = FALSE;
+ }
+ else
+ {
+ result = (access (p, X_OK) == 0);
+ g_free (p);
+ }
+ }
+
+ return result;
+}
+
+
+
+static void
+xfsm_startup_autostart_migrate (void)
+{
+ const gchar *entry;
+ gchar source_path[4096];
+ gchar target_path[4096];
+ gchar *source;
+ gchar *target;
+ FILE *fp;
+ GDir *dp;
+
+ /* migrate the content */
+ source = xfce_get_homefile ("Desktop", "Autostart/", NULL);
+ dp = g_dir_open (source, 0, NULL);
+ if (G_UNLIKELY (dp != NULL))
+ {
+ /* check if the LOCATION-CHANGED.txt file exists and the target can be opened */
+ g_snprintf (source_path, 4096, "%s/LOCATION-CHANGED.txt", source);
+ target = xfce_resource_save_location (XFCE_RESOURCE_CONFIG, "autostart/", TRUE);
+ if (G_LIKELY (target != NULL && !g_file_test (source_path, G_FILE_TEST_IS_REGULAR)))
+ {
+ g_message ("Trying to migrate autostart items from %s to %s...", source, target);
+
+ for (;;)
+ {
+ entry = g_dir_read_name (dp);
+ if (entry == NULL)
+ break;
+
+ /* determine full source and dest paths */
+ g_snprintf (source_path, 4096, "%s%s", source, entry);
+ g_snprintf (target_path, 4096, "%s%s", target, entry);
+
+ /* try to move the file */
+ if (rename (source_path, target_path) < 0)
+ {
+ g_warning ("Failed to rename %s to %s: %s",
+ source_path, target_path,
+ g_strerror (errno));
+ continue;
+ }
+
+ /* check if the file is executable */
+ if (!g_file_test (target_path, G_FILE_TEST_IS_EXECUTABLE))
+ continue;
+
+ /* generate a .desktop file for the executable file */
+ g_snprintf (source_path, 4096, "%s.desktop", target_path);
+ if (!g_file_test (source_path, G_FILE_TEST_IS_REGULAR))
+ {
+ fp = fopen (source_path, "w");
+ if (G_LIKELY (fp != NULL))
+ {
+ fprintf (fp,
+ "# This file was automatically generated for the autostart\n"
+ "# item %s\n"
+ "[Desktop Entry]\n"
+ "Type=Application\n"
+ "Exec=%s\n"
+ "Hidden=False\n"
+ "Terminal=False\n"
+ "StartupNotify=False\n"
+ "Version=0.9.4\n"
+ "Name=%s\n",
+ entry, target_path, entry);
+ fclose (fp);
+ }
+ else
+ {
+ g_warning ("Failed to create a .desktop file for %s: %s",
+ target_path, g_strerror (errno));
+ }
+ }
+ }
+
+ /* create the LOCATION-CHANGED.txt file to let the user know */
+ g_snprintf (source_path, 4096, "%s/LOCATION-CHANGED.txt", source);
+ fp = fopen (source_path, "w");
+ if (G_LIKELY (fp != NULL))
+ {
+ g_fprintf (fp, _("The location and the format of the autostart directory has changed.\n"
+ "The new location is\n"
+ "\n"
+ " %s\n"
+ "\n"
+ "where you can place .desktop files to, that describe the applications\n"
+ "to start when you login to your Xfce desktop. The files in your old\n"
+ "autostart directory have been successfully migrated to the new\n"
+ "location.\n"
+ "You should delete this directory now.\n"), target);
+ fclose (fp);
+ }
+
+ g_free (target);
+ }
+
+ g_dir_close (dp);
+ }
+}
+
+
+
+static gint
+xfsm_startup_autostart_xdg (XfsmManager *manager,
+ gboolean start_at_spi)
+{
+ const gchar *try_exec;
+ const gchar *type;
+ const gchar *exec;
+ gboolean startup_notify;
+ gboolean terminal;
+ gboolean skip;
+ GError *error = NULL;
+ XfceRc *rc;
+ gchar **files;
+ gchar **only_show_in;
+ gchar **not_show_in;
+ gint started = 0;
+ gint n, m;
+ gchar *filename;
+ const gchar *pattern;
+
+ /* migrate the old autostart location (if still present) */
+ xfsm_startup_autostart_migrate ();
+
+ /* pattern for only at-spi desktop files or everything */
+ if (start_at_spi)
+ pattern = "autostart/at-spi-*.desktop";
+ else
+ pattern = "autostart/*.desktop";
+
+ files = xfce_resource_match (XFCE_RESOURCE_CONFIG, pattern, TRUE);
+ for (n = 0; files[n] != NULL; ++n)
+ {
+ rc = xfce_rc_config_open (XFCE_RESOURCE_CONFIG, files[n], TRUE);
+ if (G_UNLIKELY (rc == NULL))
+ continue;
+
+ xfce_rc_set_group (rc, "Desktop Entry");
+
+ /* check the Hidden key */
+ skip = xfce_rc_read_bool_entry (rc, "Hidden", FALSE);
+ if (G_LIKELY (!skip))
+ {
+ xfsm_verbose("hidden set\n");
+
+ if (xfce_rc_read_bool_entry (rc, "X-XFCE-Autostart-Override", FALSE))
+ {
+ /* override the OnlyShowIn check */
+ skip = FALSE;
+ xfsm_verbose ("X-XFCE-Autostart-Override set, launching\n");
+ }
+ else
+ {
+ /* check the OnlyShowIn setting */
+ only_show_in = xfce_rc_read_list_entry (rc, "OnlyShowIn", ";");
+ if (G_UNLIKELY (only_show_in != NULL))
+ {
+ /* check if "XFCE" is specified */
+ for (m = 0, skip = TRUE; only_show_in[m] != NULL; ++m)
+ {
+ if (g_ascii_strcasecmp (only_show_in[m], "XFCE") == 0)
+ {
+ skip = FALSE;
+ xfsm_verbose ("only show in XFCE set, launching\n");
+ break;
+ }
+ }
+
+ g_strfreev (only_show_in);
+ }
+ }
+
+ /* check the NotShowIn setting */
+ not_show_in = xfce_rc_read_list_entry (rc, "NotShowIn", ";");
+ if (G_UNLIKELY (not_show_in != NULL))
+ {
+ /* check if "Xfce" is not specified */
+ for (m = 0; not_show_in[m] != NULL; ++m)
+ if (g_ascii_strcasecmp (not_show_in[m], "XFCE") == 0)
+ {
+ skip = TRUE;
+ xfsm_verbose ("NotShowIn Xfce set, skipping\n");
+ break;
+ }
+
+ g_strfreev (not_show_in);
+ }
+
+ /* skip at-spi launchers if not in at-spi mode or don't skip
+ * them no matter what the OnlyShowIn key says if only
+ * launching at-spi */
+ filename = g_path_get_basename (files[n]);
+ if (g_str_has_prefix (filename, "at-spi-"))
+ {
+ skip = !start_at_spi;
+ xfsm_verbose ("start_at_spi (a11y support), %s\n", skip ? "skipping" : "showing");
+ }
+ g_free (filename);
+ }
+
+ /* check the "Type" key */
+ type = xfce_rc_read_entry (rc, "Type", NULL);
+ if (G_UNLIKELY (!skip && type != NULL && g_ascii_strcasecmp (type, "Application") != 0))
+ {
+ skip = TRUE;
+ xfsm_verbose ("Type == Application, skipping\n");
+ }
+
+ /* check the "TryExec" key */
+ try_exec = xfce_rc_read_entry (rc, "TryExec", NULL);
+ if (G_UNLIKELY (!skip && try_exec != NULL))
+ {
+ skip = !xfsm_check_valid_exec (try_exec);
+ if (skip)
+ xfsm_verbose ("TryExec set and xfsm_check_valid_exec failed, skipping\n");
+ }
+
+ /* execute the item */
+ exec = xfce_rc_read_entry (rc, "Exec", NULL);
+ if (G_LIKELY (!skip && exec != NULL))
+ {
+ /* query launch parameters */
+ startup_notify = xfce_rc_read_bool_entry (rc, "StartupNotify", FALSE);
+ terminal = xfce_rc_read_bool_entry (rc, "Terminal", FALSE);
+
+ /* try to launch the command */
+ xfsm_verbose ("Autostart: running command \"%s\"\n", exec);
+ if (!xfce_spawn_command_line_on_screen (gdk_screen_get_default (),
+ exec,
+ terminal,
+ startup_notify,
+ &error))
+ {
+ g_warning ("Unable to launch \"%s\" (specified by %s): %s", exec, files[n], error->message);
+ xfsm_verbose ("Unable to launch \"%s\" (specified by %s): %s\n", exec, files[n], error->message);
+ g_error_free (error);
+ error = NULL;
+ }
+ else
+ {
+ ++started;
+ }
+ }
+
+ /* cleanup */
+ xfce_rc_close (rc);
+ }
+ g_strfreev (files);
+
+ return started;
+}
+
+
+
+static void
+xfsm_startup_autostart (XfsmManager *manager)
+{
+ gint n;
+
+ n = xfsm_startup_autostart_xdg (manager, FALSE);
+
+ if (n > 0)
+ {
+ if (G_LIKELY (splash_screen != NULL))
+ xfsm_splash_screen_next (splash_screen, _("Performing Autostart..."));
+
+ g_timeout_add (2000, destroy_splash, NULL);
+ }
+ else
+ {
+ g_timeout_add (1000, destroy_splash, NULL);
+ }
+}
+
+
+
+void
+xfsm_startup_foreign (XfsmManager *manager)
+{
+ if (xfsm_manager_get_compat_startup(manager, XFSM_MANAGER_COMPAT_KDE))
+ xfsm_compat_kde_startup (splash_screen);
+
+ if (xfsm_manager_get_compat_startup(manager, XFSM_MANAGER_COMPAT_GNOME))
+ xfsm_compat_gnome_startup (splash_screen);
+}
+
+
+static void
+xfsm_startup_at_set_gtk_modules (void)
+{
+ const gchar *old;
+ gchar **modules;
+ guint i;
+ gboolean found_gail = FALSE;
+ gboolean found_atk_bridge = FALSE;
+ GString *new;
+
+ old = g_getenv ("GTK_MODULES");
+ if (old != NULL && *old != '\0')
+ {
+ /* check which modules are already loaded */
+ modules = g_strsplit (old, ":", -1);
+ for (i = 0; modules[i] != NULL; i++)
+ {
+ if (strcmp (modules[i], "gail") == 0)
+ found_gail = TRUE;
+ else if (strcmp (modules[i], "atk-bridge") == 0)
+ found_atk_bridge = TRUE;
+ }
+ g_strfreev (modules);
+
+ if (!found_gail || !found_atk_bridge)
+ {
+ /* append modules to old value */
+ new = g_string_new (old);
+ if (!found_gail)
+ new = g_string_append (new, ":gail");
+ if (!found_atk_bridge)
+ new = g_string_append (new, ":atk-bridge");
+
+ g_setenv ("GTK_MODULES", new->str, TRUE);
+ g_string_free (new, TRUE);
+ }
+ }
+ else
+ {
+ g_setenv ("GTK_MODULES", "gail:atk-bridge", TRUE);
+ }
+}
+
+
+static gboolean
+xfsm_startup_at_spi_ior_set (void)
+{
+ Atom AT_SPI_IOR;
+ GdkDisplay *display;
+ Atom actual_type;
+ gint actual_format;
+ guchar *data = NULL;
+ gulong nitems;
+ gulong leftover;
+
+ display = gdk_display_get_default ();
+ AT_SPI_IOR = XInternAtom (GDK_DISPLAY_XDISPLAY (display), "AT_SPI_IOR", False);
+ XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
+ XDefaultRootWindow (GDK_DISPLAY_XDISPLAY (display)),
+ AT_SPI_IOR, 0L,
+ (long) BUFSIZ, False,
+ (Atom) 31, &actual_type, &actual_format,
+ &nitems, &leftover, &data);
+
+ if (data == NULL)
+ return FALSE;
+ XFree (data);
+
+ return TRUE;
+}
+
+
+static void
+xfsm_startup_at (XfsmManager *manager)
+{
+ gint n, i;
+
+ /* start at-spi-dbus-bus and/or at-spi-registryd */
+ n = xfsm_startup_autostart_xdg (manager, TRUE);
+
+ if (n > 0)
+ {
+ if (G_LIKELY (splash_screen != NULL))
+ xfsm_splash_screen_next (splash_screen, _("Starting Assistive Technologies"));
+
+ xfsm_startup_at_set_gtk_modules ();
+
+ /* wait for 2 seconds until the at-spi registered, not very nice
+ * but required to properly start an accessible desktop */
+ for (i = 0; i < 10; i++)
+ {
+ if (xfsm_startup_at_spi_ior_set ())
+ break;
+ xfsm_verbose ("Waiting for at-spi to register...\n");
+ g_usleep (G_USEC_PER_SEC / 5);
+ }
+ }
+ else
+ {
+ g_warning ("No assistive technology service provider was started!");
+ }
+}
+
+
+void
+xfsm_startup_begin (XfsmManager *manager)
+{
+ /* start assistive technology before anything else */
+ if (xfsm_manager_get_start_at (manager))
+ xfsm_startup_at (manager);
+
+ if (xfsm_manager_get_use_failsafe_mode (manager))
+ {
+ xfsm_startup_failsafe (manager);
+ xfsm_startup_autostart (manager);
+ xfsm_manager_signal_startup_done (manager);
+ }
+ else
+ {
+ xfsm_startup_session_continue (manager);
+ }
+}
+
+
+static void
+xfsm_startup_failsafe (XfsmManager *manager)
+{
+ GQueue *failsafe_clients = xfsm_manager_get_queue (manager, XFSM_MANAGER_QUEUE_FAILSAFE_CLIENTS);
+ FailsafeClient *fclient;
+
+ while ((fclient = g_queue_pop_head (failsafe_clients)))
+ {
+ /* FIXME: splash */
+ /* let the user know whats going on */
+ if (G_LIKELY (splash_screen != NULL))
+ {
+ xfsm_splash_screen_next (splash_screen,
+ figure_app_name (fclient->command[0]));
+ }
+
+ /* start the application */
+ xfsm_start_application (fclient->command, NULL, fclient->screen,
+ NULL, NULL, NULL);
+ xfsm_failsafe_client_free (fclient);
+ }
+}
+
+
+gboolean
+xfsm_startup_start_properties (XfsmProperties *properties,
+ XfsmManager *manager)
+{
+ XfsmStartupData *child_watch_data;
+ XfsmStartupData *startup_timeout_data;
+ gchar **restart_command;
+ gchar **argv;
+ gint argc;
+ gint n;
+ const gchar *current_directory;
+ GPid pid;
+ GError *error = NULL;
+
+ /* release any possible old resources related to a previous startup */
+ xfsm_properties_set_default_child_watch (properties);
+
+ /* generate the argument vector for the application (expanding variables) */
+ restart_command = xfsm_properties_get_strv (properties, SmRestartCommand);
+ argc = g_strv_length (restart_command);
+ argv = g_new (gchar *, argc + 1);
+ for (n = 0; n < argc; ++n)
+ argv[n] = xfce_expand_variables (restart_command[n], NULL);
+ argv[n] = NULL;
+
+ current_directory = xfsm_properties_get_string (properties, SmCurrentDirectory);
+
+ if (!g_spawn_async (current_directory,
+ argv, NULL,
+ G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH,
+ NULL, NULL,
+ &pid, &error))
+ {
+ g_warning ("Unable to launch \"%s\": %s",
+ *argv, error->message);
+ g_error_free (error);
+ g_strfreev (argv);
+
+ return FALSE;
+ }
+
+ /* Don't waste time if we're not debugging, but if we are print the
+ * command + the arguments */
+ if (xfsm_is_verbose_enabled ())
+ {
+ gchar *command = g_strjoinv (" ", argv);
+ xfsm_verbose ("Launched command \"%s\" with PID %d\n", command, (gint) pid);
+ g_free (command);
+ }
+
+ g_strfreev (argv);
+
+ properties->pid = pid;
+
+ /* set a watch to make sure the child doesn't quit before registering */
+ child_watch_data = g_new0 (XfsmStartupData, 1);
+ child_watch_data->manager = g_object_ref (manager);
+ child_watch_data->properties = properties;
+ child_watch_data->properties->child_watch_id =
+ g_child_watch_add_full (G_PRIORITY_LOW, properties->pid,
+ xfsm_startup_child_watch, child_watch_data,
+ (GDestroyNotify) xfsm_startup_data_free);
+
+ /* set a timeout -- client must register in a a certain amount of time
+ * or it's assumed to be broken/have issues. */
+ startup_timeout_data = g_new (XfsmStartupData, 1);
+ startup_timeout_data->manager = g_object_ref (manager);
+ startup_timeout_data->properties = properties;
+ properties->startup_timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT,
+ STARTUP_TIMEOUT,
+ xfsm_startup_timeout,
+ startup_timeout_data,
+ (GDestroyNotify) xfsm_startup_data_free);
+
+ return TRUE;
+}
+
+
+void
+xfsm_startup_session_continue (XfsmManager *manager)
+{
+ GQueue *pending_properties = xfsm_manager_get_queue (manager, XFSM_MANAGER_QUEUE_PENDING_PROPS);
+ gboolean client_started = FALSE;
+
+ /* try to start some clients. if we fail to start anything in the current
+ * priority group, move right to the next one. if we *did* start something,
+ * the failed/registered handlers will take care of moving us on to the
+ * next priority group */
+ while (client_started == FALSE && g_queue_peek_head (pending_properties) != NULL)
+ client_started = xfsm_startup_session_next_prio_group (manager);
+
+ if (G_UNLIKELY (client_started == FALSE && g_queue_peek_head (pending_properties) == NULL))
+ {
+ /* we failed to start anything, and we don't have anything else,
+ * to start, so just move on to the autostart items and signal
+ * the manager that we're finished */
+ xfsm_verbose ("Nothing started and nothing to start, moving to autostart items\n");
+ xfsm_startup_autostart (manager);
+ xfsm_manager_signal_startup_done (manager);
+ }
+}
+
+
+/* returns TRUE if we started anything, FALSE if we didn't */
+static gboolean
+xfsm_startup_session_next_prio_group (XfsmManager *manager)
+{
+ GQueue *pending_properties = xfsm_manager_get_queue (manager, XFSM_MANAGER_QUEUE_PENDING_PROPS);
+ GQueue *starting_properties = xfsm_manager_get_queue (manager, XFSM_MANAGER_QUEUE_STARTING_PROPS);
+ XfsmProperties *properties;
+ gint cur_prio_group;
+ gboolean client_started = FALSE;
+
+ properties = (XfsmProperties *) g_queue_peek_head (pending_properties);
+ if (properties == NULL)
+ return FALSE;
+
+ cur_prio_group = xfsm_properties_get_uchar (properties, GsmPriority, 50);
+
+ xfsm_verbose ("Starting apps in prio group %d\n", cur_prio_group);
+
+ while ((properties = g_queue_pop_head (pending_properties)))
+ {
+ /* quit if we've hit all the clients in the current prio group */
+ if (xfsm_properties_get_uchar (properties, GsmPriority, 50) != cur_prio_group)
+ {
+ /* we're not starting this one yet; put it back */
+ g_queue_push_head (pending_properties, properties);
+ break;
+ }
+
+ /* FIXME: splash */
+ if (G_LIKELY (splash_screen != NULL))
+ {
+ const gchar *app_name = NULL;
+ const gchar *desktop_file;
+ XfceRc *rcfile = NULL;
+
+ desktop_file = xfsm_properties_get_string (properties, GsmDesktopFile);
+
+ if (desktop_file)
+ {
+ rcfile = xfce_rc_simple_open (desktop_file, TRUE);
+ if (rcfile)
+ {
+ xfce_rc_set_group (rcfile, "Desktop Entry");
+ app_name = xfce_rc_read_entry (rcfile, "Name", NULL);
+ }
+ }
+
+ if (!app_name)
+ app_name = figure_app_name (xfsm_properties_get_string (properties,
+ SmProgram));
+
+ xfsm_splash_screen_next (splash_screen, app_name);
+
+ if (rcfile)
+ {
+ /* delay closing because app_name belongs to the rcfile
+ * if we found it in the file */
+ xfce_rc_close (rcfile);
+ }
+ }
+
+ if (G_LIKELY (xfsm_startup_start_properties (properties, manager)))
+ {
+ g_queue_push_tail (starting_properties, properties);
+ client_started = TRUE;
+ xfsm_verbose ("client id %s started\n", properties->client_id);
+ }
+ else
+ {
+ /* if starting the app failed, let the manager handle it */
+ if (xfsm_manager_handle_failed_properties (manager, properties) == FALSE)
+ xfsm_properties_free (properties);
+ }
+ }
+
+ return client_started;
+}
+
+
+static void
+xfsm_startup_data_free (XfsmStartupData *sdata)
+{
+ g_object_unref (sdata->manager);
+ g_free (sdata);
+}
+
+
+static void
+xfsm_startup_child_watch (GPid pid,
+ gint status,
+ gpointer user_data)
+{
+ XfsmStartupData *cwdata = user_data;
+ GQueue *starting_properties;
+
+ xfsm_verbose ("Client Id = %s, PID %d exited with status %d\n",
+ cwdata->properties->client_id, (gint)pid, status);
+
+ cwdata->properties->child_watch_id = 0;
+ cwdata->properties->pid = -1;
+
+ starting_properties = xfsm_manager_get_queue (cwdata->manager, XFSM_MANAGER_QUEUE_STARTING_PROPS);
+ if (g_queue_find (starting_properties, cwdata->properties) != NULL)
+ {
+ xfsm_verbose ("Client Id = %s died while starting up\n",
+ cwdata->properties->client_id);
+ xfsm_startup_handle_failed_startup (cwdata->properties, cwdata->manager);
+ }
+
+ /* NOTE: cwdata->properties could have been freed by
+ * xfsm_startup_handle_failed_startup() above, so don't try to access
+ * any of its members here. */
+
+ g_spawn_close_pid (pid);
+}
+
+
+static gboolean
+xfsm_startup_timeout (gpointer data)
+{
+ XfsmStartupData *stdata = data;
+
+ xfsm_verbose ("Client Id = %s failed to register in time\n",
+ stdata->properties->client_id);
+
+ stdata->properties->startup_timeout_id = 0;
+ xfsm_startup_handle_failed_startup (stdata->properties, stdata->manager);
+
+ return FALSE;
+}
+
+
+static void
+xfsm_startup_handle_failed_startup (XfsmProperties *properties,
+ XfsmManager *manager)
+{
+ GQueue *starting_properties = xfsm_manager_get_queue (manager, XFSM_MANAGER_QUEUE_STARTING_PROPS);
+
+ xfsm_verbose ("Client Id = %s failed to start\n", properties->client_id);
+
+ /* if our timer hasn't run out yet, kill it */
+ if (properties->startup_timeout_id > 0)
+ {
+ g_source_remove (properties->startup_timeout_id);
+ properties->startup_timeout_id = 0;
+ }
+
+ xfsm_properties_set_default_child_watch (properties);
+
+ /* not starting anymore, so remove it from the list. tell the manager
+ * it failed, and let it do its thing. */
+ g_queue_remove (starting_properties, properties);
+ if (xfsm_manager_handle_failed_properties (manager, properties) == FALSE)
+ xfsm_properties_free (properties);
+
+ if (g_queue_peek_head (starting_properties) == NULL
+ && xfsm_manager_get_state (manager) == XFSM_MANAGER_STARTUP)
+ {
+ /* everything has finished starting or failed; continue startup */
+ xfsm_startup_session_continue (manager);
+ }
+}
+
+
diff --git a/xfce4-session/xfsm-startup.h b/xfce4-session/xfsm-startup.h
new file mode 100644
index 0000000..03762e0
--- /dev/null
+++ b/xfce4-session/xfsm-startup.h
@@ -0,0 +1,38 @@
+/* $Id$ */
+/*-
+ * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2008 Brian Tarricone <bjt23@cornell.edu>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifndef __XFSM_STARTUP_H__
+#define __XFSM_STARTUP_H__
+
+#include <xfconf/xfconf.h>
+#include <libxfce4util/libxfce4util.h>
+
+void xfsm_startup_init (XfconfChannel *channel);
+void xfsm_startup_shutdown (void);
+void xfsm_startup_foreign (XfsmManager *manager);
+void xfsm_startup_begin (XfsmManager *manager);
+void xfsm_startup_session_continue (XfsmManager *manager);
+gboolean xfsm_startup_start_properties (XfsmProperties *properties,
+ XfsmManager *manager);
+
+#endif /* !__XFSM_STARTUP_H__ */
+
diff --git a/xfce4-session/xfsm-systemd.c b/xfce4-session/xfsm-systemd.c
new file mode 100644
index 0000000..8f80873
--- /dev/null
+++ b/xfce4-session/xfsm-systemd.c
@@ -0,0 +1,325 @@
+/*-
+ * Copyright (C) 2012 Christian Hesse
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#include <config.h>
+
+#include <gio/gio.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#ifdef HAVE_POLKIT
+#include <polkit/polkit.h>
+#endif
+
+#include <libxfsm/xfsm-util.h>
+#include <xfce4-session/xfsm-systemd.h>
+
+
+
+#define SYSTEMD_DBUS_NAME "org.freedesktop.login1"
+#define SYSTEMD_DBUS_PATH "/org/freedesktop/login1"
+#define SYSTEMD_DBUS_INTERFACE "org.freedesktop.login1.Manager"
+#define SYSTEMD_REBOOT_ACTION "Reboot"
+#define SYSTEMD_POWEROFF_ACTION "PowerOff"
+#define SYSTEMD_SUSPEND_ACTION "Suspend"
+#define SYSTEMD_HIBERNATE_ACTION "Hibernate"
+#define SYSTEMD_REBOOT_TEST "org.freedesktop.login1.reboot"
+#define SYSTEMD_POWEROFF_TEST "org.freedesktop.login1.power-off"
+#define SYSTEMD_SUSPEND_TEST "org.freedesktop.login1.suspend"
+#define SYSTEMD_HIBERNATE_TEST "org.freedesktop.login1.hibernate"
+
+
+
+static void xfsm_systemd_finalize (GObject *object);
+
+
+
+struct _XfsmSystemdClass
+{
+ GObjectClass __parent__;
+};
+
+struct _XfsmSystemd
+{
+ GObject __parent__;
+#ifdef HAVE_POLKIT
+ PolkitAuthority *authority;
+ PolkitSubject *subject;
+#endif
+};
+
+
+
+G_DEFINE_TYPE (XfsmSystemd, xfsm_systemd, G_TYPE_OBJECT)
+
+
+
+static void
+xfsm_systemd_class_init (XfsmSystemdClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = xfsm_systemd_finalize;
+}
+
+
+
+static void
+xfsm_systemd_init (XfsmSystemd *systemd)
+{
+#ifdef HAVE_POLKIT
+ systemd->authority = polkit_authority_get_sync (NULL, NULL);
+ systemd->subject = polkit_unix_process_new_for_owner (getpid(), 0, -1);
+#endif
+}
+
+
+
+static void
+xfsm_systemd_finalize (GObject *object)
+{
+#ifdef HAVE_POLKIT
+ XfsmSystemd *systemd = XFSM_SYSTEMD (object);
+
+ g_object_unref (G_OBJECT (systemd->authority));
+ g_object_unref (G_OBJECT (systemd->subject));
+#endif
+
+ (*G_OBJECT_CLASS (xfsm_systemd_parent_class)->finalize) (object);
+}
+
+
+
+static gboolean
+xfsm_systemd_lock_screen (GError **error)
+{
+ XfconfChannel *channel;
+ gboolean ret = TRUE;
+
+ channel = xfsm_open_config ();
+ if (xfconf_channel_get_bool (channel, "/shutdown/LockScreen", FALSE))
+ ret = g_spawn_command_line_async ("xflock4", error);
+
+ return ret;
+}
+
+
+
+static gboolean
+xfsm_systemd_can_method (XfsmSystemd *systemd,
+ gboolean *can_method,
+ const gchar *method,
+ GError **error)
+{
+#ifdef HAVE_POLKIT
+ PolkitAuthorizationResult *res;
+ GError *local_error = NULL;
+#endif
+
+ *can_method = FALSE;
+
+#ifdef HAVE_POLKIT
+ res = polkit_authority_check_authorization_sync (systemd->authority,
+ systemd->subject,
+ method,
+ NULL,
+ POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE,
+ NULL,
+ &local_error);
+
+ if (res == NULL)
+ {
+ g_propagate_error (error, local_error);
+ return FALSE;
+ }
+
+ *can_method = polkit_authorization_result_get_is_authorized (res)
+ || polkit_authorization_result_get_is_challenge (res);
+
+ g_object_unref (G_OBJECT (res));
+#endif
+
+ return TRUE;
+}
+
+
+
+static gboolean
+xfsm_systemd_try_method (XfsmSystemd *systemd,
+ const gchar *method,
+ GError **error)
+{
+ GDBusConnection *bus;
+ GError *local_error = NULL;
+
+ bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error);
+ if (G_UNLIKELY (bus == NULL))
+ return FALSE;
+
+ g_dbus_connection_call_sync (bus,
+ SYSTEMD_DBUS_NAME,
+ SYSTEMD_DBUS_PATH,
+ SYSTEMD_DBUS_INTERFACE,
+ method,
+ g_variant_new ("(b)", TRUE),
+ NULL, 0, G_MAXINT, NULL,
+ &local_error);
+
+ g_object_unref (G_OBJECT (bus));
+
+ if (local_error != NULL)
+ {
+ g_propagate_error (error, local_error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+
+XfsmSystemd *
+xfsm_systemd_get (void)
+{
+ static XfsmSystemd *object = NULL;
+
+ if (G_LIKELY (object != NULL))
+ {
+ g_object_ref (G_OBJECT (object));
+ }
+ else
+ {
+ object = g_object_new (XFSM_TYPE_SYSTEMD, NULL);
+ g_object_add_weak_pointer (G_OBJECT (object), (gpointer) &object);
+ }
+
+ return object;
+}
+
+
+
+gboolean
+xfsm_systemd_try_restart (XfsmSystemd *systemd,
+ GError **error)
+{
+ return xfsm_systemd_try_method (systemd,
+ SYSTEMD_REBOOT_ACTION,
+ error);
+}
+
+
+
+gboolean
+xfsm_systemd_try_shutdown (XfsmSystemd *systemd,
+ GError **error)
+{
+ return xfsm_systemd_try_method (systemd,
+ SYSTEMD_POWEROFF_ACTION,
+ error);
+}
+
+
+
+gboolean
+xfsm_systemd_try_suspend (XfsmSystemd *systemd,
+ GError **error)
+{
+ if (!xfsm_systemd_lock_screen (error))
+ return FALSE;
+
+ return xfsm_systemd_try_method (systemd,
+ SYSTEMD_SUSPEND_ACTION,
+ error);
+}
+
+
+
+gboolean
+xfsm_systemd_try_hibernate (XfsmSystemd *systemd,
+ GError **error)
+{
+ if (!xfsm_systemd_lock_screen (error))
+ return FALSE;
+
+ return xfsm_systemd_try_method (systemd,
+ SYSTEMD_HIBERNATE_ACTION,
+ error);
+}
+
+
+
+gboolean
+xfsm_systemd_can_restart (XfsmSystemd *systemd,
+ gboolean *can_restart,
+ GError **error)
+{
+ return xfsm_systemd_can_method (systemd,
+ can_restart,
+ SYSTEMD_REBOOT_TEST,
+ error);
+}
+
+
+
+gboolean
+xfsm_systemd_can_shutdown (XfsmSystemd *systemd,
+ gboolean *can_shutdown,
+ GError **error)
+{
+ return xfsm_systemd_can_method (systemd,
+ can_shutdown,
+ SYSTEMD_POWEROFF_TEST,
+ error);
+}
+
+
+
+gboolean
+xfsm_systemd_can_suspend (XfsmSystemd *systemd,
+ gboolean *can_suspend,
+ gboolean *auth_suspend,
+ GError **error)
+{
+ gboolean ret = FALSE;
+
+ ret = xfsm_systemd_can_method (systemd,
+ can_suspend,
+ SYSTEMD_SUSPEND_TEST,
+ error);
+ *auth_suspend = *can_suspend;
+ return ret;
+}
+
+
+
+gboolean
+xfsm_systemd_can_hibernate (XfsmSystemd *systemd,
+ gboolean *can_hibernate,
+ gboolean *auth_hibernate,
+ GError **error)
+{
+ gboolean ret = FALSE;
+
+ ret = xfsm_systemd_can_method (systemd,
+ can_hibernate,
+ SYSTEMD_HIBERNATE_TEST,
+ error);
+ *auth_hibernate = *can_hibernate;
+ return ret;
+}
diff --git a/xfce4-session/xfsm-systemd.h b/xfce4-session/xfsm-systemd.h
new file mode 100644
index 0000000..c5e74b5
--- /dev/null
+++ b/xfce4-session/xfsm-systemd.h
@@ -0,0 +1,73 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2012 Christian Hesse
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __XFSM_SYSTEMD_H__
+#define __XFSM_SYSTEMD_H__
+
+#define LOGIND_RUNNING() (access ("/run/systemd/seats/", F_OK) >= 0)
+
+typedef struct _XfsmSystemdClass XfsmSystemdClass;
+typedef struct _XfsmSystemd XfsmSystemd;
+
+#define XFSM_TYPE_SYSTEMD (xfsm_systemd_get_type ())
+#define XFSM_SYSTEMD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFSM_TYPE_SYSTEMD, XfsmSystemd))
+#define XFSM_SYSTEMD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFSM_TYPE_SYSTEMD, XfsmSystemdClass))
+#define XFSM_IS_SYSTEMD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFSM_TYPE_SYSTEMD))
+#define XFSM_IS_SYSTEMD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFSM_TYPE_SYSTEMD))
+#define XFSM_SYSTEMD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XFSM_TYPE_SYSTEMD, XfsmSystemdClass))
+
+GType xfsm_systemd_get_type (void) G_GNUC_CONST;
+
+XfsmSystemd *xfsm_systemd_get (void);
+
+gboolean xfsm_systemd_try_restart (XfsmSystemd *systemd,
+ GError **error);
+
+gboolean xfsm_systemd_try_shutdown (XfsmSystemd *systemd,
+ GError **error);
+
+gboolean xfsm_systemd_try_suspend (XfsmSystemd *systemd,
+ GError **error);
+
+gboolean xfsm_systemd_try_hibernate (XfsmSystemd *systemd,
+ GError **error);
+
+gboolean xfsm_systemd_can_restart (XfsmSystemd *systemd,
+ gboolean *can_restart,
+ GError **error);
+
+gboolean xfsm_systemd_can_shutdown (XfsmSystemd *systemd,
+ gboolean *can_shutdown,
+ GError **error);
+
+gboolean xfsm_systemd_can_suspend (XfsmSystemd *systemd,
+ gboolean *can_suspend,
+ gboolean *auth_suspend,
+ GError **error);
+
+gboolean xfsm_systemd_can_hibernate (XfsmSystemd *systemd,
+ gboolean *can_hibernate,
+ gboolean *auth_hibernate,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __XFSM_SYSTEMD_H__ */
diff --git a/xfce4-session/xfsm-upower.c b/xfce4-session/xfsm-upower.c
new file mode 100644
index 0000000..050872a
--- /dev/null
+++ b/xfce4-session/xfsm-upower.c
@@ -0,0 +1,423 @@
+/*-
+ * Copyright (c) 2011 Nick Schermer <nick@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#ifdef HAVE_UPOWER
+#include <upower.h>
+#endif /* HAVE_UPOWER */
+
+#include <libxfsm/xfsm-util.h>
+#include <xfce4-session/xfsm-upower.h>
+
+
+
+#define UPOWER_NAME "org.freedesktop.UPower"
+#define UPOWER_PATH "/org/freedesktop/UPower"
+#define UPOWER_INTERFACE UPOWER_NAME
+
+
+
+static void xfsm_upower_finalize (GObject *object);
+static gboolean xfsm_upower_proxy_ensure (XfsmUPower *upower,
+ GError **error);
+static void xfsm_upower_proxy_free (XfsmUPower *upower);
+
+
+
+struct _XfsmUPowerClass
+{
+ GObjectClass __parent__;
+};
+
+struct _XfsmUPower
+{
+ GObject __parent__;
+
+ DBusGConnection *dbus_conn;
+ DBusGProxy *upower_proxy;
+ DBusGProxy *props_proxy;
+};
+
+
+
+G_DEFINE_TYPE (XfsmUPower, xfsm_upower, G_TYPE_OBJECT)
+
+
+
+static void
+xfsm_upower_class_init (XfsmUPowerClass *klass)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = xfsm_upower_finalize;
+}
+
+
+
+static void
+xfsm_upower_init (XfsmUPower *upower)
+{
+}
+
+
+
+static void
+xfsm_upower_finalize (GObject *object)
+{
+ xfsm_upower_proxy_free (XFSM_UPOWER (object));
+
+ (*G_OBJECT_CLASS (xfsm_upower_parent_class)->finalize) (object);
+}
+
+
+
+static gboolean
+xfsm_upower_proxy_ensure (XfsmUPower *upower,
+ GError **error)
+{
+ GError *err = NULL;
+ DBusConnection *connection;
+
+ if (upower->dbus_conn == NULL)
+ {
+ upower->dbus_conn = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err);
+ if (upower->dbus_conn == NULL)
+ goto error1;
+
+ connection = dbus_g_connection_get_connection (upower->dbus_conn);
+ dbus_connection_set_exit_on_disconnect (connection, FALSE);
+ }
+
+ if (upower->upower_proxy == NULL)
+ {
+ upower->upower_proxy = dbus_g_proxy_new_for_name (upower->dbus_conn,
+ UPOWER_NAME,
+ UPOWER_PATH,
+ UPOWER_INTERFACE);
+ if (upower->upower_proxy == NULL)
+ {
+ g_set_error (&err, DBUS_GERROR, DBUS_GERROR_FAILED,
+ "Failed to get proxy for %s",
+ UPOWER_NAME);
+ goto error1;
+ }
+ }
+
+ if (upower->props_proxy == NULL)
+ {
+ upower->props_proxy = dbus_g_proxy_new_for_name (upower->dbus_conn,
+ UPOWER_NAME,
+ UPOWER_PATH,
+ DBUS_INTERFACE_PROPERTIES);
+ if (upower->props_proxy == NULL)
+ {
+ g_set_error (&err, DBUS_GERROR, DBUS_GERROR_FAILED,
+ "Failed to get proxy for %s properties",
+ UPOWER_NAME);
+ goto error1;
+ }
+ }
+
+ return TRUE;
+
+ error1:
+
+ g_propagate_error (error, err);
+ xfsm_upower_proxy_free (upower);
+
+ return FALSE;
+}
+
+
+
+static void
+xfsm_upower_proxy_free (XfsmUPower *upower)
+{
+ if (upower->upower_proxy != NULL)
+ {
+ g_object_unref (G_OBJECT (upower->upower_proxy));
+ upower->upower_proxy = NULL;
+ }
+
+ if (upower->props_proxy != NULL)
+ {
+ g_object_unref (G_OBJECT (upower->props_proxy));
+ upower->props_proxy = NULL;
+ }
+
+ if (upower->dbus_conn != NULL)
+ {
+ dbus_g_connection_unref (upower->dbus_conn);
+ upower->dbus_conn = NULL;
+ }
+}
+
+
+
+static gboolean
+xfsm_upower_get_property (XfsmUPower *upower,
+ const gchar *prop_name,
+ gboolean *bool_return,
+ GError **error)
+{
+ GValue val = { 0, };
+ gboolean succeed;
+
+ succeed = dbus_g_proxy_call (upower->props_proxy, "Get",
+ error,
+ G_TYPE_STRING, UPOWER_INTERFACE,
+ G_TYPE_STRING, prop_name,
+ G_TYPE_INVALID,
+ G_TYPE_VALUE, &val,
+ G_TYPE_INVALID);
+
+ if (succeed)
+ {
+ g_assert (G_VALUE_HOLDS_BOOLEAN (&val));
+ *bool_return = g_value_get_boolean (&val);
+ }
+ else
+ {
+ *bool_return = FALSE;
+ }
+
+ return succeed;
+}
+
+
+
+static gboolean
+xfsm_upower_can_method (XfsmUPower *upower,
+ const gchar *can_property, /* if the system is capable */
+ gboolean *can_return,
+ const gchar *auth_method, /* if the user is allowed */
+ gboolean *auth_return,
+ GError **error)
+{
+ g_return_val_if_fail (can_return != NULL, FALSE);
+ g_return_val_if_fail (auth_return != NULL, FALSE);
+
+ /* never return true if something fails */
+ *can_return = FALSE;
+ *auth_return = FALSE;
+
+ if (!xfsm_upower_proxy_ensure (upower, error))
+ return FALSE;
+
+ if (xfsm_upower_get_property (upower, can_property, can_return, error))
+ {
+ if (*can_return)
+ {
+ /* check authentication if system is capable of this action */
+ return dbus_g_proxy_call (upower->upower_proxy, auth_method,
+ error, G_TYPE_INVALID,
+ G_TYPE_BOOLEAN, auth_return,
+ G_TYPE_INVALID);
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+
+static void
+xfsm_upower_try_method_cb (DBusGProxy *proxy,
+ DBusGProxyCall *call,
+ gpointer user_data)
+{
+ GError *error = NULL;
+
+ if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID, G_TYPE_INVALID))
+ {
+ if (g_error_matches (error, DBUS_GERROR, DBUS_GERROR_NO_REPLY))
+ g_message ("Reply after suspend/hibernate timed out. Continuing...");
+ else
+ g_warning ("Failed to suspend the system: %s", error->message);
+
+ g_error_free (error);
+ }
+}
+
+
+
+static gboolean
+xfsm_upower_try_method (XfsmUPower *upower,
+ const gchar *method,
+ GError **error)
+{
+ DBusGProxyCall *call;
+
+ if (!xfsm_upower_proxy_ensure (upower, error))
+ return FALSE;
+
+ call = dbus_g_proxy_begin_call (upower->upower_proxy,
+ method,
+ xfsm_upower_try_method_cb,
+ upower,
+ NULL,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+
+ return call != NULL;
+}
+
+
+
+gboolean
+xfsm_upower_lock_screen (XfsmUPower *upower,
+ const gchar *sleep_kind,
+ GError **error)
+{
+ XfconfChannel *channel;
+ gboolean ret = TRUE;
+
+ g_return_val_if_fail (sleep_kind != NULL, FALSE);
+
+ channel = xfsm_open_config ();
+ if (xfconf_channel_get_bool (channel, "/shutdown/LockScreen", FALSE))
+ {
+ if (xfsm_upower_proxy_ensure (upower, error))
+ {
+#ifdef HAVE_UPOWER
+#if !UP_CHECK_VERSION(0, 99, 0)
+ GError *err = NULL;
+
+ /* tell upower we're going to sleep, this saves some
+ * time while we sleep 1 second if xflock4 is spawned */
+ ret = dbus_g_proxy_call (upower->upower_proxy,
+ "AboutToSleep", &err,
+ G_TYPE_STRING, sleep_kind,
+ G_TYPE_INVALID, G_TYPE_INVALID);
+
+ /* we don't abort on this, since it is not so critical */
+ if (!ret)
+ {
+ g_warning ("Couldn't sent that we were about to sleep: %s", err->message);
+ g_error_free (err);
+ }
+#endif /* UP_CHECK_VERSION */
+#endif /* HAVE_UPOWER */
+ }
+ else
+ {
+ /* proxy failed */
+ return FALSE;
+ }
+
+ ret = g_spawn_command_line_async ("xflock4", error);
+ if (ret)
+ {
+ /* sleep 1 second so locking has time to startup */
+ g_usleep (G_USEC_PER_SEC);
+ }
+ }
+
+ return ret;
+}
+
+
+
+XfsmUPower *
+xfsm_upower_get (void)
+{
+ static XfsmUPower *object = NULL;
+
+ if (G_LIKELY (object != NULL))
+ {
+ g_object_ref (G_OBJECT (object));
+ }
+ else
+ {
+ object = g_object_new (XFSM_TYPE_UPOWER, NULL);
+ g_object_add_weak_pointer (G_OBJECT (object), (gpointer) &object);
+ }
+
+ return object;
+}
+
+
+
+gboolean
+xfsm_upower_try_suspend (XfsmUPower *upower,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_UPOWER (upower), FALSE);
+
+ if (!xfsm_upower_lock_screen (upower, "suspend", error))
+ return FALSE;
+
+ return xfsm_upower_try_method (upower, "Suspend", error);
+}
+
+
+
+gboolean
+xfsm_upower_try_hibernate (XfsmUPower *upower,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_UPOWER (upower), FALSE);
+
+ if (!xfsm_upower_lock_screen (upower, "hibernate", error))
+ return FALSE;
+
+ return xfsm_upower_try_method (upower, "Hibernate", error);
+}
+
+
+
+gboolean
+xfsm_upower_can_suspend (XfsmUPower *upower,
+ gboolean *can_suspend,
+ gboolean *auth_suspend,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_UPOWER (upower), FALSE);
+
+ return xfsm_upower_can_method (upower,
+ "CanSuspend",
+ can_suspend,
+ "SuspendAllowed",
+ auth_suspend,
+ error);
+}
+
+
+
+gboolean
+xfsm_upower_can_hibernate (XfsmUPower *upower,
+ gboolean *can_hibernate,
+ gboolean *auth_hibernate,
+ GError **error)
+{
+ g_return_val_if_fail (XFSM_IS_UPOWER (upower), FALSE);
+
+ return xfsm_upower_can_method (upower,
+ "CanHibernate",
+ can_hibernate,
+ "HibernateAllowed",
+ auth_hibernate,
+ error);
+}
diff --git a/xfce4-session/xfsm-upower.h b/xfce4-session/xfsm-upower.h
new file mode 100644
index 0000000..4e6a53b
--- /dev/null
+++ b/xfce4-session/xfsm-upower.h
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 2011 Nick Schermer <nick@xfce.org>
+ * All rights reserved.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+
+#ifndef __XFSM_UPOWER_HELPER_H__
+#define __XFSM_UPOWER_HELPER_H__
+
+typedef struct _XfsmUPowerClass XfsmUPowerClass;
+typedef struct _XfsmUPower XfsmUPower;
+
+#define XFSM_TYPE_UPOWER (xfsm_upower_get_type ())
+#define XFSM_UPOWER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFSM_TYPE_UPOWER, XfsmUPower))
+#define XFSM_UPOWER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFSM_TYPE_UPOWER, XfsmUPowerClass))
+#define XFSM_IS_UPOWER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFSM_TYPE_UPOWER))
+#define XFSM_IS_UPOWER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFSM_TYPE_UPOWER))
+#define XFSM_UPOWER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XFSM_TYPE_UPOWER, XfsmUPowerClass))
+
+GType xfsm_upower_get_type (void) G_GNUC_CONST;
+
+XfsmUPower *xfsm_upower_get (void);
+
+gboolean xfsm_upower_try_suspend (XfsmUPower *upower,
+ GError **error);
+
+gboolean xfsm_upower_try_hibernate (XfsmUPower *upower,
+ GError **error);
+
+gboolean xfsm_upower_can_suspend (XfsmUPower *upower,
+ gboolean *can_suspend,
+ gboolean *auth_suspend,
+ GError **error);
+
+gboolean xfsm_upower_can_hibernate (XfsmUPower *upower,
+ gboolean *can_hibernate,
+ gboolean *auth_hibernate,
+ GError **error);
+
+gboolean xfsm_upower_lock_screen (XfsmUPower *upower,
+ const gchar *sleep_kind,
+ GError **error);
+
+#endif /* !__XFSM_UPOWER_HELPER_H__ */