summaryrefslogtreecommitdiff
path: root/mate-panel/libpanel-util
diff options
context:
space:
mode:
authorPerberos <[email protected]>2011-12-01 22:56:10 -0300
committerPerberos <[email protected]>2011-12-01 22:56:10 -0300
commitc51ef797a707f4e2c6f9688d4378f2b0e9898a66 (patch)
tree019ae92bb53c19b30077545cb14743cbd1b57aef /mate-panel/libpanel-util
downloadmate-panel-c51ef797a707f4e2c6f9688d4378f2b0e9898a66.tar.bz2
mate-panel-c51ef797a707f4e2c6f9688d4378f2b0e9898a66.tar.xz
moving from https://github.com/perberos/mate-desktop-environment
Diffstat (limited to 'mate-panel/libpanel-util')
-rw-r--r--mate-panel/libpanel-util/Makefile.am39
-rw-r--r--mate-panel/libpanel-util/Makefile.in647
-rw-r--r--mate-panel/libpanel-util/panel-cleanup.c110
-rw-r--r--mate-panel/libpanel-util/panel-cleanup.h51
-rw-r--r--mate-panel/libpanel-util/panel-dbus-service.c307
-rw-r--r--mate-panel/libpanel-util/panel-dbus-service.h78
-rw-r--r--mate-panel/libpanel-util/panel-error.c96
-rw-r--r--mate-panel/libpanel-util/panel-error.h49
-rw-r--r--mate-panel/libpanel-util/panel-glib.c164
-rw-r--r--mate-panel/libpanel-util/panel-glib.h46
-rw-r--r--mate-panel/libpanel-util/panel-gtk.c83
-rw-r--r--mate-panel/libpanel-util/panel-gtk.h42
-rw-r--r--mate-panel/libpanel-util/panel-icon-chooser.c555
-rw-r--r--mate-panel/libpanel-util/panel-icon-chooser.h79
-rw-r--r--mate-panel/libpanel-util/panel-keyfile.c363
-rw-r--r--mate-panel/libpanel-util/panel-keyfile.h79
-rw-r--r--mate-panel/libpanel-util/panel-launch.c234
-rw-r--r--mate-panel/libpanel-util/panel-launch.h65
-rw-r--r--mate-panel/libpanel-util/panel-list.c212
-rw-r--r--mate-panel/libpanel-util/panel-list.h56
-rw-r--r--mate-panel/libpanel-util/panel-session-manager.c192
-rw-r--r--mate-panel/libpanel-util/panel-session-manager.h75
-rw-r--r--mate-panel/libpanel-util/panel-show.c283
-rw-r--r--mate-panel/libpanel-util/panel-show.h54
-rw-r--r--mate-panel/libpanel-util/panel-xdg.c152
-rw-r--r--mate-panel/libpanel-util/panel-xdg.h43
26 files changed, 4154 insertions, 0 deletions
diff --git a/mate-panel/libpanel-util/Makefile.am b/mate-panel/libpanel-util/Makefile.am
new file mode 100644
index 00000000..377e26e5
--- /dev/null
+++ b/mate-panel/libpanel-util/Makefile.am
@@ -0,0 +1,39 @@
+noinst_LTLIBRARIES = libpanel-util.la
+
+AM_CPPFLAGS = \
+ $(PANEL_CFLAGS) \
+ -I. \
+ -I$(srcdir) \
+ -I$(top_builddir)/mate-panel/libpanel-util \
+ -DDATADIR=\""$(datadir)"\" \
+ $(DISABLE_DEPRECATED_CFLAGS)
+
+AM_CFLAGS = $(WARN_CFLAGS)
+
+libpanel_util_la_SOURCES = \
+ panel-cleanup.c \
+ panel-cleanup.h \
+ panel-dbus-service.c \
+ panel-dbus-service.h \
+ panel-error.c \
+ panel-error.h \
+ panel-glib.c \
+ panel-glib.h \
+ panel-gtk.c \
+ panel-gtk.h \
+ panel-icon-chooser.c \
+ panel-icon-chooser.h \
+ panel-keyfile.c \
+ panel-keyfile.h \
+ panel-launch.c \
+ panel-launch.h \
+ panel-list.c \
+ panel-list.h \
+ panel-session-manager.c \
+ panel-session-manager.h \
+ panel-show.c \
+ panel-show.h \
+ panel-xdg.c \
+ panel-xdg.h
+
+-include $(top_srcdir)/git.mk
diff --git a/mate-panel/libpanel-util/Makefile.in b/mate-panel/libpanel-util/Makefile.in
new file mode 100644
index 00000000..05758f14
--- /dev/null
+++ b/mate-panel/libpanel-util/Makefile.in
@@ -0,0 +1,647 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+pkgdatadir = $(datadir)/@[email protected]
+pkgincludedir = $(includedir)/@[email protected]
+pkglibdir = $(libdir)/@[email protected]
+pkglibexecdir = $(libexecdir)/@[email protected]
+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 = @[email protected]
+host_triplet = @[email protected]
+subdir = mate-panel/libpanel-util
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/d-type.m4 \
+ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/intltool.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/mate-doc-utils.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libpanel_util_la_LIBADD =
+am_libpanel_util_la_OBJECTS = panel-cleanup.lo panel-dbus-service.lo \
+ panel-error.lo panel-glib.lo panel-gtk.lo \
+ panel-icon-chooser.lo panel-keyfile.lo panel-launch.lo \
+ panel-list.lo panel-session-manager.lo panel-show.lo \
+ panel-xdg.lo
+libpanel_util_la_OBJECTS = $(am_libpanel_util_la_OBJECTS)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+DEFAULT_INCLUDES = [email protected][email protected] -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_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " [email protected];
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o [email protected]
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " [email protected];
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " [email protected];
+SOURCES = $(libpanel_util_la_SOURCES)
+DIST_SOURCES = $(libpanel_util_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @[email protected]
+ACLOCAL_AMFLAGS = @[email protected]
+ALL_LINGUAS = @[email protected]
+AM_DEFAULT_VERBOSITY = @[email protected]
+AUTOCONF = @[email protected]
+AUTOHEADER = @[email protected]
+AUTOMAKE = @[email protected]
+CATALOGS = @[email protected]
+CATOBJEXT = @[email protected]
+CCDEPMODE = @[email protected]
+CLOCK_CFLAGS = @[email protected]
+CLOCK_EDS_ICONDIR = @[email protected]
+CLOCK_LIBS = @[email protected]
+CPPFLAGS = @[email protected]
+CYGPATH_W = @[email protected]
+DATADIRNAME = @[email protected]
+DISABLE_DEPRECATED = @[email protected]
+DISABLE_DEPRECATED_CFLAGS = @[email protected]
+DISTCHECK_CONFIGURE_FLAGS = @[email protected]
+DLLTOOL = @[email protected]
+DOC_USER_FORMATS = @[email protected]
+DSYMUTIL = @[email protected]
+DUMPBIN = @[email protected]
+EGG_SMCLIENT_CFLAGS = @[email protected]
+EGG_SMCLIENT_LIBS = @[email protected]
+FISH_CFLAGS = @[email protected]
+FISH_LIBS = @[email protected]
+GETTEXT_PACKAGE = @[email protected]
+GIO_QUERYMODULES = @[email protected]
+GLIB_GENMARSHAL = @[email protected]
+GMOFILES = @[email protected]
+GMSGFMT = @[email protected]
+GTKDOC_CHECK = @[email protected]
+GTKDOC_DEPS_CFLAGS = @[email protected]
+GTKDOC_DEPS_LIBS = @[email protected]
+GTKDOC_MKPDF = @[email protected]
+GTKDOC_REBASE = @[email protected]
+HELP_DIR = @[email protected]
+HTML_DIR = @[email protected]
+INSTALL = @[email protected]
+INSTALL_DATA = @[email protected]
+INSTALL_PROGRAM = @[email protected]
+INSTALL_SCRIPT = @[email protected]
+INSTALL_STRIP_PROGRAM = @[email protected]
+INSTOBJEXT = @[email protected]
+INTLLIBS = @[email protected]
+INTLTOOL_EXTRACT = @[email protected]
+INTLTOOL_MERGE = @[email protected]
+INTLTOOL_PERL = @[email protected]
+INTLTOOL_UPDATE = @[email protected]
+INTROSPECTION_CFLAGS = @[email protected]
+INTROSPECTION_COMPILER = @[email protected]
+INTROSPECTION_GENERATE = @[email protected]
+INTROSPECTION_GIRDIR = @[email protected]
+INTROSPECTION_LIBS = @[email protected]
+INTROSPECTION_MAKEFILE = @[email protected]
+INTROSPECTION_SCANNER = @[email protected]
+INTROSPECTION_TYPELIBDIR = @[email protected]
+LDFLAGS = @[email protected]
+LIBMATE_PANEL_APPLET_CFLAGS = @[email protected]
+LIBMATE_PANEL_APPLET_LIBS = @[email protected]
+LIBMATE_PANEL_APPLET_MATECOMPONENT_CFLAGS = @[email protected]
+LIBMATE_PANEL_APPLET_MATECOMPONENT_LIBS = @[email protected]
+LIBOBJS = @[email protected]
+LIBTOOL = @[email protected]
+LIB_MATE_PANEL_APPLET_LT_VERSION = @[email protected]
+LIB_MATE_PANEL_APPLET_MATECOMPONENT_LT_VERSION = @[email protected]
+LTLIBOBJS = @[email protected]
+MAKEINFO = @[email protected]
+MANIFEST_TOOL = @[email protected]
+MATECOMPONENT_ACT_IDLDIR = @[email protected]
+MATECOMPONENT_CFLAGS = @[email protected]
+MATECOMPONENT_IDLDIR = @[email protected]
+MATECOMPONENT_LIBS = @[email protected]
+MATECONFTOOL = @[email protected]
+MATECONF_SCHEMA_CONFIG_SOURCE = @[email protected]
+MATECONF_SCHEMA_FILE_DIR = @[email protected]
+MATECORBA_IDL = @[email protected]
+MKDIR_P = @[email protected]
+MKINSTALLDIRS = @[email protected]
+MSGFMT_OPTS = @[email protected]
+MSGMERGE = @[email protected]
+NETWORK_MANAGER_CFLAGS = @[email protected]
+NETWORK_MANAGER_LIBS = @[email protected]
+NOTIFICATION_AREA_CFLAGS = @[email protected]
+NOTIFICATION_AREA_LIBS = @[email protected]
+OBJDUMP = @[email protected]
+OMF_DIR = @[email protected]
+OTOOL64 = @[email protected]
+PACKAGE = @[email protected]
+PACKAGE_BUGREPORT = @[email protected]
+PACKAGE_NAME = @[email protected]
+PACKAGE_STRING = @[email protected]
+PACKAGE_TARNAME = @[email protected]
+PACKAGE_URL = @[email protected]
+PACKAGE_VERSION = @[email protected]
+PANEL_CFLAGS = @[email protected]
+PANEL_INTLTOOL_MATE_PANEL_APPLET_RULE = @[email protected]
+PANEL_LIBS = @[email protected]
+PANEL_MODULE_MATECOMPONENT_CFLAGS = @[email protected]
+PANEL_MODULE_MATECOMPONENT_LIBS = @[email protected]
+PATH_SEPARATOR = @[email protected]
+PKG_CONFIG = @[email protected]
+PKG_CONFIG_LIBDIR = @[email protected]
+PKG_CONFIG_PATH = @[email protected]
+POFILES = @[email protected]
+PO_IN_DATADIR_FALSE = @[email protected]
+PO_IN_DATADIR_TRUE = @[email protected]
+PYTHON_EXEC_PREFIX = @[email protected]
+PYTHON_PLATFORM = @[email protected]
+PYTHON_PREFIX = @[email protected]
+PYTHON_VERSION = @[email protected]
+REBUILD = @[email protected]
+SET_MAKE = @[email protected]
+TZ_CFLAGS = @[email protected]
+TZ_LIBS = @[email protected]
+USE_NLS = @[email protected]
+VERSION = @[email protected]
+WARN_CFLAGS = @[email protected]
+WNCKLET_CFLAGS = @[email protected]
+WNCKLET_LIBS = @[email protected]
+XGETTEXT = @[email protected]
+XRANDR_CFLAGS = @[email protected]
+XRANDR_LIBS = @[email protected]
+X_CFLAGS = @[email protected]
+X_EXTRA_LIBS = @[email protected]
+X_PRE_LIBS = @[email protected]
+abs_builddir = @[email protected]
+abs_srcdir = @[email protected]
+abs_top_builddir = @[email protected]
+abs_top_srcdir = @[email protected]
+ac_ct_AR = @[email protected]
+ac_ct_CC = @[email protected]
+ac_ct_DUMPBIN = @[email protected]
+am__include = @[email protected]
+am__leading_dot = @[email protected]
+am__quote = @[email protected]
+am__tar = @[email protected]
+am__untar = @[email protected]
+appletsdir = @[email protected]
+build_alias = @[email protected]
+build_cpu = @[email protected]
+build_os = @[email protected]
+build_vendor = @[email protected]
+builddir = @[email protected]
+datadir = @[email protected]
+datarootdir = @[email protected]
+exec_prefix = @[email protected]
+host_alias = @[email protected]
+host_cpu = @[email protected]
+host_os = @[email protected]
+host_vendor = @[email protected]
+htmldir = @[email protected]
+includedir = @[email protected]
+infodir = @[email protected]
+install_sh = @[email protected]
+libexecdir = @[email protected]
+localedir = @[email protected]
+localstatedir = @[email protected]
+mkdir_p = @[email protected]
+modulesdir = @[email protected]
+oldincludedir = @[email protected]
+pkgpyexecdir = @[email protected]
+pkgpythondir = @[email protected]
+program_transform_name = @[email protected]
+pyexecdir = @[email protected]
+pythondir = @[email protected]
+sbindir = @[email protected]
+sharedstatedir = @[email protected]
+sysconfdir = @[email protected]
+target_alias = @[email protected]
+top_build_prefix = @[email protected]
+top_builddir = @[email protected]
+top_srcdir = @[email protected]
+noinst_LTLIBRARIES = libpanel-util.la
+AM_CPPFLAGS = \
+ $(PANEL_CFLAGS) \
+ -I. \
+ -I$(srcdir) \
+ -I$(top_builddir)/mate-panel/libpanel-util \
+ -DDATADIR=\""$(datadir)"\" \
+ $(DISABLE_DEPRECATED_CFLAGS)
+
+AM_CFLAGS = $(WARN_CFLAGS)
+libpanel_util_la_SOURCES = \
+ panel-cleanup.c \
+ panel-cleanup.h \
+ panel-dbus-service.c \
+ panel-dbus-service.h \
+ panel-error.c \
+ panel-error.h \
+ panel-glib.c \
+ panel-glib.h \
+ panel-gtk.c \
+ panel-gtk.h \
+ panel-icon-chooser.c \
+ panel-icon-chooser.h \
+ panel-keyfile.c \
+ panel-keyfile.h \
+ panel-launch.c \
+ panel-launch.h \
+ panel-list.c \
+ panel-list.h \
+ panel-session-manager.c \
+ panel-session-manager.h \
+ panel-show.c \
+ panel-show.h \
+ panel-xdg.c \
+ panel-xdg.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @[email protected] $(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 [email protected]; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu mate-panel/libpanel-util/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu mate-panel/libpanel-util/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)/[email protected] $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/[email protected] $(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: @[email protected] $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @[email protected] $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libpanel-util.la: $(libpanel_util_la_OBJECTS) $(libpanel_util_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) $(libpanel_util_la_OBJECTS) $(libpanel_util_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+
+.c.o:
[email protected][email protected] $(AM_V_CC)$(COMPILE) -MT [email protected] -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o [email protected] $<
[email protected][email protected] $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+
+.c.obj:
[email protected][email protected] $(AM_V_CC)$(COMPILE) -MT [email protected] -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o [email protected] `$(CYGPATH_W) '$<'`
[email protected][email protected] $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
[email protected][email protected] $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
[email protected][email protected] $(AM_V_CC)$(LTCOMPILE) -MT [email protected] -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o [email protected] $<
[email protected][email protected] $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "[email protected]" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+
+-include $(top_srcdir)/git.mk
+
+# 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/mate-panel/libpanel-util/panel-cleanup.c b/mate-panel/libpanel-util/panel-cleanup.c
new file mode 100644
index 00000000..90b089da
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-cleanup.c
@@ -0,0 +1,110 @@
+/*
+ * panel-cleanup.c: utility to clean up things on exit
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "panel-cleanup.h"
+
+typedef struct {
+ PanelCleanFunc func;
+ gpointer data;
+} PanelClean;
+
+static GSList *cleaner;
+
+void
+panel_cleanup_do (void)
+{
+ GSList *l;
+
+ if (!cleaner)
+ return;
+
+ for (l = cleaner; l; l = l->next) {
+ PanelClean *clean;
+
+ clean = l->data;
+ clean->func (clean->data);
+ g_slice_free (PanelClean, clean);
+ }
+
+ g_slist_free (cleaner);
+ cleaner = NULL;
+}
+
+void
+panel_cleanup_register (PanelCleanFunc func,
+ gpointer data)
+{
+ PanelClean *clean;
+
+ g_return_if_fail (func != NULL);
+
+ clean = g_slice_new (PanelClean);
+ clean->func = func;
+ clean->data = data;
+
+ cleaner = g_slist_prepend (cleaner, clean);
+}
+
+void
+panel_cleanup_unregister (PanelCleanFunc func,
+ gpointer data)
+{
+ GSList *l, *next;
+ PanelClean *clean;
+
+ g_return_if_fail (func != NULL);
+
+ if (!cleaner)
+ return;
+
+ l = cleaner;
+
+ do {
+ next = l->next;
+
+ clean = l->data;
+ if (clean->func == func && clean->data == data) {
+ g_slice_free (PanelClean, clean);
+ cleaner = g_slist_delete_link (cleaner, l);
+ }
+
+ l = next;
+ } while (l);
+}
+
+void
+panel_cleanup_unref_and_nullify (gpointer data)
+{
+ GObject **obj;
+
+ g_return_if_fail (data != NULL);
+
+ obj = data;
+
+ g_object_unref (*obj);
+ *obj = NULL;
+}
diff --git a/mate-panel/libpanel-util/panel-cleanup.h b/mate-panel/libpanel-util/panel-cleanup.h
new file mode 100644
index 00000000..3e5a27ab
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-cleanup.h
@@ -0,0 +1,51 @@
+/*
+ * panel-cleanup.h: utility to clean up things on exit
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#ifndef PANEL_CLEANUP_H
+#define PANEL_CLEANUP_H
+
+#include "glib.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PANEL_CLEAN_FUNC(f) ((PanelCleanFunc) (f))
+
+typedef void (*PanelCleanFunc) (gpointer data);
+
+void panel_cleanup_unref_and_nullify (gpointer data);
+
+void panel_cleanup_do (void);
+
+void panel_cleanup_register (PanelCleanFunc func,
+ gpointer data);
+void panel_cleanup_unregister (PanelCleanFunc func,
+ gpointer data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PANEL_CLEANUP_H */
diff --git a/mate-panel/libpanel-util/panel-dbus-service.c b/mate-panel/libpanel-util/panel-dbus-service.c
new file mode 100644
index 00000000..740d9212
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-dbus-service.c
@@ -0,0 +1,307 @@
+/*
+ * panel-dbus-service.c: a simple base object to use a DBus service. Only
+ * useful when subclassed.
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * Based on code from panel-power-manager.c:
+ * Copyright (C) 2006 Ray Strode <[email protected]>
+ * (not sure the copyright header was complete)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#include <string.h>
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <dbus/dbus-glib.h>
+
+#include "panel-dbus-service.h"
+
+struct _PanelDBusServicePrivate {
+ DBusGConnection *dbus_connection;
+ DBusGProxy *bus_proxy;
+ DBusGProxy *service_proxy;
+ guint32 is_connected : 1;
+
+ const char *service_name;
+ const char *service_path;
+ const char *service_interface;
+};
+
+static void panel_dbus_service_finalize (GObject *object);
+static void panel_dbus_service_class_install_properties (PanelDBusServiceClass *service_class);
+
+static void panel_dbus_service_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+enum {
+ PROP_0 = 0,
+ PROP_IS_CONNECTED
+};
+
+G_DEFINE_TYPE (PanelDBusService, panel_dbus_service, G_TYPE_OBJECT);
+
+static void
+panel_dbus_service_class_init (PanelDBusServiceClass *service_class)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (service_class);
+
+ object_class->finalize = panel_dbus_service_finalize;
+
+ panel_dbus_service_class_install_properties (service_class);
+
+ g_type_class_add_private (service_class,
+ sizeof (PanelDBusServicePrivate));
+}
+
+static void
+panel_dbus_service_class_install_properties (PanelDBusServiceClass *service_class)
+{
+ GObjectClass *object_class;
+ GParamSpec *param_spec;
+
+ object_class = G_OBJECT_CLASS (service_class);
+ object_class->get_property = panel_dbus_service_get_property;
+
+ param_spec = g_param_spec_boolean ("is-connected",
+ "Is connected",
+ "Whether the panel is connected to "
+ "a DBus service",
+ FALSE,
+ G_PARAM_READABLE);
+ g_object_class_install_property (object_class, PROP_IS_CONNECTED,
+ param_spec);
+}
+
+static void
+panel_dbus_service_init (PanelDBusService *service)
+{
+ service->priv = G_TYPE_INSTANCE_GET_PRIVATE (service,
+ PANEL_TYPE_DBUS_SERVICE,
+ PanelDBusServicePrivate);
+
+ service->priv->dbus_connection = NULL;
+ service->priv->bus_proxy = NULL;
+ service->priv->service_proxy = NULL;
+ service->priv->is_connected = FALSE;
+
+ service->priv->service_name = NULL;
+ service->priv->service_path = NULL;
+ service->priv->service_interface = NULL;
+}
+
+static void
+panel_dbus_service_finalize (GObject *object)
+{
+ PanelDBusService *service;
+
+ service = PANEL_DBUS_SERVICE (object);
+
+ if (service->priv->dbus_connection != NULL) {
+ dbus_g_connection_unref (service->priv->dbus_connection);
+ service->priv->dbus_connection = NULL;
+ }
+
+ if (service->priv->bus_proxy != NULL) {
+ g_object_unref (service->priv->bus_proxy);
+ service->priv->bus_proxy = NULL;
+ }
+
+ if (service->priv->service_proxy != NULL) {
+ g_object_unref (service->priv->service_proxy);
+ service->priv->service_proxy = NULL;
+ }
+
+ G_OBJECT_CLASS (panel_dbus_service_parent_class)->finalize (object);
+}
+
+static void
+panel_dbus_service_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PanelDBusService *service;
+
+ service = PANEL_DBUS_SERVICE (object);
+
+ switch (prop_id) {
+ case PROP_IS_CONNECTED:
+ g_value_set_boolean (value,
+ service->priv->is_connected);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
+ prop_id,
+ pspec);
+ }
+}
+
+static void
+panel_dbus_service_on_name_owner_changed (DBusGProxy *bus_proxy,
+ const char *name,
+ const char *prev_owner,
+ const char *new_owner,
+ PanelDBusService *service)
+{
+ g_assert (service->priv->service_name != NULL);
+
+ if (name && strcmp (name, service->priv->service_name) != 0)
+ return;
+
+ if (service->priv->service_proxy != NULL) {
+ g_object_unref (service->priv->service_proxy);
+ service->priv->service_proxy = NULL;
+ }
+
+ panel_dbus_service_ensure_connection (service, NULL);
+}
+
+gboolean
+panel_dbus_service_ensure_connection (PanelDBusService *service,
+ GError **error)
+{
+ GError *connection_error;
+ gboolean is_connected;
+
+ g_return_val_if_fail (PANEL_IS_DBUS_SERVICE (service), FALSE);
+
+ if (!service->priv->service_name ||
+ !service->priv->service_path ||
+ !service->priv->service_interface)
+ return FALSE;
+
+ connection_error = NULL;
+ if (service->priv->dbus_connection == NULL) {
+ service->priv->dbus_connection = dbus_g_bus_get (DBUS_BUS_SESSION,
+ &connection_error);
+
+ if (service->priv->dbus_connection == NULL) {
+ g_propagate_error (error, connection_error);
+ is_connected = FALSE;
+ goto out;
+ }
+ }
+
+ if (service->priv->bus_proxy == NULL) {
+ service->priv->bus_proxy =
+ dbus_g_proxy_new_for_name_owner (service->priv->dbus_connection,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS,
+ &connection_error);
+
+ if (service->priv->bus_proxy == NULL) {
+ g_propagate_error (error, connection_error);
+ is_connected = FALSE;
+ goto out;
+ }
+
+ dbus_g_proxy_add_signal (service->priv->bus_proxy,
+ "NameOwnerChanged",
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (service->priv->bus_proxy,
+ "NameOwnerChanged",
+ G_CALLBACK (panel_dbus_service_on_name_owner_changed),
+ service, NULL);
+ }
+
+ if (service->priv->service_proxy == NULL) {
+ service->priv->service_proxy =
+ dbus_g_proxy_new_for_name_owner (
+ service->priv->dbus_connection,
+ service->priv->service_name,
+ service->priv->service_path,
+ service->priv->service_interface,
+ &connection_error);
+
+ if (service->priv->service_proxy == NULL) {
+ g_propagate_error (error, connection_error);
+ is_connected = FALSE;
+ goto out;
+ }
+ }
+ is_connected = TRUE;
+
+out:
+ if (service->priv->is_connected != is_connected) {
+ service->priv->is_connected = is_connected;
+ g_object_notify (G_OBJECT (service), "is-connected");
+ }
+
+ if (!is_connected) {
+ if (service->priv->dbus_connection == NULL) {
+ if (service->priv->bus_proxy != NULL) {
+ g_object_unref (service->priv->bus_proxy);
+ service->priv->bus_proxy = NULL;
+ }
+
+ if (service->priv->service_proxy != NULL) {
+ g_object_unref (service->priv->service_proxy);
+ service->priv->service_proxy = NULL;
+ }
+ } else if (service->priv->bus_proxy == NULL) {
+ if (service->priv->service_proxy != NULL) {
+ g_object_unref (service->priv->service_proxy);
+ service->priv->service_proxy = NULL;
+ }
+ }
+ }
+
+ return is_connected;
+}
+
+void
+panel_dbus_service_define_service (PanelDBusService *service,
+ const char *name,
+ const char *path,
+ const char *interface)
+{
+ g_return_if_fail (PANEL_IS_DBUS_SERVICE (service));
+
+ g_assert (name != NULL);
+ g_assert (path != NULL);
+ g_assert (interface != NULL);
+ g_assert (service->priv->service_name == NULL);
+ g_assert (service->priv->service_path == NULL);
+ g_assert (service->priv->service_interface == NULL);
+
+ service->priv->service_name = name;
+ service->priv->service_path = path;
+ service->priv->service_interface = interface;
+}
+
+DBusGProxy *
+panel_dbus_service_get_proxy (PanelDBusService *service)
+{
+ g_return_val_if_fail (PANEL_IS_DBUS_SERVICE (service), NULL);
+
+ return service->priv->service_proxy;
+}
diff --git a/mate-panel/libpanel-util/panel-dbus-service.h b/mate-panel/libpanel-util/panel-dbus-service.h
new file mode 100644
index 00000000..bfd1830f
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-dbus-service.h
@@ -0,0 +1,78 @@
+/*
+ * panel-dbus-service.h: a simple base object to use a DBus service. Only
+ * useful when subclassed.
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * Based on code from panel-power-manager.h:
+ * Copyright (C) 2006 Ray Strode <[email protected]>
+ * (not sure the copyright header was complete)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#ifndef PANEL_DBUS_SERVICE_H
+#define PANEL_DBUS_SERVICE_H
+
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PANEL_TYPE_DBUS_SERVICE (panel_dbus_service_get_type ())
+#define PANEL_DBUS_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PANEL_TYPE_DBUS_SERVICE, PanelDBusService))
+#define PANEL_DBUS_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANEL_TYPE_DBUS_SERVICE, PanelDBusServiceClass))
+#define PANEL_IS_DBUS_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PANEL_TYPE_DBUS_SERVICE))
+#define PANEL_IS_DBUS_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANEL_TYPE_DBUS_SERVICE))
+#define PANEL_DBUS_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PANEL_TYPE_DBUS_SERVICE, PanelDBusServiceClass))
+
+typedef struct _PanelDBusService PanelDBusService;
+typedef struct _PanelDBusServiceClass PanelDBusServiceClass;
+typedef struct _PanelDBusServicePrivate PanelDBusServicePrivate;
+
+struct _PanelDBusService {
+ GObject parent;
+
+ /*< private > */
+ PanelDBusServicePrivate *priv;
+};
+
+struct _PanelDBusServiceClass {
+ GObjectClass parent_class;
+};
+
+GType panel_dbus_service_get_type (void);
+
+void panel_dbus_service_define_service (PanelDBusService *service,
+ const char *name,
+ const char *path,
+ const char *interface);
+
+gboolean panel_dbus_service_ensure_connection (PanelDBusService *service,
+ GError **error);
+
+DBusGProxy *panel_dbus_service_get_proxy (PanelDBusService *service);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PANEL_DBUS_SERVICE_H */
diff --git a/mate-panel/libpanel-util/panel-error.c b/mate-panel/libpanel-util/panel-error.c
new file mode 100644
index 00000000..de5c9704
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-error.c
@@ -0,0 +1,96 @@
+/*
+ * panel-error.c: an easy-to-use error dialog
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * Originally based on code from panel-util.c (there was no relevant copyright
+ * header at the time).
+ *
+ * Originally based on code from panel-util.c (there was no relevant copyright
+ * header at the time), but the code was:
+ * Copyright (C) Novell, Inc. (for the panel_g_utf8_strstrcase() code)
+ * Copyright (C) Dennis Cranston (for the panel_g_lookup_in_data_dirs() code)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#include <glib/gi18n.h>
+
+#include <gtk/gtk.h>
+
+#include "panel-error.h"
+
+GtkWidget *
+panel_error_dialog (GtkWindow *parent,
+ GdkScreen *screen,
+ const char *dialog_class,
+ gboolean auto_destroy,
+ const char *primary_text,
+ const char *secondary_text)
+{
+ GtkWidget *dialog;
+ char *freeme;
+
+ freeme = NULL;
+
+ if (primary_text == NULL) {
+ g_warning ("NULL dialog");
+ /* No need to translate this, this should NEVER happen */
+ freeme = g_strdup_printf ("Error with displaying error "
+ "for dialog of class %s",
+ dialog_class);
+ primary_text = freeme;
+ }
+
+ dialog = gtk_message_dialog_new (parent, 0, GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE, "%s", primary_text);
+ if (secondary_text != NULL)
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ "%s", secondary_text);
+
+ /* FIXME: we're losing this feature
+ gtk_widget_add_events (dialog, GDK_KEY_PRESS_MASK);
+ g_signal_connect (dialog, "event",
+ G_CALLBACK (panel_dialog_window_event), NULL);
+ */
+
+ if (screen)
+ gtk_window_set_screen (GTK_WINDOW (dialog), screen);
+
+ if (!parent) {
+ gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), FALSE);
+ /* FIXME: We need a title in this case, but we don't know what
+ * the format should be. Let's put something simple until
+ * the following bug gets fixed:
+ * http://bugzilla.gnome.org/show_bug.cgi?id=165132 */
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Error"));
+ }
+
+ gtk_widget_show_all (dialog);
+
+ if (auto_destroy)
+ g_signal_connect_swapped (G_OBJECT (dialog), "response",
+ G_CALLBACK (gtk_widget_destroy),
+ G_OBJECT (dialog));
+
+ if (freeme)
+ g_free (freeme);
+
+ return dialog;
+}
diff --git a/mate-panel/libpanel-util/panel-error.h b/mate-panel/libpanel-util/panel-error.h
new file mode 100644
index 00000000..314acb08
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-error.h
@@ -0,0 +1,49 @@
+/*
+ * panel-error.h: an easy-to-use error dialog
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * Originally based on code from panel-util.h (there was no relevant copyright
+ * header at the time).
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#ifndef PANEL_ERROR_H
+#define PANEL_ERROR_H
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GtkWidget *panel_error_dialog (GtkWindow *parent,
+ GdkScreen *screen,
+ const char *dialog_class,
+ gboolean auto_destroy,
+ const char *primary_text,
+ const char *secondary_text);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PANEL_ERROR_H */
diff --git a/mate-panel/libpanel-util/panel-glib.c b/mate-panel/libpanel-util/panel-glib.c
new file mode 100644
index 00000000..a728f25d
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-glib.c
@@ -0,0 +1,164 @@
+/*
+ * panel-glib.c: various small extensions to glib
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * Originally based on code from panel-util.c (there was no relevant copyright
+ * header at the time), but the code was:
+ * Copyright (C) Novell, Inc. (for the panel_g_utf8_strstrcase() code)
+ * Copyright (C) Dennis Cranston (for the panel_g_lookup_in_data_dirs() code)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#include <string.h>
+
+#include <glib.h>
+
+#include "panel-glib.h"
+
+typedef char * (*LookupInDir) (const char *basename, const char *dir);
+
+static char *
+_lookup_in_dir (const char *basename,
+ const char *dir)
+{
+ char *path;
+
+ path = g_build_filename (dir, basename, NULL);
+ if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
+ g_free (path);
+ return NULL;
+ }
+
+ return path;
+}
+
+static char *
+_lookup_in_applications_subdir (const char *basename,
+ const char *dir)
+{
+ char *path;
+
+ path = g_build_filename (dir, "applications", basename, NULL);
+ if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
+ g_free (path);
+ return NULL;
+ }
+
+ return path;
+}
+
+static char *
+_panel_g_lookup_in_data_dirs_internal (const char *basename,
+ LookupInDir lookup)
+{
+ const char * const *system_data_dirs;
+ const char *user_data_dir;
+ char *retval;
+ int i;
+
+ user_data_dir = g_get_user_data_dir ();
+ system_data_dirs = g_get_system_data_dirs ();
+
+ if ((retval = lookup (basename, user_data_dir)))
+ return retval;
+
+ for (i = 0; system_data_dirs[i]; i++)
+ if ((retval = lookup (basename, system_data_dirs[i])))
+ return retval;
+
+ return NULL;
+}
+
+char *
+panel_g_lookup_in_data_dirs (const char *basename)
+{
+ return _panel_g_lookup_in_data_dirs_internal (basename,
+ _lookup_in_dir);
+}
+
+char *
+panel_g_lookup_in_applications_dirs (const char *basename)
+{
+ return _panel_g_lookup_in_data_dirs_internal (basename,
+ _lookup_in_applications_subdir);
+}
+
+/* Copied from evolution-data-server/libedataserver/e-util.c:
+ * e_util_unicode_get_utf8() */
+static char *
+_unicode_get_utf8 (const char *text, gunichar *out)
+{
+ *out = g_utf8_get_char (text);
+ return (*out == (gunichar)-1) ? NULL : g_utf8_next_char (text);
+}
+
+/* Copied from evolution-data-server/libedataserver/e-util.c:
+ * e_util_utf8_strstrcase() */
+const char *
+panel_g_utf8_strstrcase (const char *haystack, const char *needle)
+{
+ gunichar *nuni;
+ gunichar unival;
+ gint nlen;
+ const char *o, *p;
+
+ if (haystack == NULL) return NULL;
+ if (needle == NULL) return NULL;
+ if (strlen (needle) == 0) return haystack;
+ if (strlen (haystack) == 0) return NULL;
+
+ nuni = g_alloca (sizeof (gunichar) * strlen (needle));
+
+ nlen = 0;
+ for (p = _unicode_get_utf8 (needle, &unival);
+ p && unival;
+ p = _unicode_get_utf8 (p, &unival)) {
+ nuni[nlen++] = g_unichar_tolower (unival);
+ }
+ /* NULL means there was illegal utf-8 sequence */
+ if (!p) return NULL;
+
+ o = haystack;
+ for (p = _unicode_get_utf8 (o, &unival);
+ p && unival;
+ p = _unicode_get_utf8 (p, &unival)) {
+ gint sc;
+ sc = g_unichar_tolower (unival);
+ /* We have valid stripped char */
+ if (sc == nuni[0]) {
+ const char *q = p;
+ gint npos = 1;
+ while (npos < nlen) {
+ q = _unicode_get_utf8 (q, &unival);
+ if (!q || !unival) return NULL;
+ sc = g_unichar_tolower (unival);
+ if (sc != nuni[npos]) break;
+ npos++;
+ }
+ if (npos == nlen) {
+ return o;
+ }
+ }
+ o = p;
+ }
+
+ return NULL;
+}
diff --git a/mate-panel/libpanel-util/panel-glib.h b/mate-panel/libpanel-util/panel-glib.h
new file mode 100644
index 00000000..6b7b4878
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-glib.h
@@ -0,0 +1,46 @@
+/*
+ * panel-glib.h: various small extensions to glib
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#ifndef PANEL_GLIB_H
+#define PANEL_GLIB_H
+
+#include <glib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PANEL_GLIB_STR_EMPTY(x) ((x) == NULL || (x)[0] == '\0')
+
+char *panel_g_lookup_in_data_dirs (const char *basename);
+char *panel_g_lookup_in_applications_dirs (const char *basename);
+
+const char *panel_g_utf8_strstrcase (const char *haystack,
+ const char *needle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PANEL_GLIB_H */
diff --git a/mate-panel/libpanel-util/panel-gtk.c b/mate-panel/libpanel-util/panel-gtk.c
new file mode 100644
index 00000000..097367fb
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-gtk.c
@@ -0,0 +1,83 @@
+/*
+ * panel-gtk.c: various small extensions to gtk+
+ *
+ * Copyright (C) 2010 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#include <gtk/gtk.h>
+
+#include "panel-gtk.h"
+
+/*
+ * Originally based on code from panel-properties-dialog.c. This part of the
+ * code was:
+ * Copyright (C) 2005 Vincent Untz <[email protected]>
+ */
+
+static void
+panel_gtk_file_chooser_preview_update (GtkFileChooser *chooser,
+ gpointer data)
+{
+ GtkWidget *preview;
+ char *filename;
+ GdkPixbuf *pixbuf;
+ gboolean have_preview;
+
+ preview = GTK_WIDGET (data);
+ filename = gtk_file_chooser_get_preview_filename (chooser);
+
+ if (filename == NULL)
+ return;
+
+ pixbuf = gdk_pixbuf_new_from_file_at_size (filename, 128, 128, NULL);
+ have_preview = (pixbuf != NULL);
+ g_free (filename);
+
+ gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
+ if (pixbuf)
+ g_object_unref (pixbuf);
+
+ gtk_file_chooser_set_preview_widget_active (chooser,
+ have_preview);
+}
+
+void
+panel_gtk_file_chooser_add_image_preview (GtkFileChooser *chooser)
+{
+ GtkFileFilter *filter;
+ GtkWidget *chooser_preview;
+
+ g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
+
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_add_pixbuf_formats (filter);
+ gtk_file_chooser_set_filter (chooser, filter);
+
+ chooser_preview = gtk_image_new ();
+ gtk_file_chooser_set_preview_widget (chooser, chooser_preview);
+ g_signal_connect (chooser, "update-preview",
+ G_CALLBACK (panel_gtk_file_chooser_preview_update),
+ chooser_preview);
+}
+
+/*
+ * End of code coming from panel-properties-dialog.c
+ */
diff --git a/mate-panel/libpanel-util/panel-gtk.h b/mate-panel/libpanel-util/panel-gtk.h
new file mode 100644
index 00000000..282fb82f
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-gtk.h
@@ -0,0 +1,42 @@
+/*
+ * panel-gtk.h: various small extensions to gtk+
+ *
+ * Copyright (C) 2009-2010 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#ifndef PANEL_GTK_H
+#define PANEL_GTK_H
+
+#include <gtk/gtk.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PANEL_GTK_BUILDER_GET(builder, name) GTK_WIDGET (gtk_builder_get_object (builder, name))
+
+void panel_gtk_file_chooser_add_image_preview (GtkFileChooser *chooser);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PANEL_GTK_H */
diff --git a/mate-panel/libpanel-util/panel-icon-chooser.c b/mate-panel/libpanel-util/panel-icon-chooser.c
new file mode 100644
index 00000000..07d14641
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-icon-chooser.c
@@ -0,0 +1,555 @@
+/*
+ * panel-icon-chooser.c: An icon chooser widget
+ *
+ * Copyright (C) 2010 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "panel-gtk.h"
+#include "panel-xdg.h"
+
+#include "panel-icon-chooser.h"
+
+#define PANEL_ICON_CHOOSER_ICON_SIZE GTK_ICON_SIZE_DIALOG
+
+struct _PanelIconChooserPrivate
+{
+ char *fallback_icon_name;
+ char *icon;
+
+ char *icon_theme_dir;
+
+ GtkWidget *image;
+
+ GtkWidget *filechooser;
+};
+
+enum {
+ CHANGED,
+ LAST_SIGNAL
+};
+
+enum {
+ PROP_0,
+ PROP_FALLBACK_ICON,
+ PROP_ICON
+};
+
+static guint panel_icon_chooser_signals[LAST_SIGNAL] = { 0 };
+
+#define PANEL_ICON_CHOOSER_GET_PRIVATE(o) (PANEL_ICON_CHOOSER (o)->priv)
+
+G_DEFINE_TYPE (PanelIconChooser, panel_icon_chooser, GTK_TYPE_BUTTON)
+
+static void _panel_icon_chooser_clicked (GtkButton *button);
+static void _panel_icon_chooser_style_set (GtkWidget *widget,
+ GtkStyle *prev_style);
+static void _panel_icon_chooser_screen_changed (GtkWidget *widget,
+ GdkScreen *prev_screen);
+
+/* gobject stuff */
+
+static GObject *
+panel_icon_chooser_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ GObject *obj;
+ PanelIconChooser *chooser;
+
+ obj = G_OBJECT_CLASS (panel_icon_chooser_parent_class)->constructor (type,
+ n_construct_properties,
+ construct_properties);
+
+ chooser = PANEL_ICON_CHOOSER (obj);
+ gtk_container_add (GTK_CONTAINER (chooser), chooser->priv->image);
+ gtk_widget_show (chooser->priv->image);
+
+ return obj;
+}
+
+static void
+panel_icon_chooser_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PanelIconChooser *chooser;
+
+ g_return_if_fail (PANEL_IS_ICON_CHOOSER (object));
+
+ chooser = PANEL_ICON_CHOOSER (object);
+
+ switch (prop_id) {
+ case PROP_FALLBACK_ICON:
+ g_value_set_string (value, panel_icon_chooser_get_fallback_icon_name (chooser));
+ break;
+ case PROP_ICON:
+ g_value_set_string (value, panel_icon_chooser_get_icon (chooser));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+panel_icon_chooser_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PanelIconChooser *chooser;
+
+ g_return_if_fail (PANEL_IS_ICON_CHOOSER (object));
+
+ chooser = PANEL_ICON_CHOOSER (object);
+
+ switch (prop_id) {
+ case PROP_FALLBACK_ICON:
+ panel_icon_chooser_set_fallback_icon_name (chooser,
+ g_value_get_string (value));
+ break;
+ case PROP_ICON:
+ panel_icon_chooser_set_icon (chooser,
+ g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+panel_icon_chooser_destroy (GtkObject *object)
+{
+ PanelIconChooser *chooser;
+
+ chooser = PANEL_ICON_CHOOSER (object);
+
+ if (chooser->priv->filechooser) {
+ gtk_widget_destroy (chooser->priv->filechooser);
+ chooser->priv->filechooser = NULL;
+ }
+
+ /* remember, destroy can be run multiple times! */
+
+ if (chooser->priv->fallback_icon_name != NULL)
+ g_free (chooser->priv->fallback_icon_name);
+ chooser->priv->fallback_icon_name = NULL;
+
+ if (chooser->priv->icon != NULL)
+ g_free (chooser->priv->icon);
+ chooser->priv->icon = NULL;
+
+ if (chooser->priv->icon_theme_dir != NULL)
+ g_free (chooser->priv->icon_theme_dir);
+ chooser->priv->icon_theme_dir = NULL;
+
+ GTK_OBJECT_CLASS (panel_icon_chooser_parent_class)->destroy (object);
+}
+
+static void
+panel_icon_chooser_class_init (PanelIconChooserClass *class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+ GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (class);
+ GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS (class);
+ GtkButtonClass *gtkbutton_class = GTK_BUTTON_CLASS (class);
+
+ gobject_class->constructor = panel_icon_chooser_constructor;
+ gobject_class->get_property = panel_icon_chooser_get_property;
+ gobject_class->set_property = panel_icon_chooser_set_property;
+
+ gtkobject_class->destroy = panel_icon_chooser_destroy;
+
+ gtkwidget_class->style_set = _panel_icon_chooser_style_set;
+ gtkwidget_class->screen_changed = _panel_icon_chooser_screen_changed;
+
+ gtkbutton_class->clicked = _panel_icon_chooser_clicked;
+
+ g_type_class_add_private (class,
+ sizeof (PanelIconChooserPrivate));
+
+ panel_icon_chooser_signals[CHANGED] =
+ g_signal_new ("changed",
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (PanelIconChooserClass,
+ changed),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ g_object_class_install_property (
+ gobject_class,
+ PROP_FALLBACK_ICON,
+ g_param_spec_string ("fallback-icon-name",
+ "Fallback Icon Name",
+ "Icon name of the icon displayed (but not returned) if the current icon does not exit",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ gobject_class,
+ PROP_ICON,
+ g_param_spec_string ("icon",
+ "Icon",
+ "Icon name or path",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+panel_icon_chooser_init (PanelIconChooser *chooser)
+{
+ PanelIconChooserPrivate *priv;
+
+ priv = G_TYPE_INSTANCE_GET_PRIVATE (chooser,
+ PANEL_TYPE_ICON_CHOOSER,
+ PanelIconChooserPrivate);
+
+ chooser->priv = priv;
+
+ priv->fallback_icon_name = g_strdup ("gtk-missing-image");
+ priv->icon = NULL;
+ priv->icon_theme_dir = NULL;
+
+ priv->image = gtk_image_new_from_icon_name (priv->fallback_icon_name,
+ PANEL_ICON_CHOOSER_ICON_SIZE);
+
+ priv->filechooser = NULL;
+}
+
+/* internal code */
+
+static void
+_panel_icon_chooser_update (PanelIconChooser *chooser)
+{
+ if (!chooser->priv->icon) {
+ gtk_image_set_from_icon_name (GTK_IMAGE (chooser->priv->image),
+ chooser->priv->fallback_icon_name,
+ PANEL_ICON_CHOOSER_ICON_SIZE);
+
+ } else if (g_path_is_absolute (chooser->priv->icon)) {
+ gboolean fallback;
+
+ fallback = TRUE;
+
+ if (g_file_test (chooser->priv->icon, G_FILE_TEST_EXISTS)) {
+ /* we pass via a pixbuf to force the size we want */
+ GdkPixbuf *pixbuf;
+ int width, height;
+
+ gtk_icon_size_lookup (PANEL_ICON_CHOOSER_ICON_SIZE,
+ &width, &height);
+ pixbuf = gdk_pixbuf_new_from_file_at_size (chooser->priv->icon,
+ width, height,
+ NULL);
+
+ if (pixbuf) {
+ gtk_image_set_from_pixbuf (GTK_IMAGE (chooser->priv->image),
+ pixbuf);
+ g_object_unref (pixbuf);
+ fallback = FALSE;
+ }
+ }
+
+ if (fallback) {
+ gtk_image_set_from_icon_name (GTK_IMAGE (chooser->priv->image),
+ chooser->priv->fallback_icon_name,
+ PANEL_ICON_CHOOSER_ICON_SIZE);
+ }
+
+ } else {
+ /* Note: using GThemedIcon doesn't work well, see bug #606752.
+ * When we'll remove the alternative code, we won't need the
+ * style_set/screen_changed handlers anymore.
+ */
+#if 0
+ GIcon *icon;
+ char *names[2];
+
+ names[0] = panel_xdg_icon_remove_extension (chooser->priv->icon);
+ names[1] = chooser->priv->fallback_icon_name;
+ icon = g_themed_icon_new_from_names (names, 2);
+
+ gtk_image_set_from_gicon (GTK_IMAGE (chooser->priv->image),
+ icon,
+ PANEL_ICON_CHOOSER_ICON_SIZE);
+
+ g_free (names[0]);
+#endif
+ GtkIconTheme *icon_theme;
+ const char *icon;
+ char *no_ext;
+
+ no_ext = panel_xdg_icon_remove_extension (chooser->priv->icon);
+
+ icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (chooser)));
+ if (gtk_icon_theme_has_icon (icon_theme, no_ext))
+ icon = no_ext;
+ else
+ icon = chooser->priv->fallback_icon_name;
+
+ gtk_image_set_from_icon_name (GTK_IMAGE (chooser->priv->image),
+ icon,
+ PANEL_ICON_CHOOSER_ICON_SIZE);
+
+ g_free (no_ext);
+ }
+}
+
+static char *
+_panel_icon_chooser_find_icon_from_path (PanelIconChooser *chooser,
+ const char *path)
+{
+ GdkScreen *screen;
+ char *icon;
+
+ screen = gtk_widget_get_screen (GTK_WIDGET (chooser));
+
+ icon = panel_xdg_icon_name_from_icon_path (path, screen);
+ if (!icon)
+ icon = g_strdup (path);
+
+ return icon;
+}
+
+static void
+_panel_icon_chooser_file_chooser_response (GtkFileChooser *filechooser,
+ gint response_id,
+ PanelIconChooser *chooser)
+{
+ if (response_id == GTK_RESPONSE_ACCEPT) {
+ char *path;
+ char *icon;
+
+ path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filechooser));
+ icon = _panel_icon_chooser_find_icon_from_path (chooser, path);
+ g_free (path);
+
+ panel_icon_chooser_set_icon (chooser, icon);
+ g_free (icon);
+ }
+
+ gtk_widget_destroy (GTK_WIDGET (filechooser));
+}
+
+static void
+_panel_icon_chooser_clicked (GtkButton *button)
+{
+ PanelIconChooser *chooser = PANEL_ICON_CHOOSER (button);
+ GtkWidget *filechooser;
+ GtkWidget *toplevel;
+ GtkWindow *parent;
+ char *path;
+ gboolean filechooser_path_set;
+
+ if (chooser->priv->filechooser) {
+ gtk_window_present (GTK_WINDOW (chooser->priv->filechooser));
+ return;
+ }
+
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button));
+ if (gtk_widget_is_toplevel (toplevel))
+ parent = GTK_WINDOW (toplevel);
+ else
+ parent = NULL;
+
+ filechooser = gtk_file_chooser_dialog_new (_("Choose an icon"),
+ parent,
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN,
+ GTK_RESPONSE_ACCEPT,
+ NULL);
+ panel_gtk_file_chooser_add_image_preview (GTK_FILE_CHOOSER (filechooser));
+
+ path = g_build_filename (DATADIR, "icons", NULL);
+ gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (filechooser),
+ path, NULL);
+ g_free (path);
+
+ path = g_build_filename (DATADIR, "pixmaps", NULL);
+ gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (filechooser),
+ path, NULL);
+ g_free (path);
+
+ filechooser_path_set = FALSE;
+
+ if (chooser->priv->icon) {
+ char *path = NULL;
+ if (g_path_is_absolute (chooser->priv->icon)) {
+ path = g_strdup (chooser->priv->icon);
+ } else {
+ GtkIconTheme *icon_theme;
+ GtkIconInfo *info;
+ char *no_ext;
+ int size;
+
+ icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (chooser)));
+ no_ext = panel_xdg_icon_remove_extension (chooser->priv->icon);
+ gtk_icon_size_lookup (PANEL_ICON_CHOOSER_ICON_SIZE,
+ &size, NULL);
+
+ info = gtk_icon_theme_lookup_icon (icon_theme, no_ext,
+ size, 0);
+ g_free (no_ext);
+
+ if (info) {
+ path = g_strdup (gtk_icon_info_get_filename (info));
+ gtk_icon_info_free (info);
+ }
+ }
+
+ if (path) {
+ gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (filechooser),
+ path);
+ g_free (path);
+ filechooser_path_set = TRUE;
+ }
+ }
+
+ if (!filechooser_path_set) {
+ char *path;
+ // FIXME? Use current icon theme? But there might not be a lot
+ // of icons there...
+ path = g_build_filename (DATADIR, "icons", NULL);
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (filechooser),
+ path);
+ }
+
+ gtk_window_set_destroy_with_parent (GTK_WINDOW (filechooser), TRUE);
+
+ g_signal_connect (filechooser, "response",
+ G_CALLBACK (_panel_icon_chooser_file_chooser_response),
+ chooser);
+
+ chooser->priv->filechooser = filechooser;
+
+ g_signal_connect (G_OBJECT (filechooser), "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &chooser->priv->filechooser);
+
+ gtk_widget_show (filechooser);
+}
+
+static void
+_panel_icon_chooser_style_set (GtkWidget *widget,
+ GtkStyle *prev_style)
+{
+ PanelIconChooser *chooser;
+
+ chooser = PANEL_ICON_CHOOSER (widget);
+
+ GTK_WIDGET_CLASS (panel_icon_chooser_parent_class)->style_set (widget, prev_style);
+
+ _panel_icon_chooser_update (chooser);
+}
+
+static void
+_panel_icon_chooser_screen_changed (GtkWidget *widget,
+ GdkScreen *prev_screen)
+{
+ PanelIconChooser *chooser;
+
+ chooser = PANEL_ICON_CHOOSER (widget);
+
+ if (GTK_WIDGET_CLASS (panel_icon_chooser_parent_class)->screen_changed)
+ GTK_WIDGET_CLASS (panel_icon_chooser_parent_class)->screen_changed (widget, prev_screen);
+
+ _panel_icon_chooser_update (chooser);
+}
+
+/* public methods */
+
+GtkWidget *
+panel_icon_chooser_new (const char *icon)
+{
+ GtkWidget *chooser;
+
+ chooser = g_object_new (PANEL_TYPE_ICON_CHOOSER,
+ "icon", icon,
+ NULL);
+
+ return chooser;
+}
+
+const char *
+panel_icon_chooser_get_fallback_icon_name (PanelIconChooser *chooser)
+{
+ g_return_val_if_fail (PANEL_IS_ICON_CHOOSER (chooser), NULL);
+
+ return chooser->priv->fallback_icon_name;
+}
+
+void
+panel_icon_chooser_set_fallback_icon_name (PanelIconChooser *chooser,
+ const char *fallback_icon_name)
+{
+ g_return_if_fail (PANEL_IS_ICON_CHOOSER (chooser));
+
+ if (g_strcmp0 (chooser->priv->fallback_icon_name, fallback_icon_name) == 0)
+ return;
+
+ if (chooser->priv->fallback_icon_name)
+ g_free (chooser->priv->fallback_icon_name);
+ chooser->priv->fallback_icon_name = g_strdup (fallback_icon_name);
+
+ _panel_icon_chooser_update (chooser);
+
+ g_object_notify (G_OBJECT (chooser), "fallback-icon-name");
+}
+
+const char *
+panel_icon_chooser_get_icon (PanelIconChooser *chooser)
+{
+ g_return_val_if_fail (PANEL_IS_ICON_CHOOSER (chooser), NULL);
+
+ return chooser->priv->icon;
+}
+
+void
+panel_icon_chooser_set_icon (PanelIconChooser *chooser,
+ const char *icon)
+{
+ g_return_if_fail (PANEL_IS_ICON_CHOOSER (chooser));
+
+ if (g_strcmp0 (chooser->priv->icon, icon) == 0)
+ return;
+
+ if (chooser->priv->icon)
+ g_free (chooser->priv->icon);
+ chooser->priv->icon = g_strdup (icon);
+
+ _panel_icon_chooser_update (chooser);
+
+ g_object_notify (G_OBJECT (chooser), "icon");
+
+ g_signal_emit (G_OBJECT (chooser),
+ panel_icon_chooser_signals[CHANGED], 0, icon);
+}
diff --git a/mate-panel/libpanel-util/panel-icon-chooser.h b/mate-panel/libpanel-util/panel-icon-chooser.h
new file mode 100644
index 00000000..03475e8f
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-icon-chooser.h
@@ -0,0 +1,79 @@
+/*
+ * panel-icon-chooser.h: An icon chooser widget
+ *
+ * Copyright (C) 2010 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#ifndef PANEL_ICON_CHOOSER_H
+#define PANEL_ICON_CHOOSER_H
+
+#include <gtk/gtk.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PANEL_TYPE_ICON_CHOOSER (panel_icon_chooser_get_type ())
+#define PANEL_ICON_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PANEL_TYPE_ICON_CHOOSER, PanelIconChooser))
+#define PANEL_ICON_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANEL_TYPE_ICON_CHOOSER, PanelIconChooserClass))
+#define PANEL_IS_ICON_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PANEL_TYPE_ICON_CHOOSER))
+#define PANEL_IS_ICON_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANEL_TYPE_ICON_CHOOSER))
+#define PANEL_ICON_CHOOSER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANEL_TYPE_ICON_CHOOSER, PanelIconChooserClass))
+
+typedef struct _PanelIconChooser PanelIconChooser;
+typedef struct _PanelIconChooserClass PanelIconChooserClass;
+
+typedef struct _PanelIconChooserPrivate PanelIconChooserPrivate;
+
+struct _PanelIconChooserClass
+{
+ GtkButtonClass parent_class;
+
+ void (* changed) (PanelIconChooser *chooser,
+ const char *icon);
+};
+
+struct _PanelIconChooser
+{
+ GtkButton parent_instance;
+
+ PanelIconChooserPrivate *priv;
+};
+
+GType panel_icon_chooser_get_type (void);
+
+GtkWidget *panel_icon_chooser_new (const char *icon);
+
+const char *panel_icon_chooser_get_fallback_icon_name (PanelIconChooser *chooser);
+
+void panel_icon_chooser_set_fallback_icon_name (PanelIconChooser *chooser,
+ const char *fallback_icon_name);
+
+const char *panel_icon_chooser_get_icon (PanelIconChooser *chooser);
+
+void panel_icon_chooser_set_icon (PanelIconChooser *chooser,
+ const char *icon);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PANEL_ICON_CHOOSER_H */
diff --git a/mate-panel/libpanel-util/panel-keyfile.c b/mate-panel/libpanel-util/panel-keyfile.c
new file mode 100644
index 00000000..28ec5853
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-keyfile.c
@@ -0,0 +1,363 @@
+/*
+ * panel-keyfile.c: GKeyFile extensions
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * Based on code from panel-util.c (there was no copyright header at the time)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#include <string.h>
+#include <sys/stat.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include "panel-keyfile.h"
+
+#define KEYFILE_TRUSTED_SHEBANG "#!/usr/bin/env xdg-open\n"
+
+GKeyFile *
+panel_key_file_new_desktop (void)
+{
+ GKeyFile *retval;
+
+ retval = g_key_file_new ();
+
+ //FIXME? g_key_file_set_string (retval, G_KEY_FILE_DESKTOP_GROUP, "Name", _("No Name"));
+ g_key_file_set_string (retval, G_KEY_FILE_DESKTOP_GROUP, "Version", "1.0");
+
+ return retval;
+}
+
+static void
+_panel_key_file_make_executable (const gchar *path)
+{
+ GFile *file;
+ GFileInfo *info;
+ guint32 current_perms;
+ guint32 new_perms;
+
+ file = g_file_new_for_path (path);
+
+ info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_STANDARD_TYPE","
+ G_FILE_ATTRIBUTE_UNIX_MODE,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ NULL,
+ NULL);
+
+ if (info == NULL) {
+ g_warning ("Cannot mark %s executable", path);
+ g_object_unref (file);
+ return;
+ }
+
+ if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_UNIX_MODE)) {
+ current_perms = g_file_info_get_attribute_uint32 (info,
+ G_FILE_ATTRIBUTE_UNIX_MODE);
+ new_perms = current_perms | S_IXGRP | S_IXUSR | S_IXOTH;
+ if ((current_perms != new_perms) &&
+ !g_file_set_attribute_uint32 (file,
+ G_FILE_ATTRIBUTE_UNIX_MODE,
+ new_perms,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ NULL, NULL))
+ g_warning ("Cannot mark %s executable", path);
+ }
+
+ g_object_unref (info);
+ g_object_unref (file);
+}
+
+//FIXME: kill this when bug #309224 is fixed
+gboolean
+panel_key_file_to_file (GKeyFile *keyfile,
+ const gchar *file,
+ GError **error)
+{
+ gchar *filename;
+ GError *write_error;
+ gchar *data;
+ gsize length;
+ gboolean res;
+
+ g_return_val_if_fail (keyfile != NULL, FALSE);
+ g_return_val_if_fail (file != NULL, FALSE);
+
+ write_error = NULL;
+ data = g_key_file_to_data (keyfile, &length, &write_error);
+ if (write_error) {
+ g_propagate_error (error, write_error);
+ return FALSE;
+ }
+
+ if (!g_path_is_absolute (file))
+ filename = g_filename_from_uri (file, NULL, &write_error);
+ else
+ filename = g_filename_from_utf8 (file, -1, NULL, NULL,
+ &write_error);
+
+ if (write_error) {
+ g_propagate_error (error, write_error);
+ g_free (data);
+ return FALSE;
+ }
+
+ if (!g_str_has_prefix (data, "#!")) {
+ gchar *new_data;
+ gsize new_length;
+
+ new_length = length + strlen (KEYFILE_TRUSTED_SHEBANG);
+ new_data = g_malloc (new_length);
+
+ strcpy (new_data, KEYFILE_TRUSTED_SHEBANG);
+ memcpy (new_data + strlen (KEYFILE_TRUSTED_SHEBANG),
+ data, length);
+
+ g_free (data);
+ data = new_data;
+ length = new_length;
+ }
+
+ res = g_file_set_contents (filename, data, length, &write_error);
+
+ if (write_error) {
+ g_propagate_error (error, write_error);
+ g_free (data);
+ g_free (filename);
+ return FALSE;
+ }
+
+ g_free (data);
+
+ _panel_key_file_make_executable (filename);
+ g_free (filename);
+
+ return res;
+}
+
+gboolean
+panel_key_file_load_from_uri (GKeyFile *keyfile,
+ const gchar *uri,
+ GKeyFileFlags flags,
+ GError **error)
+{
+ char *scheme;
+ gboolean is_local;
+ gboolean result;
+
+ g_return_val_if_fail (keyfile != NULL, FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ scheme = g_uri_parse_scheme (uri);
+ is_local = (scheme == NULL) || !g_ascii_strcasecmp (scheme, "file");
+ g_free (scheme);
+
+ if (is_local) {
+ char *path;
+
+ if (g_path_is_absolute (uri))
+ path = g_filename_from_utf8 (uri, -1, NULL, NULL, NULL);
+ else
+ path = g_filename_from_uri (uri, NULL, NULL);
+ result = g_key_file_load_from_file (keyfile, path,
+ flags, error);
+ g_free (path);
+ } else {
+ GFile *file;
+ char *contents;
+ gsize size;
+ gboolean ret;
+
+ file = g_file_new_for_uri (uri);
+ ret = g_file_load_contents (file, NULL, &contents, &size,
+ NULL, NULL);
+ g_object_unref (file);
+
+ if (!ret)
+ return FALSE;
+
+ result = g_key_file_load_from_data (keyfile, contents, size,
+ flags, error);
+
+ g_free (contents);
+ }
+
+ return result;
+}
+
+gboolean
+panel_key_file_copy_and_mark_trusted (const char *source_path,
+ const char *target_path,
+ GError **error)
+{
+ GKeyFile *key_file;
+ gboolean res = FALSE;
+
+ key_file = g_key_file_new ();
+ res = g_key_file_load_from_file (key_file, source_path,
+ G_KEY_FILE_KEEP_COMMENTS|G_KEY_FILE_KEEP_TRANSLATIONS,
+ error);
+ if (!res) {
+ g_key_file_free (key_file);
+ return FALSE;
+ }
+
+ res = panel_key_file_to_file (key_file, target_path, error);
+
+ g_key_file_free (key_file);
+
+ return res;
+}
+
+gboolean
+panel_key_file_get_boolean (GKeyFile *keyfile,
+ const gchar *key,
+ gboolean default_value)
+{
+ GError *error;
+ gboolean retval;
+
+ error = NULL;
+ retval = g_key_file_get_boolean (keyfile, G_KEY_FILE_DESKTOP_GROUP, key, &error);
+ if (error != NULL) {
+ retval = default_value;
+ g_error_free (error);
+ }
+
+ return retval;
+}
+
+void
+panel_key_file_set_locale_string (GKeyFile *keyfile,
+ const gchar *key,
+ const gchar *value)
+{
+ const char *locale;
+ const char * const *langs_pointer;
+ int i;
+
+ locale = NULL;
+ langs_pointer = g_get_language_names ();
+ for (i = 0; langs_pointer[i] != NULL; i++) {
+ /* find first without encoding */
+ if (strchr (langs_pointer[i], '.') == NULL) {
+ locale = langs_pointer[i];
+ break;
+ }
+ }
+
+ if (locale)
+ g_key_file_set_locale_string (keyfile, G_KEY_FILE_DESKTOP_GROUP,
+ key, locale, value);
+ else
+ g_key_file_set_string (keyfile, G_KEY_FILE_DESKTOP_GROUP,
+ key, value);
+}
+
+void
+panel_key_file_remove_locale_key (GKeyFile *keyfile,
+ const gchar *key)
+{
+ const char * const *langs_pointer;
+ int i;
+ char *locale_key;
+
+ locale_key = NULL;
+ langs_pointer = g_get_language_names ();
+ for (i = 0; langs_pointer[i] != NULL; i++) {
+ /* find first without encoding */
+ if (strchr (langs_pointer[i], '.') == NULL) {
+ locale_key = g_strdup_printf ("%s[%s]",
+ key, langs_pointer[i]);
+ if (g_key_file_has_key (keyfile, G_KEY_FILE_DESKTOP_GROUP,
+ locale_key, NULL))
+ break;
+
+ g_free (locale_key);
+ locale_key = NULL;
+ }
+ }
+
+ if (locale_key) {
+ g_key_file_remove_key (keyfile, G_KEY_FILE_DESKTOP_GROUP,
+ locale_key, NULL);
+ g_free (locale_key);
+ } else
+ g_key_file_remove_key (keyfile, G_KEY_FILE_DESKTOP_GROUP,
+ key, NULL);
+}
+
+void
+panel_key_file_remove_all_locale_key (GKeyFile *keyfile,
+ const gchar *key)
+{
+ char **keys;
+ int key_len;
+ int i;
+
+ if (!key)
+ return;
+
+ keys = g_key_file_get_keys (keyfile, G_KEY_FILE_DESKTOP_GROUP, NULL, NULL);
+ if (!keys)
+ return;
+
+ key_len = strlen (key);
+
+ for (i = 0; keys[i] != NULL; i++) {
+ int len;
+
+ if (strncmp (keys[i], key, key_len))
+ continue;
+
+ len = strlen (keys[i]);
+ if (len == key_len ||
+ (len > key_len && keys[i][key_len] == '['))
+ g_key_file_remove_key (keyfile, G_KEY_FILE_DESKTOP_GROUP,
+ keys[i], NULL);
+ }
+
+ g_strfreev (keys);
+}
+
+void
+panel_key_file_ensure_C_key (GKeyFile *keyfile,
+ const char *key)
+{
+ char *C_value;
+ char *buffer;
+
+ /* Make sure we set the "C" locale strings to the terms we set here.
+ * This is so that if the user logs into another locale they get their
+ * own description there rather then empty. It is not the C locale
+ * however, but the user created this entry herself so it's OK */
+ C_value = panel_key_file_get_string (keyfile, key);
+ if (C_value == NULL || C_value [0] == '\0') {
+ buffer = panel_key_file_get_locale_string (keyfile, key);
+ if (buffer) {
+ panel_key_file_set_string (keyfile, key, buffer);
+ g_free (buffer);
+ }
+ }
+ g_free (C_value);
+}
diff --git a/mate-panel/libpanel-util/panel-keyfile.h b/mate-panel/libpanel-util/panel-keyfile.h
new file mode 100644
index 00000000..addcefe4
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-keyfile.h
@@ -0,0 +1,79 @@
+/*
+ * panel-keyfile.h: GKeyFile extensions
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * Based on code from panel-util.h (there was no copyright header at the time)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#ifndef PANEL_KEYFILE_H
+#define PANEL_KEYFILE_H
+
+#include "glib.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+GKeyFile *panel_key_file_new_desktop (void);
+gboolean panel_key_file_to_file (GKeyFile *keyfile,
+ const gchar *file,
+ GError **error);
+gboolean panel_key_file_load_from_uri (GKeyFile *keyfile,
+ const gchar *uri,
+ GKeyFileFlags flags,
+ GError **error);
+
+gboolean panel_key_file_copy_and_mark_trusted (const char *source_path,
+ const char *target_path,
+ GError **error);
+
+gboolean panel_key_file_get_boolean (GKeyFile *keyfile,
+ const gchar *key,
+ gboolean default_value);
+#define panel_key_file_get_string(key_file, key) \
+ g_key_file_get_string (key_file, G_KEY_FILE_DESKTOP_GROUP, key, NULL)
+#define panel_key_file_get_locale_string(key_file, key) \
+ g_key_file_get_locale_string(key_file, G_KEY_FILE_DESKTOP_GROUP, key, NULL, NULL)
+
+#define panel_key_file_set_boolean(key_file, key, value) \
+ g_key_file_set_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, key, value)
+#define panel_key_file_set_string(key_file, key, value) \
+ g_key_file_set_string (key_file, G_KEY_FILE_DESKTOP_GROUP, key, value)
+void panel_key_file_set_locale_string (GKeyFile *keyfile,
+ const gchar *key,
+ const gchar *value);
+
+#define panel_key_file_remove_key(key_file, key) \
+ g_key_file_remove_key (key_file, G_KEY_FILE_DESKTOP_GROUP, key, NULL)
+void panel_key_file_remove_locale_key (GKeyFile *keyfile,
+ const gchar *key);
+void panel_key_file_remove_all_locale_key (GKeyFile *keyfile,
+ const gchar *key);
+void panel_key_file_ensure_C_key (GKeyFile *keyfile,
+ const char *key);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PANEL_KEYFILE_H */
diff --git a/mate-panel/libpanel-util/panel-launch.c b/mate-panel/libpanel-util/panel-launch.c
new file mode 100644
index 00000000..af2b4282
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-launch.c
@@ -0,0 +1,234 @@
+/*
+ * panel-launch.c: some helpers to launch desktop files
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#include <glib/gi18n.h>
+#include <gio/gio.h>
+#include <gio/gdesktopappinfo.h>
+
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+
+#include "panel-error.h"
+#include "panel-glib.h"
+
+#include "panel-launch.h"
+
+static void
+_panel_launch_error_dialog (const gchar *name,
+ GdkScreen *screen,
+ const gchar *message)
+{
+ char *primary;
+
+ if (name)
+ primary = g_markup_printf_escaped (_("Could not launch '%s'"),
+ name);
+ else
+ primary = g_strdup (_("Could not launch application"));
+
+ panel_error_dialog (NULL, screen, "cannot_launch", TRUE,
+ primary, message);
+ g_free (primary);
+}
+
+static gboolean
+_panel_launch_handle_error (const gchar *name,
+ GdkScreen *screen,
+ GError *local_error,
+ GError **error)
+{
+ if (local_error == NULL)
+ return TRUE;
+
+ else if (g_error_matches (local_error,
+ G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_error_free (local_error);
+ return TRUE;
+ }
+
+ else if (error != NULL)
+ g_propagate_error (error, local_error);
+
+ else {
+ _panel_launch_error_dialog (name, screen, local_error->message);
+ g_error_free (local_error);
+ }
+
+ return FALSE;
+}
+
+gboolean
+panel_app_info_launch_uris (GAppInfo *appinfo,
+ GList *uris,
+ GdkScreen *screen,
+ guint32 timestamp,
+ GError **error)
+{
+ GdkAppLaunchContext *context;
+ GError *local_error;
+ gboolean retval;
+
+ g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ context = gdk_app_launch_context_new ();
+ gdk_app_launch_context_set_screen (context, screen);
+ gdk_app_launch_context_set_timestamp (context, timestamp);
+
+ local_error = NULL;
+ retval = g_app_info_launch_uris (appinfo, uris,
+ (GAppLaunchContext *) context,
+ &local_error);
+
+ g_object_unref (context);
+
+ return _panel_launch_handle_error (g_app_info_get_name (appinfo),
+ screen, local_error, error);
+}
+
+gboolean
+panel_app_info_launch_uri (GAppInfo *appinfo,
+ const gchar *uri,
+ GdkScreen *screen,
+ guint32 timestamp,
+ GError **error)
+{
+ GList *uris;
+ gboolean retval;
+
+ g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ uris = NULL;
+ if (uri)
+ uris = g_list_prepend (uris, (gpointer) uri);
+
+ retval = panel_app_info_launch_uris (appinfo, uris,
+ screen, timestamp, error);
+
+ g_list_free (uris);
+
+ return retval;
+}
+
+gboolean
+panel_launch_key_file (GKeyFile *keyfile,
+ GList *uri_list,
+ GdkScreen *screen,
+ GError **error)
+{
+ GDesktopAppInfo *appinfo;
+ gboolean retval;
+
+ g_return_val_if_fail (keyfile != NULL, FALSE);
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ appinfo = g_desktop_app_info_new_from_keyfile (keyfile);
+
+ if (appinfo == NULL)
+ return FALSE;
+
+ retval = panel_app_info_launch_uris (G_APP_INFO (appinfo),
+ uri_list, screen,
+ gtk_get_current_event_time (),
+ error);
+
+ g_object_unref (appinfo);
+
+ return retval;
+}
+
+gboolean
+panel_launch_desktop_file (const char *desktop_file,
+ GdkScreen *screen,
+ GError **error)
+{
+ GDesktopAppInfo *appinfo;
+ gboolean retval;
+
+ g_return_val_if_fail (desktop_file != NULL, FALSE);
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ appinfo = NULL;
+
+ if (g_path_is_absolute (desktop_file))
+ appinfo = g_desktop_app_info_new_from_filename (desktop_file);
+ else {
+ char *full;
+
+ full = panel_g_lookup_in_applications_dirs (desktop_file);
+ if (full) {
+ appinfo = g_desktop_app_info_new_from_filename (full);
+ g_free (full);
+ }
+ }
+
+ if (appinfo == NULL)
+ return FALSE;
+
+ retval = panel_app_info_launch_uris (G_APP_INFO (appinfo), NULL, screen,
+ gtk_get_current_event_time (),
+ error);
+
+ g_object_unref (appinfo);
+
+ return retval;
+}
+
+gboolean
+panel_launch_desktop_file_with_fallback (const char *desktop_file,
+ const char *fallback_exec,
+ GdkScreen *screen,
+ GError **error)
+{
+ char *argv[2] = { (char *) fallback_exec, NULL };
+ GError *local_error;
+ gboolean retval;
+
+ g_return_val_if_fail (desktop_file != NULL, FALSE);
+ g_return_val_if_fail (fallback_exec != NULL, FALSE);
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ /* need to pass a non-NULL error to avoid getting a dialog */
+ local_error = NULL;
+ if (panel_launch_desktop_file (desktop_file, screen, &local_error))
+ return TRUE;
+
+ if (local_error) {
+ g_error_free (local_error);
+ local_error = NULL;
+ }
+
+ retval = gdk_spawn_on_screen (screen, NULL, argv, NULL,
+ G_SPAWN_SEARCH_PATH,
+ NULL, NULL, NULL, &local_error);
+
+ return _panel_launch_handle_error (fallback_exec,
+ screen, local_error, error);
+}
diff --git a/mate-panel/libpanel-util/panel-launch.h b/mate-panel/libpanel-util/panel-launch.h
new file mode 100644
index 00000000..d580f375
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-launch.h
@@ -0,0 +1,65 @@
+/*
+ * panel-launch.h: some helpers to launch desktop files
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#ifndef PANEL_LAUNCH_H
+#define PANEL_LAUNCH_H
+
+#include <gio/gio.h>
+#include <gdk/gdk.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+gboolean panel_app_info_launch_uris (GAppInfo *appinfo,
+ GList *uris,
+ GdkScreen *screen,
+ guint32 timestamp,
+ GError **error);
+
+gboolean panel_app_info_launch_uri (GAppInfo *appinfo,
+ const gchar *uri,
+ GdkScreen *screen,
+ guint32 timestamp,
+ GError **error);
+
+gboolean panel_launch_key_file (GKeyFile *keyfile,
+ GList *uri_list,
+ GdkScreen *screen,
+ GError **error);
+
+gboolean panel_launch_desktop_file (const char *desktop_file,
+ GdkScreen *screen,
+ GError **error);
+
+gboolean panel_launch_desktop_file_with_fallback (const char *desktop_file,
+ const char *fallback_exec,
+ GdkScreen *screen,
+ GError **error);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PANEL_LAUNCH_H */
diff --git a/mate-panel/libpanel-util/panel-list.c b/mate-panel/libpanel-util/panel-list.c
new file mode 100644
index 00000000..db036186
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-list.c
@@ -0,0 +1,212 @@
+/*
+ * panel-list.c: GList & GSList extensions
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * Originally based on code from panel-util.c (there was no relevant copyright
+ * header at the time), but the code was:
+ * Copyright (C) Mark McLoughlin <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#include <glib.h>
+
+#include "panel-list.h"
+
+GList *
+panel_g_list_insert_before (GList *list,
+ GList *sibling,
+ GList *link)
+{
+ if (!list) {
+ g_return_val_if_fail (sibling == NULL, list);
+ return link;
+ } else if (sibling) {
+ if (sibling->prev) {
+ link->prev = sibling->prev;
+ link->prev->next = link;
+ link->next = sibling;
+ sibling->prev = link;
+ return list;
+ } else {
+ link->next = sibling;
+ sibling->prev = link;
+ g_return_val_if_fail (sibling == list, link);
+ return link;
+ }
+ } else {
+ GList *last;
+
+ last = list;
+ while (last->next)
+ last = last->next;
+
+ last->next = link;
+ link->prev = last;
+ return list;
+ }
+}
+
+GList *
+panel_g_list_insert_after (GList *list,
+ GList *sibling,
+ GList *link)
+{
+ if (!list) {
+ g_return_val_if_fail (sibling == NULL, link);
+ return link;
+ } else if (sibling) {
+ if (sibling->next) {
+ link->next = sibling->next;
+ link->next->prev = link;
+ link->prev = sibling;
+ sibling->next = link;
+ return list;
+ } else {
+ sibling->next = link;
+ link->prev = sibling;
+ return list;
+ }
+
+ } else {
+ link->next = list;
+ list->prev = link;
+ return link;
+ }
+}
+
+GList *
+panel_g_list_swap_next (GList *list,
+ GList *dl)
+{
+ GList *t;
+
+ if (!dl)
+ return list;
+
+ if (!dl->next)
+ return list;
+
+ if (dl->prev)
+ dl->prev->next = dl->next;
+ t = dl->prev;
+ dl->prev = dl->next;
+ dl->next->prev = t;
+ if (dl->next->next)
+ dl->next->next->prev = dl;
+ t = dl->next->next;
+ dl->next->next = dl;
+ dl->next = t;
+
+ if (list == dl)
+ return dl->prev;
+
+ return list;
+}
+
+GList *
+panel_g_list_swap_prev (GList *list,
+ GList *dl)
+{
+ GList *t;
+
+ if (!dl)
+ return list;
+
+ if (!dl->prev)
+ return list;
+
+ if (dl->next)
+ dl->next->prev = dl->prev;
+ t = dl->next;
+ dl->next = dl->prev;
+ dl->prev->next = t;
+ if (dl->prev->prev)
+ dl->prev->prev->next = dl;
+ t = dl->prev->prev;
+ dl->prev->prev = dl;
+ dl->prev = t;
+
+ if (list == dl->next)
+ return dl;
+
+ return list;
+}
+
+/*maybe this should be a glib function?
+ it resorts a single item in the list*/
+GList *
+panel_g_list_resort_item (GList *list,
+ gpointer data,
+ GCompareFunc func)
+{
+ GList *dl;
+
+ g_return_val_if_fail (func != NULL, list);
+
+ if (!list)
+ return NULL;
+
+ dl = g_list_find (list, data);
+
+ if (dl != NULL)
+ return list;
+
+ while (dl->next &&
+ (*func)(dl->data, dl->next->data) > 0)
+ list = panel_g_list_swap_next (list, dl);
+ while (dl->prev &&
+ (*func) (dl->data, dl->prev->data) < 0)
+ list = panel_g_list_swap_prev (list, dl);
+
+ return list;
+}
+
+GSList *
+panel_g_slist_make_unique (GSList *list,
+ GCompareFunc compare,
+ gboolean free_data)
+{
+ GSList *sorted, *l;
+
+ g_return_val_if_fail (compare != NULL, list);
+
+ if (!list)
+ return NULL;
+
+ sorted = g_slist_copy (list);
+ sorted = g_slist_sort (sorted, compare);
+
+ for (l = sorted; l; l = l->next) {
+ GSList *next;
+
+ next = l->next;
+ if (l->data && next && next->data)
+ if (!compare (l->data, next->data)) {
+ list = g_slist_remove (list, l->data);
+ if (free_data)
+ g_free (l->data);
+ }
+ }
+
+ g_slist_free (sorted);
+
+ return list;
+}
diff --git a/mate-panel/libpanel-util/panel-list.h b/mate-panel/libpanel-util/panel-list.h
new file mode 100644
index 00000000..c3e48f53
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-list.h
@@ -0,0 +1,56 @@
+/*
+ * panel-list.h: GList & GSList extensions
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#ifndef PANEL_LIST_H
+#define PANEL_LIST_H
+
+#include <glib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GList *panel_g_list_insert_before (GList *list,
+ GList *sibling,
+ GList *link);
+GList *panel_g_list_insert_after (GList *list,
+ GList *sibling,
+ GList *link);
+GList *panel_g_list_swap_next (GList *list,
+ GList *dl);
+GList *panel_g_list_swap_prev (GList *list,
+ GList *dl);
+GList *panel_g_list_resort_item (GList *list,
+ gpointer data,
+ GCompareFunc func);
+
+GSList *panel_g_slist_make_unique (GSList *list,
+ GCompareFunc compare,
+ gboolean free_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PANEL_LIST_H */
diff --git a/mate-panel/libpanel-util/panel-session-manager.c b/mate-panel/libpanel-util/panel-session-manager.c
new file mode 100644
index 00000000..63152e1a
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-session-manager.c
@@ -0,0 +1,192 @@
+/*
+ * panel-session.c:
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#include <dbus/dbus-glib.h>
+
+#include "panel-cleanup.h"
+#include "panel-dbus-service.h"
+
+#include "panel-session-manager.h"
+
+static GObject *panel_session_manager_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties);
+
+G_DEFINE_TYPE (PanelSessionManager, panel_session_manager, PANEL_TYPE_DBUS_SERVICE);
+
+static void
+panel_session_manager_class_init (PanelSessionManagerClass *klass)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (klass);
+
+ object_class->constructor = panel_session_manager_constructor;
+}
+
+static void
+panel_session_manager_init (PanelSessionManager *manager)
+{
+}
+
+static GObject *
+panel_session_manager_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ GObject *obj;
+ GError *error;
+
+ obj = G_OBJECT_CLASS (panel_session_manager_parent_class)->constructor (
+ type,
+ n_construct_properties,
+ construct_properties);
+
+
+ panel_dbus_service_define_service (PANEL_DBUS_SERVICE (obj),
+ "org.mate.SessionManager",
+ "/org/mate/SessionManager",
+ "org.mate.SessionManager");
+
+ error = NULL;
+ if (!panel_dbus_service_ensure_connection (PANEL_DBUS_SERVICE (obj),
+ &error)) {
+ g_message ("Could not connect to session manager: %s",
+ error->message);
+ g_error_free (error);
+ }
+
+ return obj;
+}
+
+void
+panel_session_manager_request_logout (PanelSessionManager *manager,
+ PanelSessionManagerLogoutType mode)
+{
+ GError *error;
+ DBusGProxy *proxy;
+
+ g_return_if_fail (PANEL_IS_SESSION_MANAGER (manager));
+
+ error = NULL;
+
+ if (!panel_dbus_service_ensure_connection (PANEL_DBUS_SERVICE (manager),
+ &error)) {
+ g_warning ("Could not connect to session manager: %s",
+ error->message);
+ g_error_free (error);
+ return;
+ }
+
+ proxy = panel_dbus_service_get_proxy (PANEL_DBUS_SERVICE (manager));
+
+ if (!dbus_g_proxy_call (proxy, "Logout", &error,
+ G_TYPE_UINT, mode, G_TYPE_INVALID,
+ G_TYPE_INVALID) &&
+ error != NULL) {
+ g_warning ("Could not ask session manager to log out: %s",
+ error->message);
+ g_error_free (error);
+ }
+}
+
+void
+panel_session_manager_request_shutdown (PanelSessionManager *manager)
+{
+ GError *error;
+ DBusGProxy *proxy;
+
+ g_return_if_fail (PANEL_IS_SESSION_MANAGER (manager));
+
+ error = NULL;
+
+ if (!panel_dbus_service_ensure_connection (PANEL_DBUS_SERVICE (manager),
+ &error)) {
+ g_warning ("Could not connect to session manager: %s",
+ error->message);
+ g_error_free (error);
+ return;
+ }
+
+ proxy = panel_dbus_service_get_proxy (PANEL_DBUS_SERVICE (manager));
+
+ if (!dbus_g_proxy_call (proxy, "Shutdown", &error,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID) &&
+ error != NULL) {
+ g_warning ("Could not ask session manager to shut down: %s",
+ error->message);
+ g_error_free (error);
+ }
+}
+
+gboolean
+panel_session_manager_is_shutdown_available (PanelSessionManager *manager)
+{
+ GError *error;
+ DBusGProxy *proxy;
+ gboolean is_shutdown_available;
+
+ g_return_val_if_fail (PANEL_IS_SESSION_MANAGER (manager), FALSE);
+
+ error = NULL;
+
+ if (!panel_dbus_service_ensure_connection (PANEL_DBUS_SERVICE (manager),
+ &error)) {
+ g_warning ("Could not connect to session manager: %s",
+ error->message);
+ g_error_free (error);
+
+ return FALSE;
+ }
+
+ proxy = panel_dbus_service_get_proxy (PANEL_DBUS_SERVICE (manager));
+
+ if (!dbus_g_proxy_call (proxy, "CanShutdown", &error,
+ G_TYPE_INVALID, G_TYPE_BOOLEAN,
+ &is_shutdown_available, G_TYPE_INVALID) &&
+ error != NULL) {
+ g_warning ("Could not ask session manager if shut down is available: %s",
+ error->message);
+ g_error_free (error);
+
+ return FALSE;
+ }
+
+ return is_shutdown_available;
+}
+
+PanelSessionManager *
+panel_session_manager_get (void)
+{
+ static PanelSessionManager *manager = NULL;
+
+ if (manager == NULL) {
+ manager = g_object_new (PANEL_TYPE_SESSION_MANAGER, NULL);
+ panel_cleanup_register (panel_cleanup_unref_and_nullify,
+ &manager);
+ }
+
+ return manager;
+}
diff --git a/mate-panel/libpanel-util/panel-session-manager.h b/mate-panel/libpanel-util/panel-session-manager.h
new file mode 100644
index 00000000..d48ce5d3
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-session-manager.h
@@ -0,0 +1,75 @@
+/*
+ * panel-session.h:
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#ifndef PANEL_SESSION_MANAGER_H
+#define PANEL_SESSION_MANAGER_H
+
+#include <glib-object.h>
+
+#include "panel-dbus-service.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PANEL_TYPE_SESSION_MANAGER (panel_session_manager_get_type ())
+#define PANEL_SESSION_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PANEL_TYPE_SESSION_MANAGER, PanelSessionManager))
+#define PANEL_SESSION_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANEL_TYPE_SESSION_MANAGER, PanelSessionManagerClass))
+#define PANEL_IS_SESSION_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PANEL_TYPE_SESSION_MANAGER))
+#define PANEL_IS_SESSION_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANEL_TYPE_SESSION_MANAGER))
+#define PANEL_SESSION_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PANEL_TYPE_SESSION_MANAGER, PanelSessionManagerClass))
+
+typedef struct _PanelSessionManager PanelSessionManager;
+typedef struct _PanelSessionManagerClass PanelSessionManagerClass;
+
+struct _PanelSessionManager {
+ PanelDBusService parent;
+};
+
+struct _PanelSessionManagerClass {
+ PanelDBusServiceClass parent_class;
+};
+
+GType panel_session_manager_get_type (void);
+
+/* Keep in sync with the values defined in mate-session/session.h */
+typedef enum {
+ PANEL_SESSION_MANAGER_LOGOUT_MODE_NORMAL = 0,
+ PANEL_SESSION_MANAGER_LOGOUT_MODE_NO_CONFIRMATION,
+ PANEL_SESSION_MANAGER_LOGOUT_MODE_FORCE
+} PanelSessionManagerLogoutType;
+
+PanelSessionManager *panel_session_manager_get (void);
+
+void panel_session_manager_request_logout (PanelSessionManager *session,
+ PanelSessionManagerLogoutType mode);
+void panel_session_manager_request_shutdown (PanelSessionManager *session);
+
+gboolean panel_session_manager_is_shutdown_available (PanelSessionManager *session);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PANEL_SESSION_MANAGER_H */
diff --git a/mate-panel/libpanel-util/panel-show.c b/mate-panel/libpanel-util/panel-show.c
new file mode 100644
index 00000000..02ea2e63
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-show.c
@@ -0,0 +1,283 @@
+/*
+ * panel-show.c: a helper around gtk_show_uri
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#include <glib/gi18n.h>
+#include <gio/gio.h>
+#include <gio/gdesktopappinfo.h>
+
+#include <gtk/gtk.h>
+
+#include "panel-error.h"
+#include "panel-glib.h"
+#include "panel-launch.h"
+
+#include "panel-show.h"
+
+static void
+_panel_show_error_dialog (const gchar *uri,
+ GdkScreen *screen,
+ const gchar *message)
+{
+ char *primary;
+
+ primary = g_markup_printf_escaped (_("Could not open location '%s'"),
+ uri);
+ panel_error_dialog (NULL, screen, "cannot_show_url", TRUE,
+ primary, message);
+ g_free (primary);
+}
+
+typedef struct {
+ GMountOperation *mount_op;
+ GdkScreen *screen;
+} PanelShowMountOperationHandle;
+
+static void
+_panel_show_mount_async_callback (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ GFile *file;
+ PanelShowMountOperationHandle *handle = user_data;
+
+ file = G_FILE (source_object);
+
+ error = NULL;
+ if (g_file_mount_enclosing_volume_finish (file, result, &error)) {
+ char *uri = g_file_get_uri (file);
+
+ panel_show_uri (handle->screen, uri,
+ gtk_get_current_event_time (), NULL);
+ g_free (uri);
+ } else {
+ if (!g_error_matches (error, G_IO_ERROR,
+ G_IO_ERROR_PERMISSION_DENIED) &&
+ !g_error_matches (error, G_IO_ERROR,
+ G_IO_ERROR_FAILED_HANDLED)) {
+ char *uri;
+
+ uri = g_file_get_uri (file);
+ _panel_show_error_dialog (uri, handle->screen,
+ error->message);
+ g_free (uri);
+ }
+ g_error_free (error);
+ }
+
+ if (handle->mount_op)
+ g_object_unref (handle->mount_op);
+
+ g_slice_free (PanelShowMountOperationHandle, handle);
+}
+
+static gboolean _panel_show_handle_error(const gchar* uri, GdkScreen* screen, GError* local_error, GError** error)
+{
+ if (local_error == NULL)
+ {
+ return TRUE;
+ }
+
+ else if (g_error_matches (local_error,
+ G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_error_free (local_error);
+ return TRUE;
+ }
+
+ else if (g_error_matches (local_error,
+ G_IO_ERROR, G_IO_ERROR_NOT_MOUNTED)) {
+ GFile *file;
+ PanelShowMountOperationHandle *handle;
+
+ handle = g_slice_new (PanelShowMountOperationHandle);
+ file = g_file_new_for_uri (uri);
+
+ /* If it's not mounted, try to mount it ourselves */
+ handle->mount_op = gtk_mount_operation_new (NULL);
+ gtk_mount_operation_set_screen (GTK_MOUNT_OPERATION (handle->mount_op),
+ screen);
+ handle->screen = screen;
+
+ g_file_mount_enclosing_volume (file, G_MOUNT_MOUNT_NONE,
+ handle->mount_op, NULL,
+ _panel_show_mount_async_callback,
+ handle);
+ g_object_unref (file);
+
+ return TRUE;
+ }
+
+ else if (error != NULL)
+ g_propagate_error (error, local_error);
+
+ else {
+ _panel_show_error_dialog (uri, screen, local_error->message);
+ g_error_free (local_error);
+ }
+
+ return FALSE;
+}
+
+static gboolean panel_show_caja_search_uri(GdkScreen* screen, const gchar* uri, guint32 timestamp, GError** error)
+{
+ char* desktopfile;
+ GDesktopAppInfo* appinfo;
+ gboolean ret;
+
+ desktopfile = panel_g_lookup_in_applications_dirs("caja-folder-handler.desktop");
+
+ if (desktopfile)
+ {
+ appinfo = g_desktop_app_info_new_from_filename(desktopfile);
+ g_free(desktopfile);
+ }
+
+ if (!appinfo)
+ {
+ _panel_show_error_dialog (uri, screen, _("No application to handle search folders is installed."));
+ return FALSE;
+ }
+
+ ret = panel_app_info_launch_uri((GAppInfo*) appinfo, uri, screen, timestamp, error);
+ g_object_unref(appinfo);
+
+ return ret;
+}
+
+gboolean panel_show_uri(GdkScreen* screen, const gchar* uri, guint32 timestamp, GError** error)
+{
+ GError* local_error = NULL;
+
+ g_return_val_if_fail(GDK_IS_SCREEN (screen), FALSE);
+ g_return_val_if_fail(uri != NULL, FALSE);
+ g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
+
+ if (g_str_has_prefix(uri, "x-caja-search:"))
+ {
+ return panel_show_caja_search_uri(screen, uri, timestamp, error);
+ }
+
+ gtk_show_uri(screen, uri, timestamp, &local_error);
+
+ return _panel_show_handle_error(uri, screen, local_error, error);
+}
+
+gboolean
+panel_show_uri_force_mime_type (GdkScreen *screen,
+ const gchar *uri,
+ const gchar *mime_type,
+ guint32 timestamp,
+ GError **error)
+{
+ GFile *file;
+ GAppInfo *app;
+ gboolean ret;
+
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+ g_return_val_if_fail (mime_type != NULL, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ file = g_file_new_for_uri (uri);
+ app = g_app_info_get_default_for_type (mime_type,
+ !g_file_is_native (file));
+ g_object_unref (file);
+
+ if (app == NULL) {
+ /* no application for the mime type, so let's fallback on
+ * automatic detection */
+ return panel_show_uri (screen, uri, timestamp, error);
+ }
+
+ ret = panel_app_info_launch_uri (app, uri, screen, timestamp, error);
+ g_object_unref (app);
+
+ return ret;
+}
+
+static void
+_panel_show_help_error_dialog (const gchar *doc,
+ GdkScreen *screen,
+ const gchar *message)
+{
+ char *primary;
+
+ primary = g_markup_printf_escaped (_("Could not display help document '%s'"),
+ doc);
+ panel_error_dialog (NULL, screen, "cannot_show_help", TRUE,
+ primary, message);
+ g_free (primary);
+}
+
+static gboolean
+_panel_show_help_handle_error (const gchar *doc,
+ GdkScreen *screen,
+ GError *local_error,
+ GError **error)
+{
+ if (local_error == NULL)
+ return TRUE;
+
+ else if (g_error_matches (local_error,
+ G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_error_free (local_error);
+ return TRUE;
+ }
+
+ else if (error != NULL)
+ g_propagate_error (error, local_error);
+
+ else {
+ _panel_show_help_error_dialog (doc, screen,
+ local_error->message);
+ g_error_free (local_error);
+ }
+
+ return FALSE;
+}
+
+gboolean
+panel_show_help (GdkScreen *screen,
+ const gchar *doc,
+ const gchar *link,
+ GError **error)
+{
+ GError *local_error = NULL;
+ char *uri;
+
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE);
+ g_return_val_if_fail (doc != NULL, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ if (link)
+ uri = g_strdup_printf ("ghelp:%s?%s", doc, link);
+ else
+ uri = g_strdup_printf ("ghelp:%s", doc);
+
+ gtk_show_uri (screen, uri, gtk_get_current_event_time (), &local_error);
+
+ g_free (uri);
+
+ return _panel_show_help_handle_error (doc, screen, local_error, error);
+}
diff --git a/mate-panel/libpanel-util/panel-show.h b/mate-panel/libpanel-util/panel-show.h
new file mode 100644
index 00000000..a0eac9bc
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-show.h
@@ -0,0 +1,54 @@
+/*
+ * panel-show.h: a helper around gtk_show_uri
+ *
+ * Copyright (C) 2008 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#ifndef PANEL_SHOW_H
+#define PANEL_SHOW_H
+
+#include <gtk/gtk.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+gboolean panel_show_uri (GdkScreen *screen,
+ const gchar *uri,
+ guint32 timestamp,
+ GError **error);
+
+gboolean panel_show_uri_force_mime_type (GdkScreen *screen,
+ const gchar *uri,
+ const gchar *mime_type,
+ guint32 timestamp,
+ GError **error);
+
+gboolean panel_show_help (GdkScreen *screen,
+ const gchar *doc,
+ const gchar *link,
+ GError **error);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PANEL_SHOW_H */
diff --git a/mate-panel/libpanel-util/panel-xdg.c b/mate-panel/libpanel-util/panel-xdg.c
new file mode 100644
index 00000000..5415a22e
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-xdg.c
@@ -0,0 +1,152 @@
+/*
+ * panel-xdg.c: miscellaneous XDG-related functions.
+ *
+ * Copyright (C) 2010 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#include <string.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include "panel-xdg.h"
+
+#define DEFAULT_THEME_NAME "hicolor"
+
+/*
+ * Originally based on code from panel-util.c. This part of the code was:
+ * Copyright (C) 2006 Vincent Untz <[email protected]>
+ */
+
+char *
+panel_xdg_icon_remove_extension (const char *icon)
+{
+ char *icon_no_extension;
+ char *p;
+
+ icon_no_extension = g_strdup (icon);
+ p = strrchr (icon_no_extension, '.');
+ if (p &&
+ (strcmp (p, ".png") == 0 ||
+ strcmp (p, ".xpm") == 0 ||
+ strcmp (p, ".svg") == 0)) {
+ *p = 0;
+ }
+
+ return icon_no_extension;
+}
+
+/*
+ * End of code coming from panel-util.c
+ */
+
+char *
+panel_xdg_icon_name_from_icon_path (const char *path,
+ GdkScreen *screen)
+{
+ GtkIconTheme *theme;
+ GtkSettings *settings;
+ char *theme_name;
+ char *icon;
+ char **paths;
+ int n_paths;
+ int i;
+ GFile *file;
+
+ /* we look if the icon comes from the current icon theme */
+ if (!screen)
+ screen = gdk_screen_get_default ();
+
+ settings = gtk_settings_get_for_screen (screen);
+ g_object_get (settings,
+ "gtk-icon-theme-name", &theme_name,
+ NULL);
+
+ theme = gtk_icon_theme_get_for_screen (screen);
+ gtk_icon_theme_get_search_path (theme, &paths, &n_paths);
+
+ file = g_file_new_for_path (path);
+ icon = NULL;
+
+ for (i = 0; i < n_paths; i++) {
+ GFile *parent;
+ char *basename;
+
+ parent = g_file_new_for_path (paths[i]);
+
+ if (!g_file_has_prefix (file, parent)) {
+ g_object_unref (parent);
+ continue;
+ }
+
+ basename = g_file_get_basename (parent);
+
+ if (g_strcmp0 (basename, "pixmaps") == 0) {
+ char *relative_path;
+
+ relative_path = g_file_get_relative_path (parent, file);
+
+ /* if the icon is in a subdir of pixmaps, then it's not
+ * a real icon name */
+ if (!strchr (relative_path, G_DIR_SEPARATOR))
+ icon = panel_xdg_icon_remove_extension (relative_path);
+
+ g_free (relative_path);
+ } else {
+ /* real icon theme; but is it the current one? */
+ GFile *theme_dir;
+ gboolean current;
+
+ theme_dir = g_file_get_child (parent, theme_name);
+
+ current = FALSE;
+ if (g_file_has_prefix (file, theme_dir)) {
+ /* it's the current one */
+ current = TRUE;
+ } else {
+ /* it's the default one */
+ g_object_unref (theme_dir);
+ theme_dir = g_file_get_child (parent, DEFAULT_THEME_NAME);
+ current = g_file_has_prefix (file, theme_dir);
+ }
+
+ g_object_unref (theme_dir);
+
+ if (current) {
+ char *buffer;
+
+ buffer = g_file_get_basename (file);
+ icon = panel_xdg_icon_remove_extension (buffer);
+ g_free (buffer);
+ }
+ }
+
+ g_free (basename);
+ g_object_unref (parent);
+
+ break;
+ }
+
+ g_object_unref (file);
+ g_free (theme_name);
+
+ return icon;
+}
diff --git a/mate-panel/libpanel-util/panel-xdg.h b/mate-panel/libpanel-util/panel-xdg.h
new file mode 100644
index 00000000..8fa71b2e
--- /dev/null
+++ b/mate-panel/libpanel-util/panel-xdg.h
@@ -0,0 +1,43 @@
+/*
+ * panel-xdg.h: miscellaneous XDG-related functions.
+ *
+ * Copyright (C) 2010 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ * Vincent Untz <[email protected]>
+ */
+
+#ifndef PANEL_XDG_H
+#define PANEL_XDG_H
+
+#include <gtk/gtk.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+char *panel_xdg_icon_remove_extension (const char *icon);
+
+char *panel_xdg_icon_name_from_icon_path (const char *path,
+ GdkScreen *screen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PANEL_XDG_H */