diff options
author | Sebastien Bacher <seb128@ubuntu.com> | 2012-08-21 16:54:10 +0200 |
---|---|---|
committer | Sebastien Bacher <seb128@ubuntu.com> | 2012-08-21 16:54:10 +0200 |
commit | 9d8a4eeaf93b5f5537558e925a1c4f9b16e772b7 (patch) | |
tree | f801c95c81b320abcb8d3b9f6b6a2980001f65ec /src | |
parent | 06d8dda36decf33bc41e638ac8d59abed9abafbb (diff) | |
parent | e3c2920cf5d1f08466bc93a79a9642525eec838e (diff) | |
download | ayatana-indicator-messages-9d8a4eeaf93b5f5537558e925a1c4f9b16e772b7.tar.gz ayatana-indicator-messages-9d8a4eeaf93b5f5537558e925a1c4f9b16e772b7.tar.bz2 ayatana-indicator-messages-9d8a4eeaf93b5f5537558e925a1c4f9b16e772b7.zip |
Import upstream version 12.10.0
Diffstat (limited to 'src')
57 files changed, 4821 insertions, 8198 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 6617b49..403a289 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -15,8 +15,12 @@ messaginglibdir = $(INDICATORDIR) messaginglib_LTLIBRARIES = libmessaging.la libmessaging_la_SOURCES = \ indicator-messages.c \ - gen-messages-service.xml.h \ - gen-messages-service.xml.c \ + im-app-menu-item.c \ + im-app-menu-item.h \ + im-source-menu-item.c \ + im-source-menu-item.h \ + indicator-messages-service.c \ + indicator-messages-service.h dbus-data.h libmessaging_la_CFLAGS = \ $(APPLET_CFLAGS) \ @@ -37,26 +41,18 @@ libmessaging_la_LDFLAGS = \ ###################################### indicator_messages_service_SOURCES = \ - default-applications.h \ - default-applications.c \ messages-service.c \ - messages-service-dbus.c \ - messages-service-dbus.h \ - gen-messages-service.xml.h \ - gen-messages-service.xml.c \ - im-menu-item.c \ - im-menu-item.h \ - app-menu-item.c \ - app-menu-item.h \ - launcher-menu-item.c \ - launcher-menu-item.h \ - seen-db.c \ - seen-db.h \ - dirs.h \ + indicator-messages-service.c \ + indicator-messages-service.h \ + app-section.c \ + app-section.h \ dbus-data.h \ - \ - status-items.c \ - status-items.h + gactionmuxer.c \ + gactionmuxer.h \ + gsettingsstrv.c \ + gsettingsstrv.h \ + gmenuutils.c \ + gmenuutils.h indicator_messages_service_CFLAGS = \ $(APPLET_CFLAGS) \ @@ -66,218 +62,29 @@ indicator_messages_service_CFLAGS = \ -Wl,-z,defs \ -Wl,--as-needed \ -Werror \ - -DG_LOG_DOMAIN=\"Indicator-Messages\" \ - -DSTATUS_PROVIDER_DIR=\"$(STATUS_PROVIDER_DIR)\" + -DG_LOG_DOMAIN=\"Indicator-Messages\" indicator_messages_service_LDADD = \ - $(APPLET_LIBS) \ - libindicator-messages-status-provider.la + $(APPLET_LIBS) indicator_messages_service_LDFLAGS = \ $(COVERAGE_LDFLAGS) -gen-%.xml.h: %.xml - @echo "Building $@ from $<" - @echo "extern const char * _$(subst -,_,$(subst .,_,$(basename $(notdir $<))));" > $@ - -gen-%.xml.c: %.xml - @echo "Building $@ from $<" - echo "const char * _$(subst -,_,$(subst .,_,$(basename $(notdir $<)))) = " > $@ - @sed -e "s:\":\\\\\":g" -e s:^:\": -e s:\$$:\\\\n\": $< >> $@ - @echo ";" >> $@ +indicator-messages-service.c: $(top_srcdir)/src/messages-service.xml + $(AM_V_GEN) gdbus-codegen \ + --interface-prefix com.canonical.indicator.messages. \ + --generate-c-code indicator-messages-service \ + --c-namespace IndicatorMessages \ + $^ +indicator-messages-service.h: indicator-messages-service.c BUILT_SOURCES += \ - gen-messages-service.xml.h \ - gen-messages-service.xml.c + indicator-messages-service.c \ + indicator-messages-service.h EXTRA_DIST += \ messages-service.xml -###################################### -# Status Provider Library -###################################### - -STATUS_PROVIDER_API_VERSION = 1 -STATUS_PROVIDER_DIR = $(libexecdir)/status-providers/$(STATUS_PROVIDER_API_VERSION) -statusprovidersdir = $(STATUS_PROVIDER_DIR) -statusproviders_LTLIBRARIES = - -EXTRA_DIST += \ - indicator-messages-status-provider-0.5.pc.in.in -CLEANFILES += \ - indicator-messages-status-provider-0.5.pc - -pkgconfig_DATA = indicator-messages-status-provider-0.5.pc -pkgconfigdir = $(libdir)/pkgconfig - -%.pc: %.pc.in - sed \ - -e "s|\@status_provider_dir\@|$(STATUS_PROVIDER_DIR)|" \ - -e "s|\@status_provider_api_version\@|$(STATUS_PROVIDER_API_VERSION)|" \ - $< > $@ - -lib_LTLIBRARIES = \ - libindicator-messages-status-provider.la - -libindicator_messages_status_provider_la_HEADERS = \ - status-provider.h - -libindicator_messages_status_provider_la_SOURCES = \ - $(libindicator_messages_status_provider_HEADERS) \ - status-provider.c - -libindicator_messages_status_provider_ladir = \ - $(includedir)/libindicator-messages-status-provider-$(STATUS_PROVIDER_API_VERSION)/ - -libindicator_messages_status_provider_la_LDFLAGS = \ - -version-info $(STATUS_PROVIDER_API_VERSION):0:0 \ - -no-undefined \ - -export-symbols-regex "^[^_].*" - -libindicator_messages_status_provider_la_LIBADD = \ - $(APPLET_LIBS) - -libindicator_messages_status_provider_la_CFLAGS = \ - $(APPLET_CFLAGS) \ - -Wall -Werror - -###################################### -# Status provider: Pidgin -###################################### - -statusproviders_LTLIBRARIES += libpidgin.la -libpidgin_la_SOURCES = \ - status-provider-pidgin.h \ - status-provider-pidgin.c \ - status-provider-pidgin-marshal.h \ - status-provider-pidgin-marshal.c -libpidgin_la_CFLAGS = \ - $(APPLET_CFLAGS) \ - $(STATUS_PROVIDER_PIDGIN_CFLAGS) \ - -Wall -Werror \ - -DG_LOG_DOMAIN=\"Status-Provider-Pidgin\" -libpidgin_la_LIBADD = \ - libindicator-messages-status-provider.la \ - $(APPLET_LIBS) \ - $(STATUS_PROVIDER_PIDGIN_LIBS) -libpidgin_la_LDFLAGS = -module -avoid-version - -status-provider-pidgin-marshal.h: $(srcdir)/status-provider-pidgin.list - glib-genmarshal --header \ - --prefix=_status_provider_pidgin_marshal $(srcdir)/status-provider-pidgin.list \ - > status-provider-pidgin-marshal.h - -status-provider-pidgin-marshal.c: $(srcdir)/status-provider-pidgin.list - glib-genmarshal --body \ - --prefix=_status_provider_pidgin_marshal $(srcdir)/status-provider-pidgin.list \ - > status-provider-pidgin-marshal.c - -BUILT_SOURCES += \ - status-provider-pidgin-marshal.h \ - status-provider-pidgin-marshal.c - -EXTRA_DIST += \ - status-provider-pidgin.list - -###################################### -# Status provider: Mission Control 4 -###################################### - -statusproviders_LTLIBRARIES += libtelepathy.la -libtelepathy_la_SOURCES = \ - status-provider-telepathy.h \ - status-provider-telepathy.c \ - status-provider-telepathy-marshal.h \ - status-provider-telepathy-marshal.c -libtelepathy_la_CFLAGS = \ - $(APPLET_CFLAGS) \ - $(STATUS_PROVIDER_TELEPATHY_CFLAGS) \ - -Wall -Werror \ - -DG_LOG_DOMAIN=\"Status-Provider-Telepathy\" -libtelepathy_la_LIBADD = \ - libindicator-messages-status-provider.la \ - $(APPLET_LIBS) \ - $(STATUS_PROVIDER_TELEPATHY_LIBS) -libtelepathy_la_LDFLAGS = -module -avoid-version - -status-provider-telepathy-marshal.h: $(srcdir)/status-provider-telepathy.list - glib-genmarshal --header \ - --prefix=_status_provider_telepathy_marshal $(srcdir)/status-provider-telepathy.list \ - > status-provider-telepathy-marshal.h - -status-provider-telepathy-marshal.c: $(srcdir)/status-provider-telepathy.list - glib-genmarshal --body \ - --prefix=_status_provider_telepathy_marshal $(srcdir)/status-provider-telepathy.list \ - > status-provider-telepathy-marshal.c - -BUILT_SOURCES += \ - status-provider-telepathy-marshal.h \ - status-provider-telepathy-marshal.c - -EXTRA_DIST += \ - status-provider-telepathy.list - -###################################### -# Status provider: Mission Control 5 -###################################### - -statusproviders_LTLIBRARIES += libmc5.la -libmc5_la_SOURCES = \ - status-provider-mc5.h \ - status-provider-mc5.c \ - status-provider-mc5-marshal.h \ - status-provider-mc5-marshal.c -libmc5_la_CFLAGS = \ - $(APPLET_CFLAGS) \ - $(STATUS_PROVIDER_MC5_CFLAGS) \ - -Wall -Werror \ - -DG_LOG_DOMAIN=\"Status-Provider-MC5\" -libmc5_la_LIBADD = \ - libindicator-messages-status-provider.la \ - $(APPLET_LIBS) \ - $(STATUS_PROVIDER_MC5_LIBS) -libmc5_la_LDFLAGS = -module -avoid-version - -status-provider-mc5-marshal.h: $(srcdir)/status-provider-mc5.list - glib-genmarshal --header \ - --prefix=_status_provider_mc5_marshal $(srcdir)/status-provider-mc5.list \ - > status-provider-mc5-marshal.h - -status-provider-mc5-marshal.c: $(srcdir)/status-provider-mc5.list - glib-genmarshal --body \ - --prefix=_status_provider_mc5_marshal $(srcdir)/status-provider-mc5.list \ - > status-provider-mc5-marshal.c - -BUILT_SOURCES += \ - status-provider-mc5-marshal.h \ - status-provider-mc5-marshal.c - -EXTRA_DIST += \ - status-provider-mc5.list - -###################################### -# Status provider: Emesene -###################################### - -statusproviders_LTLIBRARIES += libemesene.la -libemesene_la_SOURCES = \ - status-provider-emesene.h \ - status-provider-emesene.c -libemesene_la_CFLAGS = \ - $(APPLET_CFLAGS) \ - $(STATUS_PROVIDER_EMESENE_CFLAGS) \ - -Wall -Werror \ - -DG_LOG_DOMAIN=\"Status-Provider-Emesene\" -libemesene_la_LIBADD = \ - libindicator-messages-status-provider.la \ - $(APPLET_LIBS) \ - $(STATUS_PROVIDER_EMESENE_LIBS) -libemesene_la_LDFLAGS = -module -avoid-version - -###################################### -# Extras -###################################### - CLEANFILES += \ $(BUILT_SOURCES) diff --git a/src/Makefile.in b/src/Makefile.in index a66adb2..d95ba26 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11.3 from Makefile.am. +# Makefile.in generated by automake 1.11.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -16,9 +16,24 @@ @SET_MAKE@ - - VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -39,20 +54,15 @@ build_triplet = @build@ host_triplet = @host@ libexec_PROGRAMS = indicator-messages-service$(EXEEXT) subdir = src -DIST_COMMON = $(libindicator_messages_status_provider_la_HEADERS) \ - $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(srcdir)/indicator-messages-status-provider-0.5.pc.in.in +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(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/gcov.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/gcov.m4 \ $(top_srcdir)/m4/gtest.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 = indicator-messages-status-provider-0.5.pc.in +CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ @@ -81,84 +91,34 @@ am__uninstall_files_from_dir = { \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(messaginglibdir)" \ - "$(DESTDIR)$(statusprovidersdir)" "$(DESTDIR)$(libexecdir)" \ - "$(DESTDIR)$(pkgconfigdir)" \ - "$(DESTDIR)$(libindicator_messages_status_provider_ladir)" -LTLIBRARIES = $(lib_LTLIBRARIES) $(messaginglib_LTLIBRARIES) \ - $(statusproviders_LTLIBRARIES) +am__installdirs = "$(DESTDIR)$(messaginglibdir)" \ + "$(DESTDIR)$(libexecdir)" +LTLIBRARIES = $(messaginglib_LTLIBRARIES) am__DEPENDENCIES_1 = -libemesene_la_DEPENDENCIES = libindicator-messages-status-provider.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am_libemesene_la_OBJECTS = libemesene_la-status-provider-emesene.lo -libemesene_la_OBJECTS = $(am_libemesene_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -libemesene_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libemesene_la_CFLAGS) \ - $(CFLAGS) $(libemesene_la_LDFLAGS) $(LDFLAGS) -o $@ -libindicator_messages_status_provider_la_DEPENDENCIES = \ - $(am__DEPENDENCIES_1) -am_libindicator_messages_status_provider_la_OBJECTS = \ - libindicator_messages_status_provider_la-status-provider.lo -libindicator_messages_status_provider_la_OBJECTS = \ - $(am_libindicator_messages_status_provider_la_OBJECTS) -libindicator_messages_status_provider_la_LINK = $(LIBTOOL) $(AM_V_lt) \ - --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ - $(CCLD) $(libindicator_messages_status_provider_la_CFLAGS) \ - $(CFLAGS) $(libindicator_messages_status_provider_la_LDFLAGS) \ - $(LDFLAGS) -o $@ -libmc5_la_DEPENDENCIES = libindicator-messages-status-provider.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am_libmc5_la_OBJECTS = libmc5_la-status-provider-mc5.lo \ - libmc5_la-status-provider-mc5-marshal.lo -libmc5_la_OBJECTS = $(am_libmc5_la_OBJECTS) -libmc5_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libmc5_la_CFLAGS) \ - $(CFLAGS) $(libmc5_la_LDFLAGS) $(LDFLAGS) -o $@ libmessaging_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am_libmessaging_la_OBJECTS = libmessaging_la-indicator-messages.lo \ - libmessaging_la-gen-messages-service.xml.lo + libmessaging_la-im-app-menu-item.lo \ + libmessaging_la-im-source-menu-item.lo \ + libmessaging_la-indicator-messages-service.lo libmessaging_la_OBJECTS = $(am_libmessaging_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent libmessaging_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libmessaging_la_CFLAGS) $(CFLAGS) $(libmessaging_la_LDFLAGS) \ $(LDFLAGS) -o $@ -libpidgin_la_DEPENDENCIES = libindicator-messages-status-provider.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am_libpidgin_la_OBJECTS = libpidgin_la-status-provider-pidgin.lo \ - libpidgin_la-status-provider-pidgin-marshal.lo -libpidgin_la_OBJECTS = $(am_libpidgin_la_OBJECTS) -libpidgin_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libpidgin_la_CFLAGS) \ - $(CFLAGS) $(libpidgin_la_LDFLAGS) $(LDFLAGS) -o $@ -libtelepathy_la_DEPENDENCIES = \ - libindicator-messages-status-provider.la $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) -am_libtelepathy_la_OBJECTS = \ - libtelepathy_la-status-provider-telepathy.lo \ - libtelepathy_la-status-provider-telepathy-marshal.lo -libtelepathy_la_OBJECTS = $(am_libtelepathy_la_OBJECTS) -libtelepathy_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(libtelepathy_la_CFLAGS) $(CFLAGS) $(libtelepathy_la_LDFLAGS) \ - $(LDFLAGS) -o $@ PROGRAMS = $(libexec_PROGRAMS) am_indicator_messages_service_OBJECTS = \ - indicator_messages_service-default-applications.$(OBJEXT) \ indicator_messages_service-messages-service.$(OBJEXT) \ - indicator_messages_service-messages-service-dbus.$(OBJEXT) \ - indicator_messages_service-gen-messages-service.xml.$(OBJEXT) \ - indicator_messages_service-im-menu-item.$(OBJEXT) \ - indicator_messages_service-app-menu-item.$(OBJEXT) \ - indicator_messages_service-launcher-menu-item.$(OBJEXT) \ - indicator_messages_service-seen-db.$(OBJEXT) \ - indicator_messages_service-status-items.$(OBJEXT) + indicator_messages_service-indicator-messages-service.$(OBJEXT) \ + indicator_messages_service-app-section.$(OBJEXT) \ + indicator_messages_service-gactionmuxer.$(OBJEXT) \ + indicator_messages_service-gsettingsstrv.$(OBJEXT) \ + indicator_messages_service-gmenuutils.$(OBJEXT) indicator_messages_service_OBJECTS = \ $(am_indicator_messages_service_OBJECTS) -indicator_messages_service_DEPENDENCIES = $(am__DEPENDENCIES_1) \ - libindicator-messages-status-provider.la +indicator_messages_service_DEPENDENCIES = $(am__DEPENDENCIES_1) indicator_messages_service_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(indicator_messages_service_CFLAGS) $(CFLAGS) \ @@ -189,18 +149,15 @@ am__v_CCLD_0 = @echo " CCLD " $@; AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; -SOURCES = $(libemesene_la_SOURCES) \ - $(libindicator_messages_status_provider_la_SOURCES) \ - $(libmc5_la_SOURCES) $(libmessaging_la_SOURCES) \ - $(libpidgin_la_SOURCES) $(libtelepathy_la_SOURCES) \ +SOURCES = $(libmessaging_la_SOURCES) \ $(indicator_messages_service_SOURCES) -DIST_SOURCES = $(libemesene_la_SOURCES) \ - $(libindicator_messages_status_provider_la_SOURCES) \ - $(libmc5_la_SOURCES) $(libmessaging_la_SOURCES) \ - $(libpidgin_la_SOURCES) $(libtelepathy_la_SOURCES) \ +DIST_SOURCES = $(libmessaging_la_SOURCES) \ $(indicator_messages_service_SOURCES) -DATA = $(pkgconfig_DATA) -HEADERS = $(libindicator_messages_status_provider_la_HEADERS) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -246,12 +203,22 @@ FGREP = @FGREP@ GCOVR = @GCOVR@ GENHTML = @GENHTML@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GIO_CFLAGS = @GIO_CFLAGS@ +GIO_LIBS = @GIO_LIBS@ +GLIB_COMPILE_SCHEMAS = @GLIB_COMPILE_SCHEMAS@ GMOFILES = @GMOFILES@ GMSGFMT = @GMSGFMT@ GNOMELOCALEDIR = @GNOMELOCALEDIR@ GREP = @GREP@ +GSETTINGS_DISABLE_SCHEMAS_COMPILE = @GSETTINGS_DISABLE_SCHEMAS_COMPILE@ GTEST_CPPFLAGS = @GTEST_CPPFLAGS@ GTEST_SOURCE = @GTEST_SOURCE@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +HTML_DIR = @HTML_DIR@ INDICATORDIR = @INDICATORDIR@ INDICATORICONSDIR = @INDICATORICONSDIR@ INSTALL = @INSTALL@ @@ -269,6 +236,14 @@ INTLTOOL_V_MERGE = @INTLTOOL_V_MERGE@ INTLTOOL_V_MERGE_OPTIONS = @INTLTOOL_V_MERGE_OPTIONS@ INTLTOOL__v_MERGE_ = @INTLTOOL__v_MERGE_@ INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ @@ -312,14 +287,6 @@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SHTOOL = @SHTOOL@ -STATUS_PROVIDER_EMESENE_CFLAGS = @STATUS_PROVIDER_EMESENE_CFLAGS@ -STATUS_PROVIDER_EMESENE_LIBS = @STATUS_PROVIDER_EMESENE_LIBS@ -STATUS_PROVIDER_MC5_CFLAGS = @STATUS_PROVIDER_MC5_CFLAGS@ -STATUS_PROVIDER_MC5_LIBS = @STATUS_PROVIDER_MC5_LIBS@ -STATUS_PROVIDER_PIDGIN_CFLAGS = @STATUS_PROVIDER_PIDGIN_CFLAGS@ -STATUS_PROVIDER_PIDGIN_LIBS = @STATUS_PROVIDER_PIDGIN_LIBS@ -STATUS_PROVIDER_TELEPATHY_CFLAGS = @STATUS_PROVIDER_TELEPATHY_CFLAGS@ -STATUS_PROVIDER_TELEPATHY_LIBS = @STATUS_PROVIDER_TELEPATHY_LIBS@ STRIP = @STRIP@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ @@ -349,6 +316,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ +gsettingsschemadir = @gsettingsschemadir@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ @@ -379,22 +347,10 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -BUILT_SOURCES = gen-messages-service.xml.h gen-messages-service.xml.c \ - status-provider-pidgin-marshal.h \ - status-provider-pidgin-marshal.c \ - status-provider-telepathy-marshal.h \ - status-provider-telepathy-marshal.c \ - status-provider-mc5-marshal.h status-provider-mc5-marshal.c -EXTRA_DIST = messages-service.xml \ - indicator-messages-status-provider-0.5.pc.in.in \ - status-provider-pidgin.list status-provider-telepathy.list \ - status-provider-mc5.list - -###################################### -# Extras -###################################### -CLEANFILES = indicator-messages-status-provider-0.5.pc \ - $(BUILT_SOURCES) +BUILT_SOURCES = indicator-messages-service.c \ + indicator-messages-service.h +EXTRA_DIST = messages-service.xml +CLEANFILES = $(BUILT_SOURCES) DISTCLEANFILES = ###################################### @@ -404,9 +360,12 @@ messaginglibdir = $(INDICATORDIR) messaginglib_LTLIBRARIES = libmessaging.la libmessaging_la_SOURCES = \ indicator-messages.c \ - gen-messages-service.xml.h \ - gen-messages-service.xml.c \ - dbus-data.h + im-app-menu-item.c \ + im-app-menu-item.h \ + im-source-menu-item.c \ + im-source-menu-item.h \ + indicator-messages-service.c \ + indicator-messages-service.h libmessaging_la_CFLAGS = \ $(APPLET_CFLAGS) \ @@ -428,26 +387,18 @@ libmessaging_la_LDFLAGS = \ # Building the messages service ###################################### indicator_messages_service_SOURCES = \ - default-applications.h \ - default-applications.c \ messages-service.c \ - messages-service-dbus.c \ - messages-service-dbus.h \ - gen-messages-service.xml.h \ - gen-messages-service.xml.c \ - im-menu-item.c \ - im-menu-item.h \ - app-menu-item.c \ - app-menu-item.h \ - launcher-menu-item.c \ - launcher-menu-item.h \ - seen-db.c \ - seen-db.h \ - dirs.h \ + indicator-messages-service.c \ + indicator-messages-service.h \ + app-section.c \ + app-section.h \ dbus-data.h \ - \ - status-items.c \ - status-items.h + gactionmuxer.c \ + gactionmuxer.h \ + gsettingsstrv.c \ + gsettingsstrv.h \ + gmenuutils.c \ + gmenuutils.h indicator_messages_service_CFLAGS = \ $(APPLET_CFLAGS) \ @@ -457,138 +408,14 @@ indicator_messages_service_CFLAGS = \ -Wl,-z,defs \ -Wl,--as-needed \ -Werror \ - -DG_LOG_DOMAIN=\"Indicator-Messages\" \ - -DSTATUS_PROVIDER_DIR=\"$(STATUS_PROVIDER_DIR)\" + -DG_LOG_DOMAIN=\"Indicator-Messages\" indicator_messages_service_LDADD = \ - $(APPLET_LIBS) \ - libindicator-messages-status-provider.la + $(APPLET_LIBS) indicator_messages_service_LDFLAGS = \ $(COVERAGE_LDFLAGS) - -###################################### -# Status Provider Library -###################################### -STATUS_PROVIDER_API_VERSION = 1 -STATUS_PROVIDER_DIR = $(libexecdir)/status-providers/$(STATUS_PROVIDER_API_VERSION) -statusprovidersdir = $(STATUS_PROVIDER_DIR) - -###################################### -# Status provider: Pidgin -###################################### - -###################################### -# Status provider: Mission Control 4 -###################################### - -###################################### -# Status provider: Mission Control 5 -###################################### - -###################################### -# Status provider: Emesene -###################################### -statusproviders_LTLIBRARIES = libpidgin.la libtelepathy.la libmc5.la \ - libemesene.la -pkgconfig_DATA = indicator-messages-status-provider-0.5.pc -pkgconfigdir = $(libdir)/pkgconfig -lib_LTLIBRARIES = \ - libindicator-messages-status-provider.la - -libindicator_messages_status_provider_la_HEADERS = \ - status-provider.h - -libindicator_messages_status_provider_la_SOURCES = \ - $(libindicator_messages_status_provider_HEADERS) \ - status-provider.c - -libindicator_messages_status_provider_ladir = \ - $(includedir)/libindicator-messages-status-provider-$(STATUS_PROVIDER_API_VERSION)/ - -libindicator_messages_status_provider_la_LDFLAGS = \ - -version-info $(STATUS_PROVIDER_API_VERSION):0:0 \ - -no-undefined \ - -export-symbols-regex "^[^_].*" - -libindicator_messages_status_provider_la_LIBADD = \ - $(APPLET_LIBS) - -libindicator_messages_status_provider_la_CFLAGS = \ - $(APPLET_CFLAGS) \ - -Wall -Werror - -libpidgin_la_SOURCES = \ - status-provider-pidgin.h \ - status-provider-pidgin.c \ - status-provider-pidgin-marshal.h \ - status-provider-pidgin-marshal.c - -libpidgin_la_CFLAGS = \ - $(APPLET_CFLAGS) \ - $(STATUS_PROVIDER_PIDGIN_CFLAGS) \ - -Wall -Werror \ - -DG_LOG_DOMAIN=\"Status-Provider-Pidgin\" - -libpidgin_la_LIBADD = \ - libindicator-messages-status-provider.la \ - $(APPLET_LIBS) \ - $(STATUS_PROVIDER_PIDGIN_LIBS) - -libpidgin_la_LDFLAGS = -module -avoid-version -libtelepathy_la_SOURCES = \ - status-provider-telepathy.h \ - status-provider-telepathy.c \ - status-provider-telepathy-marshal.h \ - status-provider-telepathy-marshal.c - -libtelepathy_la_CFLAGS = \ - $(APPLET_CFLAGS) \ - $(STATUS_PROVIDER_TELEPATHY_CFLAGS) \ - -Wall -Werror \ - -DG_LOG_DOMAIN=\"Status-Provider-Telepathy\" - -libtelepathy_la_LIBADD = \ - libindicator-messages-status-provider.la \ - $(APPLET_LIBS) \ - $(STATUS_PROVIDER_TELEPATHY_LIBS) - -libtelepathy_la_LDFLAGS = -module -avoid-version -libmc5_la_SOURCES = \ - status-provider-mc5.h \ - status-provider-mc5.c \ - status-provider-mc5-marshal.h \ - status-provider-mc5-marshal.c - -libmc5_la_CFLAGS = \ - $(APPLET_CFLAGS) \ - $(STATUS_PROVIDER_MC5_CFLAGS) \ - -Wall -Werror \ - -DG_LOG_DOMAIN=\"Status-Provider-MC5\" - -libmc5_la_LIBADD = \ - libindicator-messages-status-provider.la \ - $(APPLET_LIBS) \ - $(STATUS_PROVIDER_MC5_LIBS) - -libmc5_la_LDFLAGS = -module -avoid-version -libemesene_la_SOURCES = \ - status-provider-emesene.h \ - status-provider-emesene.c - -libemesene_la_CFLAGS = \ - $(APPLET_CFLAGS) \ - $(STATUS_PROVIDER_EMESENE_CFLAGS) \ - -Wall -Werror \ - -DG_LOG_DOMAIN=\"Status-Provider-Emesene\" - -libemesene_la_LIBADD = \ - libindicator-messages-status-provider.la \ - $(APPLET_LIBS) \ - $(STATUS_PROVIDER_EMESENE_LIBS) - -libemesene_la_LDFLAGS = -module -avoid-version all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am @@ -624,42 +451,8 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -indicator-messages-status-provider-0.5.pc.in: $(top_builddir)/config.status $(srcdir)/indicator-messages-status-provider-0.5.pc.in.in - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ - } - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ - done - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_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 install-messaginglibLTLIBRARIES: $(messaginglib_LTLIBRARIES) @$(NORMAL_INSTALL) - test -z "$(messaginglibdir)" || $(MKDIR_P) "$(DESTDIR)$(messaginglibdir)" @list='$(messaginglib_LTLIBRARIES)'; test -n "$(messaginglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ @@ -667,6 +460,8 @@ install-messaginglibLTLIBRARIES: $(messaginglib_LTLIBRARIES) else :; fi; \ done; \ test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(messaginglibdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(messaginglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(messaginglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(messaginglibdir)"; \ } @@ -688,53 +483,15 @@ clean-messaginglibLTLIBRARIES: echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done -install-statusprovidersLTLIBRARIES: $(statusproviders_LTLIBRARIES) - @$(NORMAL_INSTALL) - test -z "$(statusprovidersdir)" || $(MKDIR_P) "$(DESTDIR)$(statusprovidersdir)" - @list='$(statusproviders_LTLIBRARIES)'; test -n "$(statusprovidersdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(statusprovidersdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(statusprovidersdir)"; \ - } - -uninstall-statusprovidersLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(statusproviders_LTLIBRARIES)'; test -n "$(statusprovidersdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(statusprovidersdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(statusprovidersdir)/$$f"; \ - done - -clean-statusprovidersLTLIBRARIES: - -test -z "$(statusproviders_LTLIBRARIES)" || rm -f $(statusproviders_LTLIBRARIES) - @list='$(statusproviders_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 -libemesene.la: $(libemesene_la_OBJECTS) $(libemesene_la_DEPENDENCIES) $(EXTRA_libemesene_la_DEPENDENCIES) - $(AM_V_CCLD)$(libemesene_la_LINK) -rpath $(statusprovidersdir) $(libemesene_la_OBJECTS) $(libemesene_la_LIBADD) $(LIBS) -libindicator-messages-status-provider.la: $(libindicator_messages_status_provider_la_OBJECTS) $(libindicator_messages_status_provider_la_DEPENDENCIES) $(EXTRA_libindicator_messages_status_provider_la_DEPENDENCIES) - $(AM_V_CCLD)$(libindicator_messages_status_provider_la_LINK) -rpath $(libdir) $(libindicator_messages_status_provider_la_OBJECTS) $(libindicator_messages_status_provider_la_LIBADD) $(LIBS) -libmc5.la: $(libmc5_la_OBJECTS) $(libmc5_la_DEPENDENCIES) $(EXTRA_libmc5_la_DEPENDENCIES) - $(AM_V_CCLD)$(libmc5_la_LINK) -rpath $(statusprovidersdir) $(libmc5_la_OBJECTS) $(libmc5_la_LIBADD) $(LIBS) libmessaging.la: $(libmessaging_la_OBJECTS) $(libmessaging_la_DEPENDENCIES) $(EXTRA_libmessaging_la_DEPENDENCIES) $(AM_V_CCLD)$(libmessaging_la_LINK) -rpath $(messaginglibdir) $(libmessaging_la_OBJECTS) $(libmessaging_la_LIBADD) $(LIBS) -libpidgin.la: $(libpidgin_la_OBJECTS) $(libpidgin_la_DEPENDENCIES) $(EXTRA_libpidgin_la_DEPENDENCIES) - $(AM_V_CCLD)$(libpidgin_la_LINK) -rpath $(statusprovidersdir) $(libpidgin_la_OBJECTS) $(libpidgin_la_LIBADD) $(LIBS) -libtelepathy.la: $(libtelepathy_la_OBJECTS) $(libtelepathy_la_DEPENDENCIES) $(EXTRA_libtelepathy_la_DEPENDENCIES) - $(AM_V_CCLD)$(libtelepathy_la_LINK) -rpath $(statusprovidersdir) $(libtelepathy_la_OBJECTS) $(libtelepathy_la_LIBADD) $(LIBS) install-libexecPROGRAMS: $(libexec_PROGRAMS) @$(NORMAL_INSTALL) - test -z "$(libexecdir)" || $(MKDIR_P) "$(DESTDIR)$(libexecdir)" @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(libexecdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libexecdir)" || exit 1; \ + fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ @@ -784,25 +541,16 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_messages_service-app-menu-item.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_messages_service-default-applications.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_messages_service-gen-messages-service.xml.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_messages_service-im-menu-item.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_messages_service-launcher-menu-item.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_messages_service-messages-service-dbus.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_messages_service-app-section.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_messages_service-gactionmuxer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_messages_service-gmenuutils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_messages_service-gsettingsstrv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_messages_service-indicator-messages-service.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_messages_service-messages-service.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_messages_service-seen-db.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_messages_service-status-items.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libemesene_la-status-provider-emesene.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libindicator_messages_status_provider_la-status-provider.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmc5_la-status-provider-mc5-marshal.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmc5_la-status-provider-mc5.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmessaging_la-gen-messages-service.xml.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmessaging_la-im-app-menu-item.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmessaging_la-im-source-menu-item.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmessaging_la-indicator-messages-service.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmessaging_la-indicator-messages.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpidgin_la-status-provider-pidgin-marshal.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpidgin_la-status-provider-pidgin.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtelepathy_la-status-provider-telepathy-marshal.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtelepathy_la-status-provider-telepathy.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -825,34 +573,6 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< -libemesene_la-status-provider-emesene.lo: status-provider-emesene.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libemesene_la_CFLAGS) $(CFLAGS) -MT libemesene_la-status-provider-emesene.lo -MD -MP -MF $(DEPDIR)/libemesene_la-status-provider-emesene.Tpo -c -o libemesene_la-status-provider-emesene.lo `test -f 'status-provider-emesene.c' || echo '$(srcdir)/'`status-provider-emesene.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libemesene_la-status-provider-emesene.Tpo $(DEPDIR)/libemesene_la-status-provider-emesene.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='status-provider-emesene.c' object='libemesene_la-status-provider-emesene.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libemesene_la_CFLAGS) $(CFLAGS) -c -o libemesene_la-status-provider-emesene.lo `test -f 'status-provider-emesene.c' || echo '$(srcdir)/'`status-provider-emesene.c - -libindicator_messages_status_provider_la-status-provider.lo: status-provider.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libindicator_messages_status_provider_la_CFLAGS) $(CFLAGS) -MT libindicator_messages_status_provider_la-status-provider.lo -MD -MP -MF $(DEPDIR)/libindicator_messages_status_provider_la-status-provider.Tpo -c -o libindicator_messages_status_provider_la-status-provider.lo `test -f 'status-provider.c' || echo '$(srcdir)/'`status-provider.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libindicator_messages_status_provider_la-status-provider.Tpo $(DEPDIR)/libindicator_messages_status_provider_la-status-provider.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='status-provider.c' object='libindicator_messages_status_provider_la-status-provider.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libindicator_messages_status_provider_la_CFLAGS) $(CFLAGS) -c -o libindicator_messages_status_provider_la-status-provider.lo `test -f 'status-provider.c' || echo '$(srcdir)/'`status-provider.c - -libmc5_la-status-provider-mc5.lo: status-provider-mc5.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmc5_la_CFLAGS) $(CFLAGS) -MT libmc5_la-status-provider-mc5.lo -MD -MP -MF $(DEPDIR)/libmc5_la-status-provider-mc5.Tpo -c -o libmc5_la-status-provider-mc5.lo `test -f 'status-provider-mc5.c' || echo '$(srcdir)/'`status-provider-mc5.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmc5_la-status-provider-mc5.Tpo $(DEPDIR)/libmc5_la-status-provider-mc5.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='status-provider-mc5.c' object='libmc5_la-status-provider-mc5.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmc5_la_CFLAGS) $(CFLAGS) -c -o libmc5_la-status-provider-mc5.lo `test -f 'status-provider-mc5.c' || echo '$(srcdir)/'`status-provider-mc5.c - -libmc5_la-status-provider-mc5-marshal.lo: status-provider-mc5-marshal.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmc5_la_CFLAGS) $(CFLAGS) -MT libmc5_la-status-provider-mc5-marshal.lo -MD -MP -MF $(DEPDIR)/libmc5_la-status-provider-mc5-marshal.Tpo -c -o libmc5_la-status-provider-mc5-marshal.lo `test -f 'status-provider-mc5-marshal.c' || echo '$(srcdir)/'`status-provider-mc5-marshal.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmc5_la-status-provider-mc5-marshal.Tpo $(DEPDIR)/libmc5_la-status-provider-mc5-marshal.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='status-provider-mc5-marshal.c' object='libmc5_la-status-provider-mc5-marshal.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmc5_la_CFLAGS) $(CFLAGS) -c -o libmc5_la-status-provider-mc5-marshal.lo `test -f 'status-provider-mc5-marshal.c' || echo '$(srcdir)/'`status-provider-mc5-marshal.c - libmessaging_la-indicator-messages.lo: indicator-messages.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmessaging_la_CFLAGS) $(CFLAGS) -MT libmessaging_la-indicator-messages.lo -MD -MP -MF $(DEPDIR)/libmessaging_la-indicator-messages.Tpo -c -o libmessaging_la-indicator-messages.lo `test -f 'indicator-messages.c' || echo '$(srcdir)/'`indicator-messages.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmessaging_la-indicator-messages.Tpo $(DEPDIR)/libmessaging_la-indicator-messages.Plo @@ -860,54 +580,26 @@ libmessaging_la-indicator-messages.lo: indicator-messages.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmessaging_la_CFLAGS) $(CFLAGS) -c -o libmessaging_la-indicator-messages.lo `test -f 'indicator-messages.c' || echo '$(srcdir)/'`indicator-messages.c -libmessaging_la-gen-messages-service.xml.lo: gen-messages-service.xml.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmessaging_la_CFLAGS) $(CFLAGS) -MT libmessaging_la-gen-messages-service.xml.lo -MD -MP -MF $(DEPDIR)/libmessaging_la-gen-messages-service.xml.Tpo -c -o libmessaging_la-gen-messages-service.xml.lo `test -f 'gen-messages-service.xml.c' || echo '$(srcdir)/'`gen-messages-service.xml.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmessaging_la-gen-messages-service.xml.Tpo $(DEPDIR)/libmessaging_la-gen-messages-service.xml.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen-messages-service.xml.c' object='libmessaging_la-gen-messages-service.xml.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmessaging_la_CFLAGS) $(CFLAGS) -c -o libmessaging_la-gen-messages-service.xml.lo `test -f 'gen-messages-service.xml.c' || echo '$(srcdir)/'`gen-messages-service.xml.c - -libpidgin_la-status-provider-pidgin.lo: status-provider-pidgin.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpidgin_la_CFLAGS) $(CFLAGS) -MT libpidgin_la-status-provider-pidgin.lo -MD -MP -MF $(DEPDIR)/libpidgin_la-status-provider-pidgin.Tpo -c -o libpidgin_la-status-provider-pidgin.lo `test -f 'status-provider-pidgin.c' || echo '$(srcdir)/'`status-provider-pidgin.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpidgin_la-status-provider-pidgin.Tpo $(DEPDIR)/libpidgin_la-status-provider-pidgin.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='status-provider-pidgin.c' object='libpidgin_la-status-provider-pidgin.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpidgin_la_CFLAGS) $(CFLAGS) -c -o libpidgin_la-status-provider-pidgin.lo `test -f 'status-provider-pidgin.c' || echo '$(srcdir)/'`status-provider-pidgin.c - -libpidgin_la-status-provider-pidgin-marshal.lo: status-provider-pidgin-marshal.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpidgin_la_CFLAGS) $(CFLAGS) -MT libpidgin_la-status-provider-pidgin-marshal.lo -MD -MP -MF $(DEPDIR)/libpidgin_la-status-provider-pidgin-marshal.Tpo -c -o libpidgin_la-status-provider-pidgin-marshal.lo `test -f 'status-provider-pidgin-marshal.c' || echo '$(srcdir)/'`status-provider-pidgin-marshal.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libpidgin_la-status-provider-pidgin-marshal.Tpo $(DEPDIR)/libpidgin_la-status-provider-pidgin-marshal.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='status-provider-pidgin-marshal.c' object='libpidgin_la-status-provider-pidgin-marshal.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpidgin_la_CFLAGS) $(CFLAGS) -c -o libpidgin_la-status-provider-pidgin-marshal.lo `test -f 'status-provider-pidgin-marshal.c' || echo '$(srcdir)/'`status-provider-pidgin-marshal.c - -libtelepathy_la-status-provider-telepathy.lo: status-provider-telepathy.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtelepathy_la_CFLAGS) $(CFLAGS) -MT libtelepathy_la-status-provider-telepathy.lo -MD -MP -MF $(DEPDIR)/libtelepathy_la-status-provider-telepathy.Tpo -c -o libtelepathy_la-status-provider-telepathy.lo `test -f 'status-provider-telepathy.c' || echo '$(srcdir)/'`status-provider-telepathy.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtelepathy_la-status-provider-telepathy.Tpo $(DEPDIR)/libtelepathy_la-status-provider-telepathy.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='status-provider-telepathy.c' object='libtelepathy_la-status-provider-telepathy.lo' libtool=yes @AMDEPBACKSLASH@ +libmessaging_la-im-app-menu-item.lo: im-app-menu-item.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmessaging_la_CFLAGS) $(CFLAGS) -MT libmessaging_la-im-app-menu-item.lo -MD -MP -MF $(DEPDIR)/libmessaging_la-im-app-menu-item.Tpo -c -o libmessaging_la-im-app-menu-item.lo `test -f 'im-app-menu-item.c' || echo '$(srcdir)/'`im-app-menu-item.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmessaging_la-im-app-menu-item.Tpo $(DEPDIR)/libmessaging_la-im-app-menu-item.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='im-app-menu-item.c' object='libmessaging_la-im-app-menu-item.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtelepathy_la_CFLAGS) $(CFLAGS) -c -o libtelepathy_la-status-provider-telepathy.lo `test -f 'status-provider-telepathy.c' || echo '$(srcdir)/'`status-provider-telepathy.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmessaging_la_CFLAGS) $(CFLAGS) -c -o libmessaging_la-im-app-menu-item.lo `test -f 'im-app-menu-item.c' || echo '$(srcdir)/'`im-app-menu-item.c -libtelepathy_la-status-provider-telepathy-marshal.lo: status-provider-telepathy-marshal.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtelepathy_la_CFLAGS) $(CFLAGS) -MT libtelepathy_la-status-provider-telepathy-marshal.lo -MD -MP -MF $(DEPDIR)/libtelepathy_la-status-provider-telepathy-marshal.Tpo -c -o libtelepathy_la-status-provider-telepathy-marshal.lo `test -f 'status-provider-telepathy-marshal.c' || echo '$(srcdir)/'`status-provider-telepathy-marshal.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libtelepathy_la-status-provider-telepathy-marshal.Tpo $(DEPDIR)/libtelepathy_la-status-provider-telepathy-marshal.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='status-provider-telepathy-marshal.c' object='libtelepathy_la-status-provider-telepathy-marshal.lo' libtool=yes @AMDEPBACKSLASH@ +libmessaging_la-im-source-menu-item.lo: im-source-menu-item.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmessaging_la_CFLAGS) $(CFLAGS) -MT libmessaging_la-im-source-menu-item.lo -MD -MP -MF $(DEPDIR)/libmessaging_la-im-source-menu-item.Tpo -c -o libmessaging_la-im-source-menu-item.lo `test -f 'im-source-menu-item.c' || echo '$(srcdir)/'`im-source-menu-item.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmessaging_la-im-source-menu-item.Tpo $(DEPDIR)/libmessaging_la-im-source-menu-item.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='im-source-menu-item.c' object='libmessaging_la-im-source-menu-item.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtelepathy_la_CFLAGS) $(CFLAGS) -c -o libtelepathy_la-status-provider-telepathy-marshal.lo `test -f 'status-provider-telepathy-marshal.c' || echo '$(srcdir)/'`status-provider-telepathy-marshal.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmessaging_la_CFLAGS) $(CFLAGS) -c -o libmessaging_la-im-source-menu-item.lo `test -f 'im-source-menu-item.c' || echo '$(srcdir)/'`im-source-menu-item.c -indicator_messages_service-default-applications.o: default-applications.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-default-applications.o -MD -MP -MF $(DEPDIR)/indicator_messages_service-default-applications.Tpo -c -o indicator_messages_service-default-applications.o `test -f 'default-applications.c' || echo '$(srcdir)/'`default-applications.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-default-applications.Tpo $(DEPDIR)/indicator_messages_service-default-applications.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='default-applications.c' object='indicator_messages_service-default-applications.o' libtool=no @AMDEPBACKSLASH@ +libmessaging_la-indicator-messages-service.lo: indicator-messages-service.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmessaging_la_CFLAGS) $(CFLAGS) -MT libmessaging_la-indicator-messages-service.lo -MD -MP -MF $(DEPDIR)/libmessaging_la-indicator-messages-service.Tpo -c -o libmessaging_la-indicator-messages-service.lo `test -f 'indicator-messages-service.c' || echo '$(srcdir)/'`indicator-messages-service.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmessaging_la-indicator-messages-service.Tpo $(DEPDIR)/libmessaging_la-indicator-messages-service.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='indicator-messages-service.c' object='libmessaging_la-indicator-messages-service.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-default-applications.o `test -f 'default-applications.c' || echo '$(srcdir)/'`default-applications.c - -indicator_messages_service-default-applications.obj: default-applications.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-default-applications.obj -MD -MP -MF $(DEPDIR)/indicator_messages_service-default-applications.Tpo -c -o indicator_messages_service-default-applications.obj `if test -f 'default-applications.c'; then $(CYGPATH_W) 'default-applications.c'; else $(CYGPATH_W) '$(srcdir)/default-applications.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-default-applications.Tpo $(DEPDIR)/indicator_messages_service-default-applications.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='default-applications.c' object='indicator_messages_service-default-applications.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-default-applications.obj `if test -f 'default-applications.c'; then $(CYGPATH_W) 'default-applications.c'; else $(CYGPATH_W) '$(srcdir)/default-applications.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libmessaging_la_CFLAGS) $(CFLAGS) -c -o libmessaging_la-indicator-messages-service.lo `test -f 'indicator-messages-service.c' || echo '$(srcdir)/'`indicator-messages-service.c indicator_messages_service-messages-service.o: messages-service.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-messages-service.o -MD -MP -MF $(DEPDIR)/indicator_messages_service-messages-service.Tpo -c -o indicator_messages_service-messages-service.o `test -f 'messages-service.c' || echo '$(srcdir)/'`messages-service.c @@ -923,145 +615,81 @@ indicator_messages_service-messages-service.obj: messages-service.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-messages-service.obj `if test -f 'messages-service.c'; then $(CYGPATH_W) 'messages-service.c'; else $(CYGPATH_W) '$(srcdir)/messages-service.c'; fi` -indicator_messages_service-messages-service-dbus.o: messages-service-dbus.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-messages-service-dbus.o -MD -MP -MF $(DEPDIR)/indicator_messages_service-messages-service-dbus.Tpo -c -o indicator_messages_service-messages-service-dbus.o `test -f 'messages-service-dbus.c' || echo '$(srcdir)/'`messages-service-dbus.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-messages-service-dbus.Tpo $(DEPDIR)/indicator_messages_service-messages-service-dbus.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='messages-service-dbus.c' object='indicator_messages_service-messages-service-dbus.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-messages-service-dbus.o `test -f 'messages-service-dbus.c' || echo '$(srcdir)/'`messages-service-dbus.c - -indicator_messages_service-messages-service-dbus.obj: messages-service-dbus.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-messages-service-dbus.obj -MD -MP -MF $(DEPDIR)/indicator_messages_service-messages-service-dbus.Tpo -c -o indicator_messages_service-messages-service-dbus.obj `if test -f 'messages-service-dbus.c'; then $(CYGPATH_W) 'messages-service-dbus.c'; else $(CYGPATH_W) '$(srcdir)/messages-service-dbus.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-messages-service-dbus.Tpo $(DEPDIR)/indicator_messages_service-messages-service-dbus.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='messages-service-dbus.c' object='indicator_messages_service-messages-service-dbus.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-messages-service-dbus.obj `if test -f 'messages-service-dbus.c'; then $(CYGPATH_W) 'messages-service-dbus.c'; else $(CYGPATH_W) '$(srcdir)/messages-service-dbus.c'; fi` - -indicator_messages_service-gen-messages-service.xml.o: gen-messages-service.xml.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-gen-messages-service.xml.o -MD -MP -MF $(DEPDIR)/indicator_messages_service-gen-messages-service.xml.Tpo -c -o indicator_messages_service-gen-messages-service.xml.o `test -f 'gen-messages-service.xml.c' || echo '$(srcdir)/'`gen-messages-service.xml.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-gen-messages-service.xml.Tpo $(DEPDIR)/indicator_messages_service-gen-messages-service.xml.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen-messages-service.xml.c' object='indicator_messages_service-gen-messages-service.xml.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-gen-messages-service.xml.o `test -f 'gen-messages-service.xml.c' || echo '$(srcdir)/'`gen-messages-service.xml.c - -indicator_messages_service-gen-messages-service.xml.obj: gen-messages-service.xml.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-gen-messages-service.xml.obj -MD -MP -MF $(DEPDIR)/indicator_messages_service-gen-messages-service.xml.Tpo -c -o indicator_messages_service-gen-messages-service.xml.obj `if test -f 'gen-messages-service.xml.c'; then $(CYGPATH_W) 'gen-messages-service.xml.c'; else $(CYGPATH_W) '$(srcdir)/gen-messages-service.xml.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-gen-messages-service.xml.Tpo $(DEPDIR)/indicator_messages_service-gen-messages-service.xml.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gen-messages-service.xml.c' object='indicator_messages_service-gen-messages-service.xml.obj' libtool=no @AMDEPBACKSLASH@ +indicator_messages_service-indicator-messages-service.o: indicator-messages-service.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-indicator-messages-service.o -MD -MP -MF $(DEPDIR)/indicator_messages_service-indicator-messages-service.Tpo -c -o indicator_messages_service-indicator-messages-service.o `test -f 'indicator-messages-service.c' || echo '$(srcdir)/'`indicator-messages-service.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-indicator-messages-service.Tpo $(DEPDIR)/indicator_messages_service-indicator-messages-service.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='indicator-messages-service.c' object='indicator_messages_service-indicator-messages-service.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-gen-messages-service.xml.obj `if test -f 'gen-messages-service.xml.c'; then $(CYGPATH_W) 'gen-messages-service.xml.c'; else $(CYGPATH_W) '$(srcdir)/gen-messages-service.xml.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-indicator-messages-service.o `test -f 'indicator-messages-service.c' || echo '$(srcdir)/'`indicator-messages-service.c -indicator_messages_service-im-menu-item.o: im-menu-item.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-im-menu-item.o -MD -MP -MF $(DEPDIR)/indicator_messages_service-im-menu-item.Tpo -c -o indicator_messages_service-im-menu-item.o `test -f 'im-menu-item.c' || echo '$(srcdir)/'`im-menu-item.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-im-menu-item.Tpo $(DEPDIR)/indicator_messages_service-im-menu-item.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='im-menu-item.c' object='indicator_messages_service-im-menu-item.o' libtool=no @AMDEPBACKSLASH@ +indicator_messages_service-indicator-messages-service.obj: indicator-messages-service.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-indicator-messages-service.obj -MD -MP -MF $(DEPDIR)/indicator_messages_service-indicator-messages-service.Tpo -c -o indicator_messages_service-indicator-messages-service.obj `if test -f 'indicator-messages-service.c'; then $(CYGPATH_W) 'indicator-messages-service.c'; else $(CYGPATH_W) '$(srcdir)/indicator-messages-service.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-indicator-messages-service.Tpo $(DEPDIR)/indicator_messages_service-indicator-messages-service.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='indicator-messages-service.c' object='indicator_messages_service-indicator-messages-service.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-im-menu-item.o `test -f 'im-menu-item.c' || echo '$(srcdir)/'`im-menu-item.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-indicator-messages-service.obj `if test -f 'indicator-messages-service.c'; then $(CYGPATH_W) 'indicator-messages-service.c'; else $(CYGPATH_W) '$(srcdir)/indicator-messages-service.c'; fi` -indicator_messages_service-im-menu-item.obj: im-menu-item.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-im-menu-item.obj -MD -MP -MF $(DEPDIR)/indicator_messages_service-im-menu-item.Tpo -c -o indicator_messages_service-im-menu-item.obj `if test -f 'im-menu-item.c'; then $(CYGPATH_W) 'im-menu-item.c'; else $(CYGPATH_W) '$(srcdir)/im-menu-item.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-im-menu-item.Tpo $(DEPDIR)/indicator_messages_service-im-menu-item.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='im-menu-item.c' object='indicator_messages_service-im-menu-item.obj' libtool=no @AMDEPBACKSLASH@ +indicator_messages_service-app-section.o: app-section.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-app-section.o -MD -MP -MF $(DEPDIR)/indicator_messages_service-app-section.Tpo -c -o indicator_messages_service-app-section.o `test -f 'app-section.c' || echo '$(srcdir)/'`app-section.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-app-section.Tpo $(DEPDIR)/indicator_messages_service-app-section.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='app-section.c' object='indicator_messages_service-app-section.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-im-menu-item.obj `if test -f 'im-menu-item.c'; then $(CYGPATH_W) 'im-menu-item.c'; else $(CYGPATH_W) '$(srcdir)/im-menu-item.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-app-section.o `test -f 'app-section.c' || echo '$(srcdir)/'`app-section.c -indicator_messages_service-app-menu-item.o: app-menu-item.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-app-menu-item.o -MD -MP -MF $(DEPDIR)/indicator_messages_service-app-menu-item.Tpo -c -o indicator_messages_service-app-menu-item.o `test -f 'app-menu-item.c' || echo '$(srcdir)/'`app-menu-item.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-app-menu-item.Tpo $(DEPDIR)/indicator_messages_service-app-menu-item.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='app-menu-item.c' object='indicator_messages_service-app-menu-item.o' libtool=no @AMDEPBACKSLASH@ +indicator_messages_service-app-section.obj: app-section.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-app-section.obj -MD -MP -MF $(DEPDIR)/indicator_messages_service-app-section.Tpo -c -o indicator_messages_service-app-section.obj `if test -f 'app-section.c'; then $(CYGPATH_W) 'app-section.c'; else $(CYGPATH_W) '$(srcdir)/app-section.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-app-section.Tpo $(DEPDIR)/indicator_messages_service-app-section.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='app-section.c' object='indicator_messages_service-app-section.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-app-menu-item.o `test -f 'app-menu-item.c' || echo '$(srcdir)/'`app-menu-item.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-app-section.obj `if test -f 'app-section.c'; then $(CYGPATH_W) 'app-section.c'; else $(CYGPATH_W) '$(srcdir)/app-section.c'; fi` -indicator_messages_service-app-menu-item.obj: app-menu-item.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-app-menu-item.obj -MD -MP -MF $(DEPDIR)/indicator_messages_service-app-menu-item.Tpo -c -o indicator_messages_service-app-menu-item.obj `if test -f 'app-menu-item.c'; then $(CYGPATH_W) 'app-menu-item.c'; else $(CYGPATH_W) '$(srcdir)/app-menu-item.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-app-menu-item.Tpo $(DEPDIR)/indicator_messages_service-app-menu-item.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='app-menu-item.c' object='indicator_messages_service-app-menu-item.obj' libtool=no @AMDEPBACKSLASH@ +indicator_messages_service-gactionmuxer.o: gactionmuxer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-gactionmuxer.o -MD -MP -MF $(DEPDIR)/indicator_messages_service-gactionmuxer.Tpo -c -o indicator_messages_service-gactionmuxer.o `test -f 'gactionmuxer.c' || echo '$(srcdir)/'`gactionmuxer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-gactionmuxer.Tpo $(DEPDIR)/indicator_messages_service-gactionmuxer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gactionmuxer.c' object='indicator_messages_service-gactionmuxer.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-app-menu-item.obj `if test -f 'app-menu-item.c'; then $(CYGPATH_W) 'app-menu-item.c'; else $(CYGPATH_W) '$(srcdir)/app-menu-item.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-gactionmuxer.o `test -f 'gactionmuxer.c' || echo '$(srcdir)/'`gactionmuxer.c -indicator_messages_service-launcher-menu-item.o: launcher-menu-item.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-launcher-menu-item.o -MD -MP -MF $(DEPDIR)/indicator_messages_service-launcher-menu-item.Tpo -c -o indicator_messages_service-launcher-menu-item.o `test -f 'launcher-menu-item.c' || echo '$(srcdir)/'`launcher-menu-item.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-launcher-menu-item.Tpo $(DEPDIR)/indicator_messages_service-launcher-menu-item.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='launcher-menu-item.c' object='indicator_messages_service-launcher-menu-item.o' libtool=no @AMDEPBACKSLASH@ +indicator_messages_service-gactionmuxer.obj: gactionmuxer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-gactionmuxer.obj -MD -MP -MF $(DEPDIR)/indicator_messages_service-gactionmuxer.Tpo -c -o indicator_messages_service-gactionmuxer.obj `if test -f 'gactionmuxer.c'; then $(CYGPATH_W) 'gactionmuxer.c'; else $(CYGPATH_W) '$(srcdir)/gactionmuxer.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-gactionmuxer.Tpo $(DEPDIR)/indicator_messages_service-gactionmuxer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gactionmuxer.c' object='indicator_messages_service-gactionmuxer.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-launcher-menu-item.o `test -f 'launcher-menu-item.c' || echo '$(srcdir)/'`launcher-menu-item.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-gactionmuxer.obj `if test -f 'gactionmuxer.c'; then $(CYGPATH_W) 'gactionmuxer.c'; else $(CYGPATH_W) '$(srcdir)/gactionmuxer.c'; fi` -indicator_messages_service-launcher-menu-item.obj: launcher-menu-item.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-launcher-menu-item.obj -MD -MP -MF $(DEPDIR)/indicator_messages_service-launcher-menu-item.Tpo -c -o indicator_messages_service-launcher-menu-item.obj `if test -f 'launcher-menu-item.c'; then $(CYGPATH_W) 'launcher-menu-item.c'; else $(CYGPATH_W) '$(srcdir)/launcher-menu-item.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-launcher-menu-item.Tpo $(DEPDIR)/indicator_messages_service-launcher-menu-item.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='launcher-menu-item.c' object='indicator_messages_service-launcher-menu-item.obj' libtool=no @AMDEPBACKSLASH@ +indicator_messages_service-gsettingsstrv.o: gsettingsstrv.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-gsettingsstrv.o -MD -MP -MF $(DEPDIR)/indicator_messages_service-gsettingsstrv.Tpo -c -o indicator_messages_service-gsettingsstrv.o `test -f 'gsettingsstrv.c' || echo '$(srcdir)/'`gsettingsstrv.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-gsettingsstrv.Tpo $(DEPDIR)/indicator_messages_service-gsettingsstrv.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gsettingsstrv.c' object='indicator_messages_service-gsettingsstrv.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-launcher-menu-item.obj `if test -f 'launcher-menu-item.c'; then $(CYGPATH_W) 'launcher-menu-item.c'; else $(CYGPATH_W) '$(srcdir)/launcher-menu-item.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-gsettingsstrv.o `test -f 'gsettingsstrv.c' || echo '$(srcdir)/'`gsettingsstrv.c -indicator_messages_service-seen-db.o: seen-db.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-seen-db.o -MD -MP -MF $(DEPDIR)/indicator_messages_service-seen-db.Tpo -c -o indicator_messages_service-seen-db.o `test -f 'seen-db.c' || echo '$(srcdir)/'`seen-db.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-seen-db.Tpo $(DEPDIR)/indicator_messages_service-seen-db.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='seen-db.c' object='indicator_messages_service-seen-db.o' libtool=no @AMDEPBACKSLASH@ +indicator_messages_service-gsettingsstrv.obj: gsettingsstrv.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-gsettingsstrv.obj -MD -MP -MF $(DEPDIR)/indicator_messages_service-gsettingsstrv.Tpo -c -o indicator_messages_service-gsettingsstrv.obj `if test -f 'gsettingsstrv.c'; then $(CYGPATH_W) 'gsettingsstrv.c'; else $(CYGPATH_W) '$(srcdir)/gsettingsstrv.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-gsettingsstrv.Tpo $(DEPDIR)/indicator_messages_service-gsettingsstrv.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gsettingsstrv.c' object='indicator_messages_service-gsettingsstrv.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-seen-db.o `test -f 'seen-db.c' || echo '$(srcdir)/'`seen-db.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-gsettingsstrv.obj `if test -f 'gsettingsstrv.c'; then $(CYGPATH_W) 'gsettingsstrv.c'; else $(CYGPATH_W) '$(srcdir)/gsettingsstrv.c'; fi` -indicator_messages_service-seen-db.obj: seen-db.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-seen-db.obj -MD -MP -MF $(DEPDIR)/indicator_messages_service-seen-db.Tpo -c -o indicator_messages_service-seen-db.obj `if test -f 'seen-db.c'; then $(CYGPATH_W) 'seen-db.c'; else $(CYGPATH_W) '$(srcdir)/seen-db.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-seen-db.Tpo $(DEPDIR)/indicator_messages_service-seen-db.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='seen-db.c' object='indicator_messages_service-seen-db.obj' libtool=no @AMDEPBACKSLASH@ +indicator_messages_service-gmenuutils.o: gmenuutils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-gmenuutils.o -MD -MP -MF $(DEPDIR)/indicator_messages_service-gmenuutils.Tpo -c -o indicator_messages_service-gmenuutils.o `test -f 'gmenuutils.c' || echo '$(srcdir)/'`gmenuutils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-gmenuutils.Tpo $(DEPDIR)/indicator_messages_service-gmenuutils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gmenuutils.c' object='indicator_messages_service-gmenuutils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-seen-db.obj `if test -f 'seen-db.c'; then $(CYGPATH_W) 'seen-db.c'; else $(CYGPATH_W) '$(srcdir)/seen-db.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-gmenuutils.o `test -f 'gmenuutils.c' || echo '$(srcdir)/'`gmenuutils.c -indicator_messages_service-status-items.o: status-items.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-status-items.o -MD -MP -MF $(DEPDIR)/indicator_messages_service-status-items.Tpo -c -o indicator_messages_service-status-items.o `test -f 'status-items.c' || echo '$(srcdir)/'`status-items.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-status-items.Tpo $(DEPDIR)/indicator_messages_service-status-items.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='status-items.c' object='indicator_messages_service-status-items.o' libtool=no @AMDEPBACKSLASH@ +indicator_messages_service-gmenuutils.obj: gmenuutils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-gmenuutils.obj -MD -MP -MF $(DEPDIR)/indicator_messages_service-gmenuutils.Tpo -c -o indicator_messages_service-gmenuutils.obj `if test -f 'gmenuutils.c'; then $(CYGPATH_W) 'gmenuutils.c'; else $(CYGPATH_W) '$(srcdir)/gmenuutils.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-gmenuutils.Tpo $(DEPDIR)/indicator_messages_service-gmenuutils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gmenuutils.c' object='indicator_messages_service-gmenuutils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-status-items.o `test -f 'status-items.c' || echo '$(srcdir)/'`status-items.c - -indicator_messages_service-status-items.obj: status-items.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -MT indicator_messages_service-status-items.obj -MD -MP -MF $(DEPDIR)/indicator_messages_service-status-items.Tpo -c -o indicator_messages_service-status-items.obj `if test -f 'status-items.c'; then $(CYGPATH_W) 'status-items.c'; else $(CYGPATH_W) '$(srcdir)/status-items.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_messages_service-status-items.Tpo $(DEPDIR)/indicator_messages_service-status-items.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='status-items.c' object='indicator_messages_service-status-items.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-status-items.obj `if test -f 'status-items.c'; then $(CYGPATH_W) 'status-items.c'; else $(CYGPATH_W) '$(srcdir)/status-items.c'; fi` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_messages_service_CFLAGS) $(CFLAGS) -c -o indicator_messages_service-gmenuutils.obj `if test -f 'gmenuutils.c'; then $(CYGPATH_W) 'gmenuutils.c'; else $(CYGPATH_W) '$(srcdir)/gmenuutils.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -install-pkgconfigDATA: $(pkgconfig_DATA) - @$(NORMAL_INSTALL) - test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" - @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ - done - -uninstall-pkgconfigDATA: - @$(NORMAL_UNINSTALL) - @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) -install-libindicator_messages_status_provider_laHEADERS: $(libindicator_messages_status_provider_la_HEADERS) - @$(NORMAL_INSTALL) - test -z "$(libindicator_messages_status_provider_ladir)" || $(MKDIR_P) "$(DESTDIR)$(libindicator_messages_status_provider_ladir)" - @list='$(libindicator_messages_status_provider_la_HEADERS)'; test -n "$(libindicator_messages_status_provider_ladir)" || list=; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libindicator_messages_status_provider_ladir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(libindicator_messages_status_provider_ladir)" || exit $$?; \ - done - -uninstall-libindicator_messages_status_provider_laHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(libindicator_messages_status_provider_la_HEADERS)'; test -n "$(libindicator_messages_status_provider_ladir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(libindicator_messages_status_provider_ladir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ @@ -1148,9 +776,9 @@ distdir: $(DISTFILES) check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am -all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) $(HEADERS) +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(messaginglibdir)" "$(DESTDIR)$(statusprovidersdir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(libindicator_messages_status_provider_ladir)"; do \ + for dir in "$(DESTDIR)$(messaginglibdir)" "$(DESTDIR)$(libexecdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) @@ -1189,9 +817,8 @@ maintainer-clean-generic: -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-am -clean-am: clean-generic clean-libLTLIBRARIES clean-libexecPROGRAMS \ - clean-libtool clean-messaginglibLTLIBRARIES \ - clean-statusprovidersLTLIBRARIES mostlyclean-am +clean-am: clean-generic clean-libexecPROGRAMS clean-libtool \ + clean-messaginglibLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) @@ -1211,16 +838,13 @@ info: info-am info-am: -install-data-am: \ - install-libindicator_messages_status_provider_laHEADERS \ - install-messaginglibLTLIBRARIES install-pkgconfigDATA \ - install-statusprovidersLTLIBRARIES +install-data-am: install-messaginglibLTLIBRARIES install-dvi: install-dvi-am install-dvi-am: -install-exec-am: install-libLTLIBRARIES install-libexecPROGRAMS +install-exec-am: install-libexecPROGRAMS install-html: install-html-am @@ -1260,81 +884,37 @@ ps: ps-am ps-am: -uninstall-am: uninstall-libLTLIBRARIES uninstall-libexecPROGRAMS \ - uninstall-libindicator_messages_status_provider_laHEADERS \ - uninstall-messaginglibLTLIBRARIES uninstall-pkgconfigDATA \ - uninstall-statusprovidersLTLIBRARIES +uninstall-am: uninstall-libexecPROGRAMS \ + uninstall-messaginglibLTLIBRARIES .MAKE: all check install install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libLTLIBRARIES clean-libexecPROGRAMS clean-libtool \ - clean-messaginglibLTLIBRARIES clean-statusprovidersLTLIBRARIES \ - 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-libLTLIBRARIES install-libexecPROGRAMS \ - install-libindicator_messages_status_provider_laHEADERS \ - install-man install-messaginglibLTLIBRARIES install-pdf \ - install-pdf-am install-pkgconfigDATA install-ps install-ps-am \ - install-statusprovidersLTLIBRARIES install-strip installcheck \ + clean-libexecPROGRAMS clean-libtool \ + clean-messaginglibLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am \ + install-libexecPROGRAMS install-man \ + install-messaginglibLTLIBRARIES 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 uninstall-libLTLIBRARIES \ - uninstall-libexecPROGRAMS \ - uninstall-libindicator_messages_status_provider_laHEADERS \ - uninstall-messaginglibLTLIBRARIES uninstall-pkgconfigDATA \ - uninstall-statusprovidersLTLIBRARIES - - -gen-%.xml.h: %.xml - @echo "Building $@ from $<" - @echo "extern const char * _$(subst -,_,$(subst .,_,$(basename $(notdir $<))));" > $@ - -gen-%.xml.c: %.xml - @echo "Building $@ from $<" - echo "const char * _$(subst -,_,$(subst .,_,$(basename $(notdir $<)))) = " > $@ - @sed -e "s:\":\\\\\":g" -e s:^:\": -e s:\$$:\\\\n\": $< >> $@ - @echo ";" >> $@ - -%.pc: %.pc.in - sed \ - -e "s|\@status_provider_dir\@|$(STATUS_PROVIDER_DIR)|" \ - -e "s|\@status_provider_api_version\@|$(STATUS_PROVIDER_API_VERSION)|" \ - $< > $@ - -status-provider-pidgin-marshal.h: $(srcdir)/status-provider-pidgin.list - glib-genmarshal --header \ - --prefix=_status_provider_pidgin_marshal $(srcdir)/status-provider-pidgin.list \ - > status-provider-pidgin-marshal.h - -status-provider-pidgin-marshal.c: $(srcdir)/status-provider-pidgin.list - glib-genmarshal --body \ - --prefix=_status_provider_pidgin_marshal $(srcdir)/status-provider-pidgin.list \ - > status-provider-pidgin-marshal.c - -status-provider-telepathy-marshal.h: $(srcdir)/status-provider-telepathy.list - glib-genmarshal --header \ - --prefix=_status_provider_telepathy_marshal $(srcdir)/status-provider-telepathy.list \ - > status-provider-telepathy-marshal.h - -status-provider-telepathy-marshal.c: $(srcdir)/status-provider-telepathy.list - glib-genmarshal --body \ - --prefix=_status_provider_telepathy_marshal $(srcdir)/status-provider-telepathy.list \ - > status-provider-telepathy-marshal.c - -status-provider-mc5-marshal.h: $(srcdir)/status-provider-mc5.list - glib-genmarshal --header \ - --prefix=_status_provider_mc5_marshal $(srcdir)/status-provider-mc5.list \ - > status-provider-mc5-marshal.h - -status-provider-mc5-marshal.c: $(srcdir)/status-provider-mc5.list - glib-genmarshal --body \ - --prefix=_status_provider_mc5_marshal $(srcdir)/status-provider-mc5.list \ - > status-provider-mc5-marshal.c + tags uninstall uninstall-am uninstall-libexecPROGRAMS \ + uninstall-messaginglibLTLIBRARIES + + dbus-data.h + +indicator-messages-service.c: $(top_srcdir)/src/messages-service.xml + $(AM_V_GEN) gdbus-codegen \ + --interface-prefix com.canonical.indicator.messages. \ + --generate-c-code indicator-messages-service \ + --c-namespace IndicatorMessages \ + $^ +indicator-messages-service.h: indicator-messages-service.c # 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. diff --git a/src/app-menu-item.c b/src/app-menu-item.c deleted file mode 100644 index ef3fbc0..0000000 --- a/src/app-menu-item.c +++ /dev/null @@ -1,579 +0,0 @@ -/* -An indicator to show information that is in messaging applications -that the user is using. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <glib/gi18n.h> -#include <gio/gdesktopappinfo.h> -#include <libdbusmenu-glib/client.h> -#include <libdbusmenu-glib/menuitem-proxy.h> -#include "app-menu-item.h" -#include "dbus-data.h" -#include "default-applications.h" -#include "seen-db.h" - -enum { - COUNT_CHANGED, - NAME_CHANGED, - SHORTCUT_ADDED, - SHORTCUT_REMOVED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -typedef struct _AppMenuItemPrivate AppMenuItemPrivate; - -struct _AppMenuItemPrivate -{ - IndicateListener * listener; - IndicateListenerServer * server; - - gchar * type; - GAppInfo * appinfo; - GKeyFile * keyfile; - gchar * desktop; - guint unreadcount; - - DbusmenuClient * client; - DbusmenuMenuitem * root; - GList * shortcuts; -}; - -#define APP_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), APP_MENU_ITEM_TYPE, AppMenuItemPrivate)) - -/* Prototypes */ -static void app_menu_item_class_init (AppMenuItemClass *klass); -static void app_menu_item_init (AppMenuItem *self); -static void app_menu_item_dispose (GObject *object); -static void app_menu_item_finalize (GObject *object); -static void activate_cb (AppMenuItem * self, guint timestamp, gpointer data); -static void count_changed (IndicateListener * listener, IndicateListenerServer * server, guint count, gpointer data); -static void count_cb (IndicateListener * listener, IndicateListenerServer * server, guint value, gpointer data); -static void menu_cb (IndicateListener * listener, IndicateListenerServer * server, const gchar * menupath, gpointer data); -static void desktop_cb (IndicateListener * listener, IndicateListenerServer * server, const gchar * value, gpointer data); -static void update_label (AppMenuItem * self); - -/* GObject Boilerplate */ -G_DEFINE_TYPE (AppMenuItem, app_menu_item, DBUSMENU_TYPE_MENUITEM); - -static void -app_menu_item_class_init (AppMenuItemClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (AppMenuItemPrivate)); - - object_class->dispose = app_menu_item_dispose; - object_class->finalize = app_menu_item_finalize; - - signals[COUNT_CHANGED] = g_signal_new(APP_MENU_ITEM_SIGNAL_COUNT_CHANGED, - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (AppMenuItemClass, count_changed), - NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, G_TYPE_UINT); - signals[NAME_CHANGED] = g_signal_new(APP_MENU_ITEM_SIGNAL_NAME_CHANGED, - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (AppMenuItemClass, name_changed), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); - signals[SHORTCUT_ADDED] = g_signal_new(APP_MENU_ITEM_SIGNAL_SHORTCUT_ADDED, - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (AppMenuItemClass, shortcut_added), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, G_TYPE_OBJECT); - signals[SHORTCUT_REMOVED] = g_signal_new(APP_MENU_ITEM_SIGNAL_SHORTCUT_REMOVED, - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (AppMenuItemClass, shortcut_removed), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, G_TYPE_OBJECT); - - return; -} - -static void -app_menu_item_init (AppMenuItem *self) -{ - g_debug("Building new App Menu Item"); - AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self); - - priv->listener = NULL; - priv->server = NULL; - priv->type = NULL; - priv->appinfo = NULL; - priv->keyfile = NULL; - priv->desktop = NULL; - priv->unreadcount = 0; - - priv->client = NULL; - priv->root = NULL; - priv->shortcuts = NULL; - - dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); - - return; -} - -/* A wrapper to make the prototypes work for GFunc */ -static void -func_unref (gpointer data, gpointer user_data) -{ - g_signal_emit(user_data, signals[SHORTCUT_REMOVED], 0, data, TRUE); - g_object_unref(G_OBJECT(data)); - return; -} - -/* Disconnect the count_changed signal and unref the listener */ -static void -app_menu_item_dispose (GObject *object) -{ - AppMenuItem * self = APP_MENU_ITEM(object); - AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self); - - if (priv->listener != NULL) { - g_signal_handlers_disconnect_by_func(G_OBJECT(priv->listener), count_changed, self); - g_object_unref(priv->listener); - priv->listener = NULL; - } - - if (priv->shortcuts != NULL) { - g_list_foreach(priv->shortcuts, func_unref, object); - g_list_free(priv->shortcuts); - priv->shortcuts = NULL; - } - - if (priv->root != NULL) { - g_object_unref(priv->root); - priv->root = NULL; - } - - if (priv->client != NULL) { - g_object_unref(priv->client); - priv->client = NULL; - } - - if (priv->appinfo != NULL) { - g_object_unref(priv->appinfo); - priv->appinfo = NULL; - } - - if (priv->keyfile != NULL) { - g_object_unref(priv->keyfile); - priv->keyfile = NULL; - } - - G_OBJECT_CLASS (app_menu_item_parent_class)->dispose (object); -} - -/* Free the memory used by our type, desktop file and application - info structures. */ -static void -app_menu_item_finalize (GObject *object) -{ - AppMenuItem * self = APP_MENU_ITEM(object); - AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self); - - if (priv->type != NULL) { - g_free(priv->type); - priv->type = NULL; - } - - if (priv->desktop != NULL) { - g_free(priv->desktop); - priv->desktop = NULL; - } - - G_OBJECT_CLASS (app_menu_item_parent_class)->finalize (object); - - return; -} - -AppMenuItem * -app_menu_item_new (IndicateListener * listener, IndicateListenerServer * server) -{ - AppMenuItem * self = g_object_new(APP_MENU_ITEM_TYPE, NULL); - - AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self); - - /* Copy the listener so we can use it later */ - priv->listener = listener; - g_object_ref(G_OBJECT(listener)); - - /* Can not ref as not real GObject */ - priv->server = server; - - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_TYPE, APPLICATION_MENUITEM_TYPE); - - /* Set up listener signals */ - g_signal_connect(G_OBJECT(listener), INDICATE_LISTENER_SIGNAL_SERVER_COUNT_CHANGED, G_CALLBACK(count_changed), self); - - /* Get the values we care about from the server */ - indicate_listener_server_get_desktop(listener, server, desktop_cb, self); - indicate_listener_server_get_count(listener, server, count_cb, self); - indicate_listener_server_get_menu(listener, server, menu_cb, self); - - g_signal_connect(G_OBJECT(self), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), NULL); - - indicate_listener_server_show_interest(listener, server, INDICATE_INTEREST_SERVER_DISPLAY); - indicate_listener_server_show_interest(listener, server, INDICATE_INTEREST_SERVER_SIGNAL); - indicate_listener_server_show_interest(listener, server, INDICATE_INTEREST_INDICATOR_COUNT); - indicate_listener_server_show_interest(listener, server, INDICATE_INTEREST_INDICATOR_DISPLAY); - indicate_listener_server_show_interest(listener, server, INDICATE_INTEREST_INDICATOR_SIGNAL); - indicate_listener_set_server_max_indicators(listener, server, MAX_NUMBER_OF_INDICATORS); - - return self; -} - -static void -update_label (AppMenuItem * self) -{ - AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self); - const gchar * name = get_default_name(priv->desktop); - - if (name == NULL) { - name = app_menu_item_get_name(self); - } - - if (priv->unreadcount > 0) { - /* TRANSLATORS: This is the name of the program and the number of indicators. So it - would read something like "Mail Client (5)" */ - gchar * label = g_strdup_printf(_("%s (%d)"), _(name), priv->unreadcount); - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), APPLICATION_MENUITEM_PROP_NAME, label); - g_free(label); - } else { - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), APPLICATION_MENUITEM_PROP_NAME, _(name)); - } - - return; -} - -/* Callback to the signal that the server count - has changed to a new value. This checks to see if - it's actually changed and if so signals everyone and - updates the label. */ -static void -count_changed (IndicateListener * listener, IndicateListenerServer * server, guint count, gpointer data) -{ - g_return_if_fail(IS_APP_MENU_ITEM(data)); - AppMenuItem * self = APP_MENU_ITEM(data); - AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self); - - if (priv->unreadcount != count) { - priv->unreadcount = count; - update_label(self); - g_signal_emit(G_OBJECT(self), signals[COUNT_CHANGED], 0, priv->unreadcount, TRUE); - } - - return; -} - -/* Callback for getting the count property off - of the server. */ -static void -count_cb (IndicateListener * listener, IndicateListenerServer * server, guint value, gpointer data) -{ - count_changed(listener, server, value, data); - return; -} - -/* Callback for when we ask the server for the path - to it's desktop file. We then turn it into an - app structure and start sucking data out of it. - Mostly the name. And the icon. */ -static void -desktop_cb (IndicateListener * listener, IndicateListenerServer * server, const gchar * value, gpointer data) -{ - g_return_if_fail(IS_APP_MENU_ITEM(data)); - AppMenuItem * self = APP_MENU_ITEM(data); - AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self); - - if (priv->appinfo != NULL) { - g_object_unref(G_OBJECT(priv->appinfo)); - priv->appinfo = NULL; - } - - if (priv->desktop != NULL) { - g_free(priv->desktop); - priv->desktop = NULL; - } - - if (value == NULL || value[0] == '\0') { - return; - } - - seen_db_add(value); - - priv->appinfo = G_APP_INFO(g_desktop_app_info_new_from_filename(value)); - g_return_if_fail(priv->appinfo != NULL); - - priv->keyfile = g_key_file_new(); - g_key_file_load_from_file(priv->keyfile, value, G_KEY_FILE_NONE, NULL); - - priv->desktop = g_strdup(value); - - dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); - dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(self), APPLICATION_MENUITEM_PROP_RUNNING, TRUE); - - update_label(self); - - const gchar * def_icon = get_default_icon(priv->desktop); - if (def_icon == NULL) { - gchar * iconstr = NULL; - - /* Check for the over ride key and see if we should be using that - icon. If we can't get it, then go back to the app info */ - if (g_key_file_has_key(priv->keyfile, G_KEY_FILE_DESKTOP_GROUP, ICON_KEY, NULL) && iconstr == NULL) { - GError * error = NULL; - - iconstr = g_key_file_get_string(priv->keyfile, G_KEY_FILE_DESKTOP_GROUP, ICON_KEY, &error); - - if (error != NULL) { - /* Can't figure out why this would happen, but sure, let's print something */ - g_warning("Error getting '" ICON_KEY "' from desktop file: %s", error->message); - g_error_free(error); - } - } - - /* For some reason that didn't work, let's try the app info */ - if (iconstr == NULL) { - GIcon * icon = g_app_info_get_icon(priv->appinfo); - iconstr = g_icon_to_string(icon); - } - - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), APPLICATION_MENUITEM_PROP_ICON, iconstr); - g_free(iconstr); - } else { - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), APPLICATION_MENUITEM_PROP_ICON, def_icon); - } - - g_signal_emit(G_OBJECT(self), signals[NAME_CHANGED], 0, app_menu_item_get_name(self), TRUE); - - return; -} - -/* Relay this signal into causing a rebuild of the shortcuts - from those above us. */ -static void -child_added_cb (DbusmenuMenuitem * root, DbusmenuMenuitem * child, guint position, gpointer data) -{ - g_return_if_fail(IS_APP_MENU_ITEM(data)); - AppMenuItem * self = APP_MENU_ITEM(data); - AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self); - DbusmenuMenuitemProxy * mip = dbusmenu_menuitem_proxy_new(child); - - priv->shortcuts = g_list_insert(priv->shortcuts, mip, position); - - g_signal_emit(G_OBJECT(data), signals[SHORTCUT_ADDED], 0, mip, TRUE); - return; -} - -/* Relay this signal into causing a rebuild of the shortcuts - from those above us. */ -static void -child_removed_cb (DbusmenuMenuitem * root, DbusmenuMenuitem * child, gpointer data) -{ - g_return_if_fail(IS_APP_MENU_ITEM(data)); - AppMenuItem * self = APP_MENU_ITEM(data); - AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self); - - GList * pitems = priv->shortcuts; - while (pitems != NULL) { - DbusmenuMenuitemProxy * mip = DBUSMENU_MENUITEM_PROXY(pitems->data); - - if (dbusmenu_menuitem_proxy_get_wrapped(mip) == child) { - break; - } - - pitems = g_list_next(pitems); - } - - if (pitems != NULL) { - DbusmenuMenuitemProxy * mip = DBUSMENU_MENUITEM_PROXY(pitems->data); - priv->shortcuts = g_list_remove(priv->shortcuts, mip); - - g_signal_emit(G_OBJECT(data), signals[SHORTCUT_REMOVED], 0, mip, TRUE); - g_object_unref(mip); - } - - return; -} - -/* Relay this signal into causing a rebuild of the shortcuts - from those above us. */ -static void -child_moved_cb (DbusmenuMenuitem * root, DbusmenuMenuitem * child, guint newpos, guint oldpos, gpointer data) -{ - g_return_if_fail(IS_APP_MENU_ITEM(data)); - AppMenuItem * self = APP_MENU_ITEM(data); - AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self); - - DbusmenuMenuitemProxy * mip = DBUSMENU_MENUITEM_PROXY(g_list_nth_data(priv->shortcuts, oldpos)); - - if (mip != NULL) { - if (dbusmenu_menuitem_proxy_get_wrapped(mip) != child) { - mip = NULL; - } - } - - if (mip != NULL) { - priv->shortcuts = g_list_remove(priv->shortcuts, mip); - priv->shortcuts = g_list_insert(priv->shortcuts, mip, newpos); - g_signal_emit(G_OBJECT(data), signals[SHORTCUT_ADDED], 0, NULL, TRUE); - } - - return; -} - -/* We've got a new root. We need to proxy it and handle it's children - if that's a relevant thing to do. */ -static void -root_changed (DbusmenuClient * client, DbusmenuMenuitem * newroot, gpointer data) -{ - g_debug("Root Changed"); - AppMenuItem * self = APP_MENU_ITEM(data); - AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self); - - if (priv->root != NULL) { - if (dbusmenu_menuitem_get_children(DBUSMENU_MENUITEM(priv->root)) != NULL) { - g_list_foreach(priv->shortcuts, func_unref, data); - g_list_free(priv->shortcuts); - priv->shortcuts = NULL; - } - g_object_unref(priv->root); - priv->root = NULL; - } - - /* We need to proxy the new root across to the old - world of indicator land. */ - priv->root = newroot; - - if (priv->root != NULL) { - g_object_ref(priv->root); - g_signal_connect(G_OBJECT(priv->root), DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED, G_CALLBACK(child_added_cb), self); - g_signal_connect(G_OBJECT(priv->root), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(child_removed_cb), self); - g_signal_connect(G_OBJECT(priv->root), DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED, G_CALLBACK(child_moved_cb), self); - - /* See if we have any menuitems to worry about, - otherwise we'll just move along. */ - GList * children = dbusmenu_menuitem_get_children(DBUSMENU_MENUITEM(priv->root)); - if (children != NULL) { - g_debug("\tProcessing %d children", g_list_length(children)); - while (children != NULL) { - DbusmenuMenuitemProxy * mip = dbusmenu_menuitem_proxy_new(DBUSMENU_MENUITEM(children->data)); - priv->shortcuts = g_list_append(priv->shortcuts, mip); - g_signal_emit(G_OBJECT(self), signals[SHORTCUT_ADDED], 0, mip, TRUE); - children = g_list_next(children); - } - } - } - - return; -} - -/* Gets the path to menuitems if there are some. Now we need to - make them special. */ -static void -menu_cb (IndicateListener * listener, IndicateListenerServer * server, const gchar * menupath, gpointer data) -{ - g_debug("Got Menu: %s", menupath); - g_return_if_fail(IS_APP_MENU_ITEM(data)); - AppMenuItem * self = APP_MENU_ITEM(data); - AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self); - - priv->client = dbusmenu_client_new(indicate_listener_server_get_dbusname(server), menupath); - g_signal_connect(G_OBJECT(priv->client), DBUSMENU_CLIENT_SIGNAL_ROOT_CHANGED, G_CALLBACK(root_changed), self); - - DbusmenuMenuitem * root = dbusmenu_client_get_root(priv->client); - if (root != NULL) { - root_changed(priv->client, root, self); - } - - return; -} - -static void -activate_cb (AppMenuItem * self, guint timestamp, gpointer data) -{ - AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(self); - - indicate_listener_display(priv->listener, priv->server, NULL, timestamp); - - return; -} - -guint -app_menu_item_get_count (AppMenuItem * appitem) -{ - g_return_val_if_fail(IS_APP_MENU_ITEM(appitem), 0); - AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(appitem); - - return priv->unreadcount; -} - -IndicateListenerServer * -app_menu_item_get_server (AppMenuItem * appitem) { - g_return_val_if_fail(IS_APP_MENU_ITEM(appitem), NULL); - AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(appitem); - - return priv->server; -} - -const gchar * -app_menu_item_get_name (AppMenuItem * appitem) -{ - g_return_val_if_fail(IS_APP_MENU_ITEM(appitem), NULL); - AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(appitem); - - if (priv->appinfo == NULL) { - return INDICATE_LISTENER_SERVER_DBUS_NAME(priv->server); - } else { - return g_app_info_get_name(priv->appinfo); - } -} - -const gchar * -app_menu_item_get_desktop (AppMenuItem * appitem) -{ - g_return_val_if_fail(IS_APP_MENU_ITEM(appitem), NULL); - AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(appitem); - return priv->desktop; -} - -/* Get the dynamic items added onto the end of - and app entry. */ -GList * -app_menu_item_get_items (AppMenuItem * appitem) -{ - g_return_val_if_fail(IS_APP_MENU_ITEM(appitem), NULL); - AppMenuItemPrivate * priv = APP_MENU_ITEM_GET_PRIVATE(appitem); - return priv->shortcuts; -} diff --git a/src/app-menu-item.h b/src/app-menu-item.h deleted file mode 100644 index d616856..0000000 --- a/src/app-menu-item.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -An indicator to show information that is in messaging applications -that the user is using. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ -#ifndef __APP_MENU_ITEM_H__ -#define __APP_MENU_ITEM_H__ - -#include <glib.h> -#include <glib-object.h> - -#include <libdbusmenu-glib/menuitem.h> -#include <libindicate/listener.h> - -G_BEGIN_DECLS - -#define APP_MENU_ITEM_TYPE (app_menu_item_get_type ()) -#define APP_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), APP_MENU_ITEM_TYPE, AppMenuItem)) -#define APP_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), APP_MENU_ITEM_TYPE, AppMenuItemClass)) -#define IS_APP_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), APP_MENU_ITEM_TYPE)) -#define IS_APP_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), APP_MENU_ITEM_TYPE)) -#define APP_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), APP_MENU_ITEM_TYPE, AppMenuItemClass)) - -#define APP_MENU_ITEM_SIGNAL_COUNT_CHANGED "count-changed" -#define APP_MENU_ITEM_SIGNAL_NAME_CHANGED "name-changed" -#define APP_MENU_ITEM_SIGNAL_SHORTCUT_ADDED "shortcut-added" -#define APP_MENU_ITEM_SIGNAL_SHORTCUT_REMOVED "shortcut-removed" - -typedef struct _AppMenuItem AppMenuItem; -typedef struct _AppMenuItemClass AppMenuItemClass; - -struct _AppMenuItemClass { - DbusmenuMenuitemClass parent_class; - - void (* count_changed) (guint count); - void (* name_changed) (gchar * name); - void (* shortcut_added) (DbusmenuMenuitem * mi); - void (* shortcut_removed) (DbusmenuMenuitem * mi); -}; - -struct _AppMenuItem { - DbusmenuMenuitem parent; -}; - -GType app_menu_item_get_type (void); -AppMenuItem * app_menu_item_new (IndicateListener * listener, IndicateListenerServer * server); -guint app_menu_item_get_count (AppMenuItem * appitem); -IndicateListenerServer * app_menu_item_get_server (AppMenuItem * appitem); -const gchar * app_menu_item_get_name (AppMenuItem * appitem); -const gchar * app_menu_item_get_desktop (AppMenuItem * appitem); -GList * app_menu_item_get_items (AppMenuItem * appitem); - -G_END_DECLS - -#endif /* __APP_MENU_ITEM_H__ */ - diff --git a/src/app-section.c b/src/app-section.c new file mode 100644 index 0000000..70bf21e --- /dev/null +++ b/src/app-section.c @@ -0,0 +1,695 @@ +/* +An indicator to show information that is in messaging applications +that the user is using. + +Copyright 2012 Canonical Ltd. + +Authors: + Lars Uebernickel <lars.uebernickel@canonical.com> + Ted Gould <ted@canonical.com> + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <glib/gi18n.h> +#include <gio/gdesktopappinfo.h> +#include <gio/gio.h> +#include <libindicator/indicator-desktop-shortcuts.h> +#include "app-section.h" +#include "dbus-data.h" +#include "gmenuutils.h" +#include "gactionmuxer.h" + +struct _AppSectionPrivate +{ + GDesktopAppInfo * appinfo; + guint unreadcount; + + IndicatorDesktopShortcuts * ids; + + GMenu *menu; + GMenuModel *source_menu; + + GSimpleActionGroup *static_shortcuts; + GActionGroup *source_actions; + GActionMuxer *muxer; + + gboolean draws_attention; + gboolean uses_chat_status; + + guint name_watch_id; +}; + +enum { + PROP_0, + PROP_APPINFO, + PROP_ACTIONS, + PROP_DRAWS_ATTENTION, + PROP_USES_CHAT_STATUS, + NUM_PROPERTIES +}; + +static GParamSpec *properties[NUM_PROPERTIES]; + +/* Prototypes */ +static void app_section_class_init (AppSectionClass *klass); +static void app_section_init (AppSection *self); +static void app_section_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); +static void app_section_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void app_section_dispose (GObject *object); +static void activate_cb (GSimpleAction *action, + GVariant *param, + gpointer userdata); +static void launch_action_change_state (GSimpleAction *action, + GVariant *value, + gpointer user_data); +static void app_section_set_app_info (AppSection *self, + GDesktopAppInfo *appinfo); +static gboolean any_action_draws_attention (GActionGroup *group, + const gchar *ignored_action); +static void action_added (GActionGroup *group, + const gchar *action_name, + gpointer user_data); +static void action_state_changed (GActionGroup *group, + const gchar *action_name, + GVariant *value, + gpointer user_data); +static void action_removed (GActionGroup *group, + const gchar *action_name, + gpointer user_data); +static gboolean action_draws_attention (GVariant *state); + +/* GObject Boilerplate */ +G_DEFINE_TYPE (AppSection, app_section, G_TYPE_OBJECT); + +static void +app_section_class_init (AppSectionClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (AppSectionPrivate)); + + object_class->get_property = app_section_get_property; + object_class->set_property = app_section_set_property; + object_class->dispose = app_section_dispose; + + properties[PROP_APPINFO] = g_param_spec_object ("app-info", + "AppInfo", + "The GAppInfo for the app that this menu represents", + G_TYPE_APP_INFO, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + + properties[PROP_ACTIONS] = g_param_spec_object ("actions", + "Actions", + "The actions exported by this application", + G_TYPE_ACTION_GROUP, + G_PARAM_READABLE); + + properties[PROP_DRAWS_ATTENTION] = g_param_spec_boolean ("draws-attention", + "Draws attention", + "Whether the section currently draws attention", + FALSE, + G_PARAM_READABLE); + + properties[PROP_USES_CHAT_STATUS] = g_param_spec_boolean ("uses-chat-status", + "Uses chat status", + "Whether the section uses the global chat status", + FALSE, + G_PARAM_READABLE); + + g_object_class_install_properties (object_class, NUM_PROPERTIES, properties); +} + +static void +app_section_init (AppSection *self) +{ + AppSectionPrivate *priv; + + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + APP_SECTION_TYPE, + AppSectionPrivate); + priv = self->priv; + + priv->appinfo = NULL; + priv->unreadcount = 0; + + priv->menu = g_menu_new (); + priv->static_shortcuts = g_simple_action_group_new (); + + priv->muxer = g_action_muxer_new (); + g_action_muxer_insert (priv->muxer, NULL, G_ACTION_GROUP (priv->static_shortcuts)); + + priv->draws_attention = FALSE; + + return; +} + +static void +app_section_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + AppSection *self = APP_SECTION (object); + + switch (property_id) + { + case PROP_APPINFO: + g_value_set_object (value, app_section_get_app_info (self)); + break; + + case PROP_DRAWS_ATTENTION: + g_value_set_boolean (value, app_section_get_draws_attention (self)); + break; + + case PROP_USES_CHAT_STATUS: + g_value_set_boolean (value, app_section_get_uses_chat_status (self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +app_section_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + AppSection *self = APP_SECTION (object); + + switch (property_id) + { + case PROP_APPINFO: + app_section_set_app_info (self, g_value_get_object (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} +static void +app_section_dispose (GObject *object) +{ + AppSection * self = APP_SECTION(object); + AppSectionPrivate * priv = self->priv; + + g_clear_object (&priv->menu); + g_clear_object (&priv->static_shortcuts); + + if (priv->name_watch_id) { + g_bus_unwatch_name (priv->name_watch_id); + priv->name_watch_id = 0; + } + + if (priv->source_actions) { + g_action_muxer_remove (priv->muxer, "source"); + g_object_disconnect (priv->source_actions, + "any_signal::action-added", action_added, self, + "any_signal::action-state-changed", action_state_changed, self, + "any_signal::action-removed", action_removed, self, + NULL); + g_clear_object (&priv->source_actions); + } + + g_clear_object (&priv->source_menu); + g_clear_object (&priv->ids); + g_clear_object (&priv->appinfo); + + G_OBJECT_CLASS (app_section_parent_class)->dispose (object); +} + +/* Respond to one of the shortcuts getting clicked on. */ +static void +nick_activate_cb (GSimpleAction *action, + GVariant *param, + gpointer userdata) +{ + const gchar * nick = g_action_get_name (G_ACTION (action)); + AppSection * mi = APP_SECTION (userdata); + AppSectionPrivate * priv = mi->priv; + + g_return_if_fail(priv->ids != NULL); + + if (!indicator_desktop_shortcuts_nick_exec(priv->ids, nick)) { + g_warning("Unable to execute nick '%s' for desktop file '%s'", + nick, g_desktop_app_info_get_filename (priv->appinfo)); + } +} + +static void +keyfile_loaded (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + AppSection *self = user_data; + gchar *contents; + gsize length; + GKeyFile *keyfile; + GError *error = NULL; + + if (!g_file_load_contents_finish (G_FILE (source_object), result, + &contents, &length, NULL, &error)) { + g_warning ("could not read key file: %s", error->message); + g_error_free (error); + return; + } + + keyfile = g_key_file_new (); + if (!g_key_file_load_from_data (keyfile, contents, length, 0, &error)) { + g_warning ("could not read key file: %s", error->message); + g_error_free (error); + goto out; + } + + self->priv->uses_chat_status = g_key_file_get_boolean (keyfile, + G_KEY_FILE_DESKTOP_GROUP, + "X-MessagingMenu-UsesChatSection", + &error); + if (error) { + if (error->code != G_KEY_FILE_ERROR_KEY_NOT_FOUND) { + g_warning ("could not read X-MessagingMenu-UsesChatSection: %s", + error->message); + } + g_error_free (error); + goto out; + } + + if (self->priv->uses_chat_status) + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_USES_CHAT_STATUS]); + +out: + g_key_file_free (keyfile); + g_free (contents); +} + +static void +app_section_set_app_info (AppSection *self, + GDesktopAppInfo *appinfo) +{ + AppSectionPrivate *priv = self->priv; + GSimpleAction *launch; + GFile *keyfile; + GMenuItem *item; + gchar *iconstr; + + g_return_if_fail (priv->appinfo == NULL); + + if (appinfo == NULL) { + g_warning ("appinfo must not be NULL"); + return; + } + + priv->appinfo = g_object_ref (appinfo); + + launch = g_simple_action_new_stateful ("launch", NULL, g_variant_new_boolean (FALSE)); + g_signal_connect (launch, "activate", G_CALLBACK (activate_cb), self); + g_signal_connect (launch, "change-state", G_CALLBACK (launch_action_change_state), self); + g_simple_action_group_insert (priv->static_shortcuts, G_ACTION (launch)); + + item = g_menu_item_new (g_app_info_get_name (G_APP_INFO (priv->appinfo)), "launch"); + g_menu_item_set_attribute (item, "x-canonical-type", "s", "ImAppMenuItem"); + iconstr = g_icon_to_string (g_app_info_get_icon (G_APP_INFO (priv->appinfo))); + g_menu_item_set_attribute (item, "x-canonical-icon", "s", iconstr); + g_free (iconstr); + + g_menu_append_item (priv->menu, item); + g_object_unref (item); + + /* Start to build static shortcuts */ + priv->ids = indicator_desktop_shortcuts_new(g_desktop_app_info_get_filename (priv->appinfo), "Messaging Menu"); + const gchar ** nicks = indicator_desktop_shortcuts_get_nicks(priv->ids); + gint i; + for (i = 0; nicks[i] != NULL; i++) { + gchar *name; + GSimpleAction *action; + + name = indicator_desktop_shortcuts_nick_get_name(priv->ids, nicks[i]); + + action = g_simple_action_new (nicks[i], NULL); + g_signal_connect(action, "activate", G_CALLBACK (nick_activate_cb), self); + g_simple_action_group_insert (priv->static_shortcuts, G_ACTION (action)); + + g_menu_append (priv->menu, name, nicks[i]); + + g_free(name); + } + + keyfile = g_file_new_for_path (g_desktop_app_info_get_filename (priv->appinfo)); + g_file_load_contents_async (keyfile, NULL, keyfile_loaded, self); + g_object_unref (keyfile); + + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_APPINFO]); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]); + + g_object_unref (launch); +} + +AppSection * +app_section_new (GDesktopAppInfo *appinfo) +{ + return g_object_new (APP_SECTION_TYPE, + "app-info", appinfo, + NULL); +} + +static void +activate_cb (GSimpleAction *action, + GVariant *param, + gpointer userdata) +{ + AppSection * mi = APP_SECTION (userdata); + AppSectionPrivate * priv = mi->priv; + GError *error = NULL; + + if (!g_app_info_launch (G_APP_INFO (priv->appinfo), NULL, NULL, &error)) { + g_warning("Unable to execute application for desktop file '%s'", + g_desktop_app_info_get_filename (priv->appinfo)); + } +} + +static void +launch_action_change_state (GSimpleAction *action, + GVariant *value, + gpointer user_data) +{ + g_simple_action_set_state (action, value); +} + +guint +app_section_get_count (AppSection * self) +{ + AppSectionPrivate * priv = self->priv; + + return priv->unreadcount; +} + +const gchar * +app_section_get_name (AppSection * self) +{ + AppSectionPrivate * priv = self->priv; + + if (priv->appinfo) { + return g_app_info_get_name(G_APP_INFO(priv->appinfo)); + } + return NULL; +} + +const gchar * +app_section_get_desktop (AppSection * self) +{ + AppSectionPrivate * priv = self->priv; + if (priv->appinfo) + return g_desktop_app_info_get_filename (priv->appinfo); + else + return NULL; +} + +GActionGroup * +app_section_get_actions (AppSection *self) +{ + AppSectionPrivate * priv = self->priv; + return G_ACTION_GROUP (priv->muxer); +} + +GMenuModel * +app_section_get_menu (AppSection *self) +{ + AppSectionPrivate * priv = self->priv; + return G_MENU_MODEL (priv->menu); +} + +GAppInfo * +app_section_get_app_info (AppSection *self) +{ + AppSectionPrivate * priv = self->priv; + return G_APP_INFO (priv->appinfo); +} + +gboolean +app_section_get_draws_attention (AppSection *self) +{ + AppSectionPrivate * priv = self->priv; + return priv->draws_attention; +} + +void +app_section_clear_draws_attention (AppSection *self) +{ + AppSectionPrivate * priv = self->priv; + gchar **action_names; + gchar **it; + + if (priv->source_actions == NULL) + return; + + action_names = g_action_group_list_actions (priv->source_actions); + + for (it = action_names; *it; it++) { + GVariant *state; + + state = g_action_group_get_action_state (priv->source_actions, *it); + if (!state) + continue; + + /* clear draws-attention while preserving other state */ + if (action_draws_attention (state)) { + guint32 count; + gint64 time; + const gchar *str; + GVariant *new_state; + + g_variant_get (state, "(ux&sb)", &count, &time, &str, NULL); + + new_state = g_variant_new ("(uxsb)", count, time, str, FALSE); + g_action_group_change_action_state (priv->source_actions, *it, new_state); + } + + g_variant_unref (state); + } + + g_strfreev (action_names); +} + +static void +application_vanished (GDBusConnection *bus, + const gchar *name, + gpointer user_data) +{ + AppSection *self = user_data; + + app_section_unset_object_path (self); +} + +/* + * app_section_set_object_path: + * @self: an #AppSection + * @bus: a #GDBusConnection + * @bus_name: the bus name of the application + * @object_path: the object path on which the app exports its actions and menus + * + * Sets the D-Bus object path exported by an instance of the application + * associated with @self. Actions and menus exported on that path will be + * shown in the section. + */ +void +app_section_set_object_path (AppSection *self, + GDBusConnection *bus, + const gchar *bus_name, + const gchar *object_path) +{ + AppSectionPrivate *priv = self->priv; + GMenuItem *item; + + g_object_freeze_notify (G_OBJECT (self)); + app_section_unset_object_path (self); + + priv->source_actions = G_ACTION_GROUP (g_dbus_action_group_get (bus, bus_name, object_path)); + g_action_muxer_insert (priv->muxer, "source", priv->source_actions); + + priv->draws_attention = any_action_draws_attention (priv->source_actions, NULL); + g_object_connect (priv->source_actions, + "signal::action-added", action_added, self, + "signal::action-state-changed", action_state_changed, self, + "signal::action-removed", action_removed, self, + NULL); + + priv->source_menu = G_MENU_MODEL (g_dbus_menu_model_get (bus, bus_name, object_path)); + + item = g_menu_item_new_section (NULL, priv->source_menu); + g_menu_item_set_attribute (item, "action-namespace", "s", "source"); + g_menu_append_item (priv->menu, item); + g_object_unref (item); + + priv->name_watch_id = g_bus_watch_name_on_connection (bus, bus_name, 0, + NULL, application_vanished, + self, NULL); + + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_USES_CHAT_STATUS]); + g_object_thaw_notify (G_OBJECT (self)); + + g_action_group_change_action_state (G_ACTION_GROUP (priv->static_shortcuts), + "launch", g_variant_new_boolean (TRUE)); +} + +/* + * app_section_unset_object_path: + * @self: an #AppSection + * + * Unsets the object path set with app_section_set_object_path(). The section + * will return to only showing application name and static shortcuts in the + * menu. + */ +void +app_section_unset_object_path (AppSection *self) +{ + AppSectionPrivate *priv = self->priv; + + if (priv->name_watch_id) { + g_bus_unwatch_name (priv->name_watch_id); + priv->name_watch_id = 0; + } + + if (priv->source_actions) { + g_object_disconnect (priv->source_actions, + "any_signal::action-added", action_added, self, + "any_signal::action-state-changed", action_state_changed, self, + "any_signal::action-removed", action_removed, self, + NULL); + g_clear_object (&priv->source_actions); + } + + if (priv->source_menu) { + /* the last menu item points is linked to the app's menumodel */ + gint n_items = g_menu_model_get_n_items (G_MENU_MODEL (priv->menu)); + g_menu_remove (priv->menu, n_items -1); + g_clear_object (&priv->source_menu); + } + + priv->draws_attention = FALSE; + + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIONS]); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_USES_CHAT_STATUS]); + + g_action_group_change_action_state (G_ACTION_GROUP (priv->static_shortcuts), + "launch", g_variant_new_boolean (FALSE)); +} + +static gboolean +action_draws_attention (GVariant *state) +{ + gboolean attention; + + if (state && g_variant_is_of_type (state, G_VARIANT_TYPE ("(uxsb)"))) + g_variant_get_child (state, 3, "b", &attention); + else + attention = FALSE; + + return attention; +} + +static gboolean +any_action_draws_attention (GActionGroup *group, + const gchar *ignored_action) +{ + gchar **actions; + gchar **it; + gboolean attention = FALSE; + + actions = g_action_group_list_actions (group); + + for (it = actions; *it && !attention; it++) { + GVariant *state; + + if (ignored_action && g_str_equal (ignored_action, *it)) + continue; + + state = g_action_group_get_action_state (group, *it); + if (state) { + attention = action_draws_attention (state); + g_variant_unref (state); + } + } + + g_strfreev (actions); + return attention; +} + +static void +action_added (GActionGroup *group, + const gchar *action_name, + gpointer user_data) +{ + AppSection *self = user_data; + GVariant *state; + + state = g_action_group_get_action_state (group, action_name); + if (state) { + self->priv->draws_attention |= action_draws_attention (state); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); + g_variant_unref (state); + } +} + +static void +action_state_changed (GActionGroup *group, + const gchar *action_name, + GVariant *value, + gpointer user_data) +{ + AppSection *self = user_data; + + self->priv->draws_attention = any_action_draws_attention (group, NULL); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); +} + +static void +action_removed (GActionGroup *group, + const gchar *action_name, + gpointer user_data) +{ + AppSection *self = user_data; + GVariant *state; + + state = g_action_group_get_action_state (group, action_name); + if (!state) + return; + + self->priv->draws_attention = any_action_draws_attention (group, action_name); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DRAWS_ATTENTION]); + + g_variant_unref (state); +} + +gboolean +app_section_get_uses_chat_status (AppSection *self) +{ + AppSectionPrivate * priv = self->priv; + + /* chat status is only useful when the app is running */ + return priv->uses_chat_status && priv->source_actions; +} diff --git a/src/app-section.h b/src/app-section.h new file mode 100644 index 0000000..711fdc9 --- /dev/null +++ b/src/app-section.h @@ -0,0 +1,72 @@ +/* +An indicator to show information that is in messaging applications +that the user is using. + +Copyright 2012 Canonical Ltd. + +Authors: + Lars Uebernickel <lars.uebernickel@canonical.com> + Ted Gould <ted@canonical.com> + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +#ifndef __APP_SECTION_H__ +#define __APP_SECTION_H__ + +#include <gio/gio.h> +#include <gio/gdesktopappinfo.h> + +G_BEGIN_DECLS + +#define APP_SECTION_TYPE (app_section_get_type ()) +#define APP_SECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), APP_SECTION_TYPE, AppSection)) +#define APP_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), APP_SECTION_TYPE, AppSectionClass)) +#define IS_APP_SECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), APP_SECTION_TYPE)) +#define IS_APP_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), APP_SECTION_TYPE)) +#define APP_SECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), APP_SECTION_TYPE, AppSectionClass)) + +typedef struct _AppSection AppSection; +typedef struct _AppSectionClass AppSectionClass; +typedef struct _AppSectionPrivate AppSectionPrivate; + + +struct _AppSectionClass { + GObjectClass parent_class; +}; + +struct _AppSection { + GObject parent; + AppSectionPrivate *priv; +}; + +GType app_section_get_type (void); +AppSection * app_section_new (GDesktopAppInfo *appinfo); +guint app_section_get_count (AppSection * appitem); +const gchar * app_section_get_name (AppSection * appitem); +const gchar * app_section_get_desktop (AppSection * appitem); +GActionGroup * app_section_get_actions (AppSection *self); +GMenuModel * app_section_get_menu (AppSection *appitem); +GAppInfo * app_section_get_app_info (AppSection *appitem); +gboolean app_section_get_draws_attention (AppSection *appitem); +void app_section_clear_draws_attention (AppSection *appitem); +void app_section_set_object_path (AppSection *self, + GDBusConnection *bus, + const gchar *bus_name, + const gchar *object_path); +void app_section_unset_object_path (AppSection *self); +gboolean app_section_get_uses_chat_status (AppSection *self); + +G_END_DECLS + +#endif /* __APP_SECTION_H__ */ + diff --git a/src/dbus-data.h b/src/dbus-data.h index fac732e..64747a9 100644 --- a/src/dbus-data.h +++ b/src/dbus-data.h @@ -8,17 +8,4 @@ #define INDICATOR_MESSAGES_DBUS_SERVICE_OBJECT "/com/canonical/indicator/messages/service" #define INDICATOR_MESSAGES_DBUS_SERVICE_INTERFACE "com.canonical.indicator.messages.service" -#define APPLICATION_MENUITEM_TYPE "application-item" -#define APPLICATION_MENUITEM_PROP_NAME "label" -#define APPLICATION_MENUITEM_PROP_ICON "icon-name" -#define APPLICATION_MENUITEM_PROP_RUNNING "app-running" - -#define INDICATOR_MENUITEM_TYPE "indicator-item" -#define INDICATOR_MENUITEM_PROP_LABEL "indicator-label" -#define INDICATOR_MENUITEM_PROP_ICON "indicator-icon" -#define INDICATOR_MENUITEM_PROP_RIGHT "right-side-text" -#define INDICATOR_MENUITEM_PROP_RIGHT_IS_LOZENGE "right-is-lozenge" - -#define MAX_NUMBER_OF_INDICATORS 7 - #endif /* __DBUS_DATA_H__ */ diff --git a/src/default-applications.c b/src/default-applications.c deleted file mode 100644 index 0382e4d..0000000 --- a/src/default-applications.c +++ /dev/null @@ -1,116 +0,0 @@ -/* -Looking for the default applications. A quick lookup. - -Copyright 2010 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include <glib.h> -#include <glib/gi18n.h> -#include <gio/gio.h> -#include <gio/gdesktopappinfo.h> -#include "default-applications.h" - -struct default_db_t { - const gchar * desktop_file; - const gchar * uri_scheme; - const gchar * name; - const gchar * setupname; - const gchar * icon; -}; - -struct default_db_t default_db[] = { - {NULL, "mailto", N_("Mail"), N_("Set Up Mail..."), "applications-email-panel"}, - {"empathy.desktop", NULL, N_("Chat"), N_("Set Up Chat..."), "applications-chat-panel"}, - {"gwibber.desktop", NULL, N_("Broadcast"), N_("Set Up Broadcast Account..."), "applications-microblogging-panel"}, -}; - -static struct default_db_t * -get_default_helper (const gchar * desktop_path) -{ - g_return_val_if_fail(desktop_path != NULL, NULL); - gchar * basename = g_path_get_basename(desktop_path); - g_return_val_if_fail(basename != NULL, NULL); - - gboolean found = FALSE; - gint i; - gint length = G_N_ELEMENTS(default_db); - for (i = 0; i < length && !found; i++) { - if (default_db[i].desktop_file) { - if (g_strcmp0(default_db[i].desktop_file, basename) == 0) { - found = TRUE; - } - } else if (default_db[i].uri_scheme) { - GAppInfo *info = g_app_info_get_default_for_uri_scheme(default_db[i].uri_scheme); - if (!info) { - continue; - } - - const gchar * filename = g_desktop_app_info_get_filename(G_DESKTOP_APP_INFO(info)); - if (!filename) { - g_object_unref(info); - continue; - } - - gchar * default_basename = g_path_get_basename(filename); - g_object_unref(info); - if (g_strcmp0(default_basename, basename) == 0) { - found = TRUE; - } - - g_free(default_basename); - } - } - - g_free(basename); - - if (found) { - return &default_db[i - 1]; - } - - return NULL; -} - -const gchar * -get_default_name (const gchar * desktop_path) -{ - struct default_db_t * db = get_default_helper(desktop_path); - - if (db == NULL) - return NULL; - return db->name; -} - -const gchar * -get_default_setup (const gchar * desktop_path) -{ - struct default_db_t * db = get_default_helper(desktop_path); - - if (db == NULL) - return NULL; - return db->setupname; -} - -const gchar * -get_default_icon (const gchar * desktop_path) -{ - struct default_db_t * db = get_default_helper(desktop_path); - - if (db == NULL) - return NULL; - return db->icon; -} diff --git a/src/default-applications.h b/src/default-applications.h deleted file mode 100644 index df52b38..0000000 --- a/src/default-applications.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -Looking for the default applications. A quick lookup. - -Copyright 2010 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef DEFAULT_APPLICATIONS_H__ -#define DEFAULT_APPLICATIONS_H__ 1 - -/* Used for override icons in the normal case, but didn't - have a better place to put it. */ -#define ICON_KEY "X-Ayatana-Messaging-Menu-Icon" - -const gchar * get_default_name (const gchar * desktop_path); -const gchar * get_default_setup (const gchar * desktop_path); -const gchar * get_default_icon (const gchar * desktop_path); - -#endif /* DEFAULT_APPLICATIONS_H__ */ - diff --git a/src/dirs.h b/src/dirs.h deleted file mode 100644 index ca322f0..0000000 --- a/src/dirs.h +++ /dev/null @@ -1,4 +0,0 @@ -#define SYSTEM_APPS_DIR "/usr/share/indicators/messages/applications" -#define SYSTEM_APPS_DIR_OLD "/etc/indicators/messages/applications" -#define USER_APPS_DIR "indicators/messages/applications" -#define USER_BLACKLIST_DIR "indicators/messages/applications-blacklist" diff --git a/src/gactionmuxer.c b/src/gactionmuxer.c new file mode 100644 index 0000000..2b1d11a --- /dev/null +++ b/src/gactionmuxer.c @@ -0,0 +1,485 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Lars Uebernickel <lars.uebernickel@canonical.com> + * Ryan Lortie <desrt@desrt.ca> + */ + +#include "gactionmuxer.h" + +#include <string.h> + +/* + * SECTION:gactionmuxer + * @short_description: Aggregate several action groups + * + * #GActionMuxer is a #GActionGroup that is capable of containing other + * #GActionGroup instances. + * + * The typical use is aggregating all of the actions applicable to a + * particular context into a single action group, with namespacing. + * + * Consider the case of two action groups -- one containing actions + * applicable to an entire application (such as 'quit') and one + * containing actions applicable to a particular window in the + * application (such as 'fullscreen'). + * + * In this case, each of these action groups could be added to a + * #GActionMuxer with the prefixes "app" and "win", respectively. This + * would expose the actions as "app.quit" and "win.fullscreen" on the + * #GActionGroup interface presented by the #GActionMuxer. + * + * Activations and state change requests on the #GActionMuxer are wired + * through to the underlying action group in the expected way. + */ + +typedef GObjectClass GActionMuxerClass; + +struct _GActionMuxer +{ + GObject parent; + GActionGroup *global_actions; + GHashTable *groups; /* prefix -> subgroup */ + GHashTable *reverse; /* subgroup -> prefix */ +}; + + +static void g_action_muxer_group_init (GActionGroupInterface *iface); +static void g_action_muxer_dispose (GObject *object); +static void g_action_muxer_finalize (GObject *object); +static void g_action_muxer_disconnect_group (GActionMuxer *muxer, + GActionGroup *subgroup); +static gchar ** g_action_muxer_list_actions (GActionGroup *group); +static void g_action_muxer_activate_action (GActionGroup *group, + const gchar *action_name, + GVariant *parameter); +static void g_action_muxer_change_action_state (GActionGroup *group, + const gchar *action_name, + GVariant *value); +static gboolean g_action_muxer_query_action (GActionGroup *group, + const gchar *action_name, + gboolean *enabled, + const GVariantType **parameter_type, + const GVariantType **state_type, + GVariant **state_hint, + GVariant **state); +static void g_action_muxer_action_added (GActionGroup *group, + gchar *action_name, + gpointer user_data); +static void g_action_muxer_action_removed (GActionGroup *group, + gchar *action_name, + gpointer user_data); +static void g_action_muxer_action_state_changed (GActionGroup *group, + gchar *action_name, + GVariant *value, + gpointer user_data); +static void g_action_muxer_action_enabled_changed (GActionGroup *group, + gchar *action_name, + gboolean enabled, + gpointer user_data); + +G_DEFINE_TYPE_WITH_CODE (GActionMuxer, g_action_muxer, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP, g_action_muxer_group_init)); + + +static void +g_action_muxer_class_init (GObjectClass *klass) +{ + klass->dispose = g_action_muxer_dispose; + klass->finalize = g_action_muxer_finalize; +} + +static void +g_action_muxer_init (GActionMuxer *muxer) +{ + muxer->global_actions = NULL; + muxer->groups = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + muxer->reverse = g_hash_table_new (g_direct_hash, g_direct_equal); +} + +static void +g_action_muxer_group_init (GActionGroupInterface *iface) +{ + iface->list_actions = g_action_muxer_list_actions; + iface->activate_action = g_action_muxer_activate_action; + iface->change_action_state = g_action_muxer_change_action_state; + iface->query_action = g_action_muxer_query_action; +} + +static void +g_action_muxer_dispose (GObject *object) +{ + GActionMuxer *muxer = G_ACTION_MUXER (object); + GHashTableIter it; + GActionGroup *subgroup; + + if (muxer->global_actions) + { + g_action_muxer_disconnect_group (muxer, muxer->global_actions); + g_clear_object (&muxer->global_actions); + } + + g_hash_table_iter_init (&it, muxer->groups); + while (g_hash_table_iter_next (&it, NULL, (gpointer *) &subgroup)) + g_action_muxer_disconnect_group (muxer, subgroup); + + g_hash_table_remove_all (muxer->groups); + g_hash_table_remove_all (muxer->reverse); +} + +static void +g_action_muxer_finalize (GObject *object) +{ + GActionMuxer *muxer = G_ACTION_MUXER (object); + + g_hash_table_unref (muxer->groups); + g_hash_table_unref (muxer->reverse); + + G_OBJECT_CLASS (g_action_muxer_parent_class)->finalize (object); +} + +static GActionGroup * +g_action_muxer_lookup_group (GActionMuxer *muxer, + const gchar *full_name, + const gchar **action_name) +{ + const gchar *sep; + GActionGroup *group; + + sep = strchr (full_name, '.'); + + if (sep) + { + gchar *prefix; + prefix = g_strndup (full_name, sep - full_name); + group = g_hash_table_lookup (muxer->groups, prefix); + g_free (prefix); + if (action_name) + *action_name = sep + 1; + } + else + { + group = muxer->global_actions; + if (action_name) + *action_name = full_name; + } + + return group; +} + +static gchar * +g_action_muxer_lookup_full_name (GActionMuxer *muxer, + GActionGroup *subgroup, + const gchar *action_name) +{ + gpointer prefix; + + if (subgroup == muxer->global_actions) + return g_strdup (action_name); + + if (g_hash_table_lookup_extended (muxer->reverse, subgroup, NULL, &prefix)) + return g_strdup_printf ("%s.%s", (gchar *) prefix, action_name); + + return NULL; +} + +static void +g_action_muxer_disconnect_group (GActionMuxer *muxer, + GActionGroup *subgroup) +{ + gchar **actions; + gchar **action; + + actions = g_action_group_list_actions (subgroup); + for (action = actions; *action; action++) + g_action_muxer_action_removed (subgroup, *action, muxer); + g_strfreev (actions); + + g_signal_handlers_disconnect_by_func (subgroup, g_action_muxer_action_added, muxer); + g_signal_handlers_disconnect_by_func (subgroup, g_action_muxer_action_removed, muxer); + g_signal_handlers_disconnect_by_func (subgroup, g_action_muxer_action_enabled_changed, muxer); + g_signal_handlers_disconnect_by_func (subgroup, g_action_muxer_action_state_changed, muxer); +} + +static gchar ** +g_action_muxer_list_actions (GActionGroup *group) +{ + GActionMuxer *muxer = G_ACTION_MUXER (group); + GHashTableIter it; + GArray *all_actions; + gchar *prefix; + GActionGroup *subgroup; + gchar **actions; + gchar **a; + + all_actions = g_array_sized_new (TRUE, FALSE, sizeof (gchar *), 8); + + if (muxer->global_actions) + { + actions = g_action_group_list_actions (muxer->global_actions); + for (a = actions; *a; a++) + { + gchar *name = g_strdup (*a); + g_array_append_val (all_actions, name); + } + g_strfreev (actions); + } + + g_hash_table_iter_init (&it, muxer->groups); + while (g_hash_table_iter_next (&it, (gpointer *) &prefix, (gpointer *) &subgroup)) + { + actions = g_action_group_list_actions (subgroup); + for (a = actions; *a; a++) + { + gchar *full_name = g_strdup_printf ("%s.%s", prefix, *a); + g_array_append_val (all_actions, full_name); + } + g_strfreev (actions); + } + + return (gchar **) g_array_free (all_actions, FALSE); +} + +static void +g_action_muxer_activate_action (GActionGroup *group, + const gchar *action_name, + GVariant *parameter) +{ + GActionMuxer *muxer = G_ACTION_MUXER (group); + GActionGroup *subgroup; + const gchar *action; + + g_return_if_fail (action_name != NULL); + + subgroup = g_action_muxer_lookup_group (muxer, action_name, &action); + + if (subgroup) + g_action_group_activate_action (subgroup, action, parameter); +} + +static void +g_action_muxer_change_action_state (GActionGroup *group, + const gchar *action_name, + GVariant *value) +{ + GActionMuxer *muxer = G_ACTION_MUXER (group); + GActionGroup *subgroup; + const gchar *action; + + g_return_if_fail (action_name != NULL); + + subgroup = g_action_muxer_lookup_group (muxer, action_name, &action); + + if (subgroup) + g_action_group_change_action_state (subgroup, action, value); +} + +static gboolean +g_action_muxer_query_action (GActionGroup *group, + const gchar *action_name, + gboolean *enabled, + const GVariantType **parameter_type, + const GVariantType **state_type, + GVariant **state_hint, + GVariant **state) +{ + GActionMuxer *muxer = G_ACTION_MUXER (group); + GActionGroup *subgroup; + const gchar *action; + + g_return_val_if_fail (action_name != NULL, FALSE); + + subgroup = g_action_muxer_lookup_group (muxer, action_name, &action); + + if (!subgroup) + return FALSE; + + return g_action_group_query_action (subgroup, action, enabled, parameter_type, + state_type, state_hint, state); +} + +static void +g_action_muxer_action_added (GActionGroup *group, + gchar *action_name, + gpointer user_data) +{ + GActionMuxer *muxer = user_data; + gchar *full_name; + + full_name = g_action_muxer_lookup_full_name (muxer, group, action_name); + + if (full_name) + { + g_action_group_action_added (G_ACTION_GROUP (muxer), full_name); + g_free (full_name); + } +} + +static void +g_action_muxer_action_removed (GActionGroup *group, + gchar *action_name, + gpointer user_data) +{ + GActionMuxer *muxer = user_data; + gchar *full_name; + + full_name = g_action_muxer_lookup_full_name (muxer, group, action_name); + + if (full_name) + { + g_action_group_action_removed (G_ACTION_GROUP (muxer), full_name); + g_free (full_name); + } +} + +static void +g_action_muxer_action_state_changed (GActionGroup *group, + gchar *action_name, + GVariant *value, + gpointer user_data) +{ + GActionMuxer *muxer = user_data; + gchar *full_name; + + full_name = g_action_muxer_lookup_full_name (muxer, group, action_name); + + if (full_name) + { + g_action_group_action_state_changed (G_ACTION_GROUP (muxer), full_name, value); + g_free (full_name); + } +} + +static void +g_action_muxer_action_enabled_changed (GActionGroup *group, + gchar *action_name, + gboolean enabled, + gpointer user_data) +{ + GActionMuxer *muxer = user_data; + gchar *full_name; + + full_name = g_action_muxer_lookup_full_name (muxer, group, action_name); + + if (full_name) + { + g_action_group_action_enabled_changed (G_ACTION_GROUP (muxer), full_name, enabled); + g_free (full_name); + } +} + +/* + * g_action_muxer_new: + * + * Creates a new #GActionMuxer. + */ +GActionMuxer * +g_action_muxer_new (void) +{ + return g_object_new (G_TYPE_ACTION_MUXER, NULL); +} + +/* + * g_action_muxer_insert: + * @muxer: a #GActionMuxer + * @prefix: (allow-none): the prefix string for the action group, or NULL + * @group: (allow-none): a #GActionGroup, or NULL + * + * Adds the actions in @group to the list of actions provided by @muxer. + * @prefix is prefixed to each action name, such that for each action + * <varname>x</varname> in @group, there is an equivalent action + * @prefix<literal>.</literal><varname>x</varname> in @muxer. + * + * For example, if @prefix is "<literal>app</literal>" and @group contains an + * action called "<literal>quit</literal>", then @muxer will now contain an + * action called "<literal>app.quit</literal>". + * + * If @prefix is <literal>NULL</literal>, the actions in @group will be added + * to @muxer without prefix. + * + * If @group is <literal>NULL</literal>, this function has the same effect as + * calling g_action_muxer_remove() with @prefix. + * + * There may only be one group per prefix (including the + * <literal>NULL</literal>-prefix). If a group has been added with @prefix in + * a previous call to this function, it will be removed. + * + * @prefix must not contain a dot ('.'). + */ +void +g_action_muxer_insert (GActionMuxer *muxer, + const gchar *prefix, + GActionGroup *group) +{ + gchar *prefix_copy; + gchar **actions; + gchar **action; + + g_return_if_fail (G_IS_ACTION_MUXER (muxer)); + g_return_if_fail (G_IS_ACTION_GROUP (group)); + + g_action_muxer_remove (muxer, prefix); + + if (prefix) + { + prefix_copy = g_strdup (prefix); + g_hash_table_insert (muxer->groups, prefix_copy, g_object_ref (group)); + g_hash_table_insert (muxer->reverse, group, prefix_copy); + } + else + muxer->global_actions = g_object_ref (group); + + actions = g_action_group_list_actions (group); + for (action = actions; *action; action++) + g_action_muxer_action_added (group, *action, muxer); + g_strfreev (actions); + + g_signal_connect (group, "action-added", G_CALLBACK (g_action_muxer_action_added), muxer); + g_signal_connect (group, "action-removed", G_CALLBACK (g_action_muxer_action_removed), muxer); + g_signal_connect (group, "action-enabled-changed", G_CALLBACK (g_action_muxer_action_enabled_changed), muxer); + g_signal_connect (group, "action-state-changed", G_CALLBACK (g_action_muxer_action_state_changed), muxer); +} + +/* + * g_action_muxer_remove: + * @muxer: a #GActionMuxer + * @prefix: (allow-none): the prefix of the action group to remove, or NULL + * + * Removes a #GActionGroup from the #GActionMuxer. + */ +void +g_action_muxer_remove (GActionMuxer *muxer, + const gchar *prefix) +{ + GActionGroup *subgroup; + + g_return_if_fail (G_IS_ACTION_MUXER (muxer)); + + subgroup = prefix ? g_hash_table_lookup (muxer->groups, prefix) : muxer->global_actions; + if (!subgroup) + return; + + g_action_muxer_disconnect_group (muxer, subgroup); + + if (prefix) + { + g_hash_table_remove (muxer->groups, prefix); + g_hash_table_remove (muxer->reverse, subgroup); + } + else + g_clear_object (&muxer->global_actions); +} + diff --git a/src/gactionmuxer.h b/src/gactionmuxer.h new file mode 100644 index 0000000..5c5e839 --- /dev/null +++ b/src/gactionmuxer.h @@ -0,0 +1,44 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Lars Uebernickel <lars.uebernickel@canonical.com> + * Ryan Lortie <desrt@desrt.ca> + */ + +#ifndef __G_ACTION_MUXER_H__ +#define __G_ACTION_MUXER_H__ + +#include <gio/gio.h> + +#define G_TYPE_ACTION_MUXER (g_action_muxer_get_type ()) +#define G_ACTION_MUXER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_ACTION_MUXER, GActionMuxer)) +#define G_IS_ACTION_MUXER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_ACTION_MUXER)) + +typedef struct _GActionMuxer GActionMuxer; + +GType g_action_muxer_get_type (void) G_GNUC_CONST; + +GActionMuxer * g_action_muxer_new (void); + +void g_action_muxer_insert (GActionMuxer *muxer, + const gchar *prefix, + GActionGroup *group); + +void g_action_muxer_remove (GActionMuxer *muxer, + const gchar *prefix); + +#endif + diff --git a/src/gen-messages-service.xml.c b/src/gen-messages-service.xml.c deleted file mode 100644 index 4e94dc3..0000000 --- a/src/gen-messages-service.xml.c +++ /dev/null @@ -1,25 +0,0 @@ -const char * _messages_service = -"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" -"<node name=\"/\">\n" -" <interface name=\"com.canonical.indicator.messages.service\">\n" -"\n" -"<!-- Methods -->\n" -" <method name=\"AttentionRequested\">\n" -" <arg type=\"b\" name=\"dot\" direction=\"out\" />\n" -" </method>\n" -" <method name=\"IconShown\">\n" -" <arg type=\"b\" name=\"hidden\" direction=\"out\" />\n" -" </method>\n" -" <method name=\"ClearAttention\" />\n" -"\n" -"<!-- Signals -->\n" -" <signal name=\"AttentionChanged\">\n" -" <arg type=\"b\" name=\"dot\" direction=\"out\" />\n" -" </signal>\n" -" <signal name=\"IconChanged\">\n" -" <arg type=\"b\" name=\"hidden\" direction=\"out\" />\n" -" </signal>\n" -"\n" -" </interface>\n" -"</node>\n" -; diff --git a/src/gen-messages-service.xml.h b/src/gen-messages-service.xml.h deleted file mode 100644 index 7884498..0000000 --- a/src/gen-messages-service.xml.h +++ /dev/null @@ -1 +0,0 @@ -extern const char * _messages_service; diff --git a/src/gmenuutils.c b/src/gmenuutils.c new file mode 100644 index 0000000..f3ceba7 --- /dev/null +++ b/src/gmenuutils.c @@ -0,0 +1,79 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Lars Uebernickel <lars.uebernickel@canonical.com> + */ + +#include "gmenuutils.h" +#include "dbus-data.h" + +/* g_menu_find_section: + * @menu: a #GMenu + * @section: the section to be found in @menu + * + * @Returns the index of the first menu item that is linked to #section, or -1 + * if there's no such item. + */ +int +g_menu_find_section (GMenu *menu, + GMenuModel *section) +{ + GMenuModel *model = G_MENU_MODEL (menu); + int n_items; + int i; + + g_return_val_if_fail (G_IS_MENU_MODEL (section), -1); + + n_items = g_menu_model_get_n_items (model); + for (i = 0; i < n_items; i++) + { + if (section == g_menu_model_get_item_link (model, i, G_MENU_LINK_SECTION)) + return i; + } + + return -1; +} + + +void +g_menu_append_with_icon (GMenu *menu, + const gchar *label, + GIcon *icon, + const gchar *detailed_action) +{ + gchar *iconstr; + + iconstr = g_icon_to_string (icon); + g_menu_append_with_icon_name (menu, label, iconstr, detailed_action); + + g_free (iconstr); +} + +void +g_menu_append_with_icon_name (GMenu *menu, + const gchar *label, + const gchar *icon_name, + const gchar *detailed_action) +{ + GMenuItem *item; + + item = g_menu_item_new (label, detailed_action); + g_menu_item_set_attribute (item, "x-canonical-icon", "s", icon_name); + + g_menu_append_item (menu, item); + + g_object_unref (item); +} diff --git a/src/gmenuutils.h b/src/gmenuutils.h new file mode 100644 index 0000000..e00ac55 --- /dev/null +++ b/src/gmenuutils.h @@ -0,0 +1,38 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Lars Uebernickel <lars.uebernickel@canonical.com> + */ + +#ifndef __G_MENU_UTILS_H__ +#define __G_MENU_UTILS_H__ + +#include <gio/gio.h> + +int g_menu_find_section (GMenu *menu, + GMenuModel *section); + +void g_menu_append_with_icon (GMenu *menu, + const gchar *label, + GIcon *icon, + const gchar *detailed_action); + +void g_menu_append_with_icon_name (GMenu *menu, + const gchar *label, + const gchar *icon_name, + const gchar *detailed_action); + +#endif diff --git a/src/gsettingsstrv.c b/src/gsettingsstrv.c new file mode 100644 index 0000000..cf889fa --- /dev/null +++ b/src/gsettingsstrv.c @@ -0,0 +1,106 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Lars Uebernickel <lars.uebernickel@canonical.com> + */ + +#include "gsettingsstrv.h" + +/** + * g_settings_strv_append_unique: + * @settings: a #GSettings object + * @key: the key at which @settings contains a string array + * @item: the string to append + * + * Appends @item to the string array at @key if that string array doesn't + * contain @item yet. + * + * Returns: TRUE if @item was added to the list, FALSE if it already existed. + */ +gboolean +g_settings_strv_append_unique (GSettings *settings, + const gchar *key, + const gchar *item) +{ + gchar **strv; + gchar **it; + gboolean add = TRUE; + + g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE); + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (item != NULL, FALSE); + + strv = g_settings_get_strv (settings, key); + + for (it = strv; *it; it++) + { + if (g_str_equal (*it, item)) + { + add = FALSE; + break; + } + } + + if (add) + { + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("as")); + + for (it = strv; *it; it++) + g_variant_builder_add (&builder, "s", *it); + g_variant_builder_add (&builder, "s", item); + + g_settings_set_value (settings, key, g_variant_builder_end (&builder)); + } + + g_strfreev (strv); + return add; +} + +/** + * g_settings_strv_remove: + * @settings: a #GSettings object + * @key: the key at which @settings contains a string array + * @item: the string to remove + * + * Removes all occurences of @item in @key. + */ +void +g_settings_strv_remove (GSettings *settings, + const gchar *key, + const gchar *item) +{ + gchar **strv; + gchar **it; + GVariantBuilder builder; + + g_return_if_fail (G_IS_SETTINGS (settings)); + g_return_if_fail (key != NULL); + g_return_if_fail (item != NULL); + + strv = g_settings_get_strv (settings, key); + + g_variant_builder_init (&builder, (GVariantType *)"as"); + for (it = strv; *it; it++) + { + if (!g_str_equal (*it, item)) + g_variant_builder_add (&builder, "s", *it); + } + g_settings_set_value (settings, key, g_variant_builder_end (&builder)); + + g_strfreev (strv); +} diff --git a/src/gsettingsstrv.h b/src/gsettingsstrv.h new file mode 100644 index 0000000..accebda --- /dev/null +++ b/src/gsettingsstrv.h @@ -0,0 +1,33 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Lars Uebernickel <lars.uebernickel@canonical.com> + */ + +#ifndef __G_SETTINGS_STRV_H__ +#define __G_SETTINGS_STRV_H__ + +#include <gio/gio.h> + +gboolean g_settings_strv_append_unique (GSettings *settings, + const gchar *key, + const gchar *item); + +void g_settings_strv_remove (GSettings *settings, + const gchar *key, + const gchar *item); + +#endif diff --git a/src/im-app-menu-item.c b/src/im-app-menu-item.c new file mode 100644 index 0000000..eddf562 --- /dev/null +++ b/src/im-app-menu-item.c @@ -0,0 +1,350 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Lars Uebernickel <lars.uebernickel@canonical.com> + */ + +#include "im-app-menu-item.h" + +struct _ImAppMenuItemPrivate +{ + GActionGroup *action_group; + gchar *action; + gboolean is_running; + + GtkWidget *icon; + GtkWidget *label; +}; + +enum +{ + PROP_0, + PROP_MENU_ITEM, + PROP_ACTION_GROUP, + NUM_PROPERTIES +}; + +static GParamSpec *properties[NUM_PROPERTIES]; + +G_DEFINE_TYPE (ImAppMenuItem, im_app_menu_item, GTK_TYPE_MENU_ITEM); + +static void +im_app_menu_item_constructed (GObject *object) +{ + ImAppMenuItemPrivate *priv = IM_APP_MENU_ITEM (object)->priv; + GtkWidget *grid; + + priv->icon = g_object_ref (gtk_image_new ()); + + priv->label = g_object_ref (gtk_label_new ("")); + + grid = gtk_grid_new (); + gtk_grid_attach (GTK_GRID (grid), priv->icon, 0, 0, 1, 1); + gtk_grid_attach (GTK_GRID (grid), priv->label, 1, 0, 1, 1); + + gtk_container_add (GTK_CONTAINER (object), grid); + gtk_widget_show_all (grid); + + G_OBJECT_CLASS (im_app_menu_item_parent_class)->constructed (object); +} + +static void +im_app_menu_item_set_action_name (ImAppMenuItem *self, + const gchar *action_name) +{ + ImAppMenuItemPrivate *priv = self->priv; + gboolean enabled = FALSE; + GVariant *state; + + if (priv->action != NULL) + g_free (priv->action); + + priv->action = g_strdup (action_name); + + priv->is_running = FALSE; + + if (priv->action_group != NULL && priv->action != NULL && + g_action_group_query_action (priv->action_group, priv->action, + &enabled, NULL, NULL, NULL, &state)) + { + if (state && g_variant_is_of_type (state, G_VARIANT_TYPE ("b"))) + priv->is_running = g_variant_get_boolean (state); + else + enabled = FALSE; + + if (state) + g_variant_unref (state); + } + + gtk_widget_set_sensitive (GTK_WIDGET (self), enabled); + gtk_widget_queue_draw (GTK_WIDGET (self)); +} + +static void +im_app_menu_item_action_added (GActionGroup *action_group, + gchar *action_name, + gpointer user_data) +{ + ImAppMenuItem *self = user_data; + + if (g_strcmp0 (self->priv->action, action_name) == 0) + im_app_menu_item_set_action_name (self, action_name); +} + +static void +im_app_menu_item_action_removed (GActionGroup *action_group, + gchar *action_name, + gpointer user_data) +{ + ImAppMenuItem *self = user_data; + + if (g_strcmp0 (self->priv->action, action_name) == 0) + { + gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE); + self->priv->is_running = FALSE; + gtk_widget_queue_draw (GTK_WIDGET (self)); + } +} + +static void +im_app_menu_item_action_enabled_changed (GActionGroup *action_group, + gchar *action_name, + gboolean enabled, + gpointer user_data) +{ + ImAppMenuItem *self = user_data; + + if (g_strcmp0 (self->priv->action, action_name) == 0) + gtk_widget_set_sensitive (GTK_WIDGET (self), enabled); +} + +static void +im_app_menu_item_action_state_changed (GActionGroup *action_group, + gchar *action_name, + GVariant *value, + gpointer user_data) +{ + ImAppMenuItem *self = user_data; + + if (g_strcmp0 (self->priv->action, action_name) == 0) + { + g_return_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("b"))); + + self->priv->is_running = g_variant_get_boolean (value); + gtk_widget_queue_draw (GTK_WIDGET (self)); + } +} + +static void +im_app_menu_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + ImAppMenuItem *self = IM_APP_MENU_ITEM (object); + + switch (property_id) + { + case PROP_MENU_ITEM: + im_app_menu_item_set_menu_item (self, G_MENU_ITEM (g_value_get_object (value))); + break; + + case PROP_ACTION_GROUP: + im_app_menu_item_set_action_group (self, G_ACTION_GROUP (g_value_get_object (value))); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +im_app_menu_item_dispose (GObject *object) +{ + ImAppMenuItem *self = IM_APP_MENU_ITEM (object); + + if (self->priv->action_group) + im_app_menu_item_set_action_group (self, NULL); + + g_clear_object (&self->priv->icon); + g_clear_object (&self->priv->label); + + G_OBJECT_CLASS (im_app_menu_item_parent_class)->dispose (object); +} + +static void +im_app_menu_item_finalize (GObject *object) +{ + ImAppMenuItemPrivate *priv = IM_APP_MENU_ITEM (object)->priv; + + g_free (priv->action); + + G_OBJECT_CLASS (im_app_menu_item_parent_class)->finalize (object); +} + +static gboolean +im_app_menu_item_draw (GtkWidget *widget, + cairo_t *cr) +{ + ImAppMenuItemPrivate *priv = IM_APP_MENU_ITEM (widget)->priv; + + GTK_WIDGET_CLASS (im_app_menu_item_parent_class)->draw (widget, cr); + + if (priv->is_running) + { + const int arrow_width = 5; + const double half_arrow_height = 4.5; + GtkAllocation alloc; + GdkRGBA color; + double center; + + gtk_widget_get_allocation (widget, &alloc); + + gtk_style_context_get_color (gtk_widget_get_style_context (widget), + gtk_widget_get_state_flags (widget), + &color); + gdk_cairo_set_source_rgba (cr, &color); + + center = alloc.height / 2 + 0.5; + + cairo_move_to (cr, 0, center - half_arrow_height); + cairo_line_to (cr, 0, center + half_arrow_height); + cairo_line_to (cr, arrow_width, center); + cairo_close_path (cr); + + cairo_fill (cr); + } + + return FALSE; +} + +static void +im_app_menu_item_activate (GtkMenuItem *item) +{ + ImAppMenuItemPrivate *priv = IM_APP_MENU_ITEM (item)->priv; + + if (priv->action && priv->action_group) + g_action_group_activate_action (priv->action_group, priv->action, NULL); +} + +static void +im_app_menu_item_class_init (ImAppMenuItemClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GtkMenuItemClass *menu_item_class = GTK_MENU_ITEM_CLASS (klass); + + g_type_class_add_private (klass, sizeof (ImAppMenuItemPrivate)); + + object_class->constructed = im_app_menu_item_constructed; + object_class->set_property = im_app_menu_set_property; + object_class->dispose = im_app_menu_item_dispose; + object_class->finalize = im_app_menu_item_finalize; + + widget_class->draw = im_app_menu_item_draw; + + menu_item_class->activate = im_app_menu_item_activate; + + properties[PROP_MENU_ITEM] = g_param_spec_object ("menu-item", + "Menu item", + "The model GMenuItem for this menu item", + G_TYPE_MENU_ITEM, + G_PARAM_WRITABLE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_ACTION_GROUP] = g_param_spec_object ("action-group", + "Action group", + "The action group associated with this menu item", + G_TYPE_ACTION_GROUP, + G_PARAM_WRITABLE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, NUM_PROPERTIES, properties); +} + +static void +im_app_menu_item_init (ImAppMenuItem *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + IM_TYPE_APP_MENU_ITEM, + ImAppMenuItemPrivate); +} + +void +im_app_menu_item_set_menu_item (ImAppMenuItem *self, + GMenuItem *menuitem) +{ + gchar *iconstr = NULL; + GIcon *icon = NULL; + gchar *label; + gchar *action = NULL; + + if (g_menu_item_get_attribute (menuitem, "x-canonical-icon", "s", &iconstr)) + { + GError *error; + + icon = g_icon_new_for_string (iconstr, &error); + if (icon == NULL) + { + g_warning ("unable to set icon: %s", error->message); + g_error_free (error); + } + g_free (iconstr); + } + gtk_image_set_from_gicon (GTK_IMAGE (self->priv->icon), icon, GTK_ICON_SIZE_MENU); + + g_menu_item_get_attribute (menuitem, "label", "s", &label); + gtk_label_set_label (GTK_LABEL (self->priv->label), label ? label : ""); + + g_menu_item_get_attribute (menuitem, "action", "s", &action); + im_app_menu_item_set_action_name (self, action); + + if (icon) + g_object_unref (icon); + g_free (label); + g_free (action); +} + +void +im_app_menu_item_set_action_group (ImAppMenuItem *self, + GActionGroup *action_group) +{ + ImAppMenuItemPrivate *priv = self->priv; + + if (priv->action_group != NULL) + { + g_signal_handlers_disconnect_by_func (priv->action_group, im_app_menu_item_action_added, self); + g_signal_handlers_disconnect_by_func (priv->action_group, im_app_menu_item_action_removed, self); + g_signal_handlers_disconnect_by_func (priv->action_group, im_app_menu_item_action_enabled_changed, self); + g_signal_handlers_disconnect_by_func (priv->action_group, im_app_menu_item_action_state_changed, self); + + g_clear_object (&priv->action_group); + } + + if (action_group != NULL) + { + priv->action_group = g_object_ref (action_group); + + g_signal_connect (priv->action_group, "action-added", + G_CALLBACK (im_app_menu_item_action_added), self); + g_signal_connect (priv->action_group, "action-removed", + G_CALLBACK (im_app_menu_item_action_removed), self); + g_signal_connect (priv->action_group, "action-enabled-changed", + G_CALLBACK (im_app_menu_item_action_enabled_changed), self); + g_signal_connect (priv->action_group, "action-state-changed", + G_CALLBACK (im_app_menu_item_action_state_changed), self); + } +} diff --git a/src/im-app-menu-item.h b/src/im-app-menu-item.h new file mode 100644 index 0000000..519de8d --- /dev/null +++ b/src/im-app-menu-item.h @@ -0,0 +1,54 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Lars Uebernickel <lars.uebernickel@canonical.com> + */ + +#ifndef __IM_APP_MENU_ITEM_H__ +#define __IM_APP_MENU_ITEM_H__ + +#include <gtk/gtk.h> + +#define IM_TYPE_APP_MENU_ITEM (im_app_menu_item_get_type ()) +#define IM_APP_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), IM_TYPE_APP_MENU_ITEM, ImAppMenuItem)) +#define IM_APP_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), IM_TYPE_APP_MENU_ITEM, ImAppMenuItemClass)) +#define IS_IM_APP_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IM_TYPE_APP_MENU_ITEM)) +#define IS_IM_APP_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), IM_TYPE_APP_MENU_ITEM)) +#define IM_APP_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), IM_TYPE_APP_MENU_ITEM, ImAppMenuItemClass)) + +typedef struct _ImAppMenuItem ImAppMenuItem; +typedef struct _ImAppMenuItemClass ImAppMenuItemClass; +typedef struct _ImAppMenuItemPrivate ImAppMenuItemPrivate; + +struct _ImAppMenuItemClass +{ + GtkMenuItemClass parent_class; +}; + +struct _ImAppMenuItem +{ + GtkMenuItem parent; + ImAppMenuItemPrivate *priv; +}; + +GType im_app_menu_item_get_type (void); + +void im_app_menu_item_set_menu_item (ImAppMenuItem *item, + GMenuItem *menuitem); +void im_app_menu_item_set_action_group (ImAppMenuItem *self, + GActionGroup *action_group); + +#endif diff --git a/src/im-menu-item.c b/src/im-menu-item.c deleted file mode 100644 index 7466d3e..0000000 --- a/src/im-menu-item.c +++ /dev/null @@ -1,586 +0,0 @@ -/* -An indicator to show information that is in messaging applications -that the user is using. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <glib/gi18n.h> -#include <libdbusmenu-glib/client.h> -#include <libindicate/indicator.h> -#include <libindicate/indicator-messages.h> -#include <libindicate/listener.h> -#include "im-menu-item.h" -#include "dbus-data.h" - -enum { - TIME_CHANGED, - ATTENTION_CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -typedef struct _ImMenuItemPrivate ImMenuItemPrivate; - -struct _ImMenuItemPrivate -{ - IndicateListener * listener; - IndicateListenerServer * server; - IndicateListenerIndicator * indicator; - - glong creation_seconds; - glong seconds; - gchar * count; - gulong indicator_changed; - gboolean attention; - gboolean show; - - guint time_update_min; -}; - -#define IM_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), IM_MENU_ITEM_TYPE, ImMenuItemPrivate)) - -/* Prototypes */ -static void im_menu_item_class_init (ImMenuItemClass *klass); -static void im_menu_item_init (ImMenuItem *self); -static void im_menu_item_dispose (GObject *object); -static void im_menu_item_finalize (GObject *object); -static void sender_cb (IndicateListener * listener, - IndicateListenerServer * server, - IndicateListenerIndicator * indicator, - gchar * property, - const gchar * propertydata, - gpointer data); -static void time_cb (IndicateListener * listener, - IndicateListenerServer * server, - IndicateListenerIndicator * indicator, - gchar * property, - const GTimeVal * propertydata, - gpointer data); -static void icon_cb (IndicateListener * listener, - IndicateListenerServer * server, - IndicateListenerIndicator * indicator, - gchar * property, - const gchar * propertydata, - gpointer data); -static void activate_cb (ImMenuItem * self, - guint timestamp, - gpointer data); -static void indicator_modified_cb (IndicateListener * listener, - IndicateListenerServer * server, - IndicateListenerIndicator * indicator, - gchar * property, - ImMenuItem * self); - -G_DEFINE_TYPE (ImMenuItem, im_menu_item, DBUSMENU_TYPE_MENUITEM); - -static void -im_menu_item_class_init (ImMenuItemClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (ImMenuItemPrivate)); - - object_class->dispose = im_menu_item_dispose; - object_class->finalize = im_menu_item_finalize; - - signals[TIME_CHANGED] = g_signal_new(IM_MENU_ITEM_SIGNAL_TIME_CHANGED, - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ImMenuItemClass, time_changed), - NULL, NULL, - g_cclosure_marshal_VOID__LONG, - G_TYPE_NONE, 1, G_TYPE_LONG); - signals[ATTENTION_CHANGED] = g_signal_new(IM_MENU_ITEM_SIGNAL_ATTENTION_CHANGED, - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ImMenuItemClass, attention_changed), - NULL, NULL, - g_cclosure_marshal_VOID__BOOLEAN, - G_TYPE_NONE, 1, G_TYPE_BOOLEAN); - - return; -} - -static void -im_menu_item_init (ImMenuItem *self) -{ - g_debug("Building new IM Menu Item"); - ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(self); - - /* Set the variables to NULL, but they should be - configured further down the line. */ - priv->listener = NULL; - priv->server = NULL; - priv->indicator = NULL; - - /* A sane default, but look below */ - priv->creation_seconds = 0; - priv->seconds = 0; - - /* Set the seconds to be the time when the item was - created incase we're not given a better time. */ - GTimeVal current_time; - g_get_current_time(¤t_time); - priv->creation_seconds = current_time.tv_sec; - - return; -} - -static void -im_menu_item_dispose (GObject *object) -{ - G_OBJECT_CLASS (im_menu_item_parent_class)->dispose (object); - - ImMenuItem * self = IM_MENU_ITEM(object); - ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(self); - - if (priv->time_update_min != 0) { - g_source_remove(priv->time_update_min); - } - - g_signal_handler_disconnect(priv->listener, priv->indicator_changed); - priv->indicator_changed = 0; - - return; -} - -static void -im_menu_item_finalize (GObject *object) -{ - G_OBJECT_CLASS (im_menu_item_parent_class)->finalize (object); -} - -/* Call back for getting icon data. It just passes it along - to the indicator so that it can visualize it. Not our problem. */ -static void -icon_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, const gchar * propertydata, gpointer data) -{ - gsize len; - guchar *icon; - icon = g_base64_decode (propertydata, &len); - dbusmenu_menuitem_property_set_byte_array(DBUSMENU_MENUITEM(data), INDICATOR_MENUITEM_PROP_ICON, icon, len); - g_free (icon); - return; -} - -/* This function takes the time and turns it into the appropriate - string to put on the right side of the menu item. Of course it - doesn't do that if there is a count set. If there's a count then - it gets that space. */ -static void -update_time (ImMenuItem * self) -{ - ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(self); - - /* Count has been set, so it takes priority. */ - if (priv->count != NULL) { - return; - } - - /* Seconds hasn't been set, so we just want to keep the time - area blank. */ - if (priv->seconds == 0) { - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), INDICATOR_MENUITEM_PROP_RIGHT, ""); - return; - } - - gchar * timestring = NULL; - - GTimeVal current_time; - g_get_current_time(¤t_time); - - guint elapsed_seconds = current_time.tv_sec - priv->seconds; - guint elapsed_minutes = elapsed_seconds / 60; - - if (elapsed_seconds % 60 > 55) { - /* We're using fuzzy timers, so we need fuzzy comparisons */ - elapsed_minutes += 1; - } - - if (elapsed_minutes < 60) { - /* TRANSLATORS: This string is used to represent the number of minutes - since an IM has occured. It is in the right column - of a menu so being brief is desirable, but one character - is not a requirement. */ - timestring = g_strdup_printf(ngettext("%d m", "%d m", elapsed_minutes), elapsed_minutes); - } else { - guint elapsed_hours = elapsed_minutes / 60; - - if (elapsed_minutes % 60 > 55) { - /* We're using fuzzy timers, so we need fuzzy comparisons */ - elapsed_hours += 1; - } - - /* TRANSLATORS: This string is used to represent the number of hours - since an IM has occured. It is in the right column - of a menu so being brief is desirable, but one character - is not a requirement. */ - timestring = g_strdup_printf(ngettext("%d h", "%d h", elapsed_hours), elapsed_hours); - } - - if (timestring != NULL) { - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), INDICATOR_MENUITEM_PROP_RIGHT, timestring); - g_free(timestring); - } - - return; -} - -/* This is a wrapper around update_time that matches the prototype - needed to make this a timer callback. Silly. */ -static gboolean -time_update_cb (gpointer data) -{ - ImMenuItem * self = IM_MENU_ITEM(data); - - update_time(self); - - return TRUE; -} - -/* Yet another time function. This one takes the time as formated as - we get it from libindicate and turns it into the seconds that we're - looking for. It should only be called once at the init with a new - indicator and again when the value changes. */ -static void -time_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, const GTimeVal * propertydata, gpointer data) -{ - g_debug("Got Time info"); - ImMenuItem * self = IM_MENU_ITEM(data); - if (self == NULL) { - g_error("Menu Item callback called without a menu item"); - return; - } - - if (property == NULL || g_strcmp0(property, "time")) { - g_warning("Time callback called without being sent the time."); - return; - } - - ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(self); - - priv->seconds = propertydata->tv_sec; - - update_time(self); - - if (priv->time_update_min == 0) { - priv->time_update_min = g_timeout_add_seconds(60, time_update_cb, self); - } - - g_signal_emit(G_OBJECT(self), signals[TIME_CHANGED], 0, priv->seconds, TRUE); - - return; -} - -/* Returns a newly allocated string which is 'str' with all occurences of - * consecutive whitespace collapsed into single space character. */ -static gchar * -collapse_whitespace (const gchar *str) -{ - GString *result; - gboolean in_space = FALSE; - - if (!str) - return NULL; - - result = g_string_sized_new (strlen (str)); - - while (*str) { - gunichar c = g_utf8_get_char_validated (str, -1); - - if (c < 0) - break; - - if (!g_unichar_isspace (c)) { - g_string_append_unichar (result, c); - in_space = FALSE; - } - else if (!in_space) { - g_string_append_c (result, ' '); - in_space = TRUE; - } - - str = g_utf8_next_char (str); - } - - return g_string_free (result, FALSE); -} - -/* Callback from libindicate that is for getting the sender information - on a particular indicator. */ -static void -sender_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, const gchar * propertydata, gpointer data) -{ - gchar *label; - - g_debug("Got Sender Information: %s", propertydata); - ImMenuItem * self = IM_MENU_ITEM(data); - - /* Our data should be right */ - g_return_if_fail(self != NULL); - /* We should have a property name */ - g_return_if_fail(property != NULL); - /* The Property should be sender or name */ - g_return_if_fail(!g_strcmp0(property, "sender") || !g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_NAME)); - - /* We might get the sender variable returning a - null string as it doesn't exist on newer clients - but we don't want to listen to that. */ - if (!g_strcmp0(property, "sender") && propertydata[0] == '\0') { - return; - } - - label = collapse_whitespace (propertydata); - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), INDICATOR_MENUITEM_PROP_LABEL, label); - g_free (label); - - return; -} - -/* Callback saying that the count is updated, we need to either put - that on the menu item or just remove it if the count is gone. If - that's the case we can update time. */ -static void -count_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, const gchar * propertydata, gpointer data) -{ - g_debug("Got Count Information"); - ImMenuItem * self = IM_MENU_ITEM(data); - - /* Our data should be right */ - g_return_if_fail(self != NULL); - /* We should have a property name */ - g_return_if_fail(property != NULL); - /* The Property should be count */ - g_return_if_fail(!g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_COUNT)); - - ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(self); - - if (propertydata == NULL || propertydata[0] == '\0') { - /* The count is either being unset or it was never - set in the first place. */ - if (priv->count != NULL) { - g_free(priv->count); - priv->count = NULL; - update_time(self); - dbusmenu_menuitem_property_set_bool (DBUSMENU_MENUITEM (self), - INDICATOR_MENUITEM_PROP_RIGHT_IS_LOZENGE, - FALSE); - } - return; - } - - if (priv->count != NULL) { - g_free(priv->count); - } - - priv->count = g_strdup_printf("%s", propertydata); - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), INDICATOR_MENUITEM_PROP_RIGHT, priv->count); - dbusmenu_menuitem_property_set_bool (DBUSMENU_MENUITEM (self), - INDICATOR_MENUITEM_PROP_RIGHT_IS_LOZENGE, - TRUE); - - return; -} - -/* This is getting the attention variable that's looking at whether - this indicator should be calling for attention or not. If we are, - we need to signal that. */ -static void -attention_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, GVariant * propertydata, gpointer data) -{ - g_debug("Got Attention Information"); - ImMenuItem * self = IM_MENU_ITEM(data); - - /* Our data should be right */ - g_return_if_fail(self != NULL); - /* We should have a property name */ - g_return_if_fail(property != NULL); - /* The Property should be count */ - g_return_if_fail(!g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_ATTENTION)); - - ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(self); - - gboolean wantit; - if (g_variant_is_of_type(propertydata, G_VARIANT_TYPE_BOOLEAN)) { - wantit = g_variant_get_boolean(propertydata); - } else if (g_variant_is_of_type(propertydata, G_VARIANT_TYPE_STRING)) { - const gchar * propstring = g_variant_get_string(propertydata, NULL); - - if (propstring == NULL || propstring[0] == '\0' || !g_strcmp0(propstring, "false")) { - wantit = FALSE; - } else { - wantit = TRUE; - } - } else { - g_warning("Got property '%s' of an unknown type.", property); - return; - } - - if (priv->attention != wantit) { - priv->attention = wantit; - g_signal_emit(G_OBJECT(self), signals[ATTENTION_CHANGED], 0, wantit, TRUE); - } - - return; -} - -/* Callback when the item gets clicked on from the Messaging Menu */ -static void -activate_cb (ImMenuItem * self, guint timestamp, gpointer data) -{ - ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(self); - - indicate_listener_display(priv->listener, priv->server, priv->indicator, timestamp); -} - -/* Callback when a property gets modified. It figures out which one - got modified and notifies the appropriate person. */ -void -indicator_modified_cb (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gchar * property, ImMenuItem * self) -{ - ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(self); - - /* Not meant for us */ - if (INDICATE_LISTENER_INDICATOR_ID(indicator) != INDICATE_LISTENER_INDICATOR_ID(priv->indicator)) return; - if (server != priv->server) return; - - /* Determine which property has been changed and request the - value go to the appropriate callback. */ - if (!g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_NAME)) { - indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_NAME, sender_cb, self); - } else if (!g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_TIME)) { - indicate_listener_get_property_time(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_TIME, time_cb, self); - } else if (!g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_ICON)) { - indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_ICON, icon_cb, self); - } else if (!g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_COUNT)) { - indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_COUNT, count_cb, self); - } else if (!g_strcmp0(property, INDICATE_INDICATOR_MESSAGES_PROP_ATTENTION)) { - indicate_listener_get_property_variant(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_ATTENTION, attention_cb, self); - } else if (!g_strcmp0(property, "sender")) { - /* This is a compatibility string with v1 and should be removed */ - g_debug("Indicator is using 'sender' property which is a v1 string."); - indicate_listener_get_property(listener, server, indicator, "sender", sender_cb, self); - } - - return; -} - -ImMenuItem * -im_menu_item_new (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator) -{ - ImMenuItem * self = g_object_new(IM_MENU_ITEM_TYPE, NULL); - - ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(self); - - priv->listener = listener; - priv->server = server; - priv->indicator = indicator; - priv->count = NULL; - priv->time_update_min = 0; - priv->attention = FALSE; - priv->show = TRUE; - - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_TYPE, INDICATOR_MENUITEM_TYPE); - - indicate_listener_displayed(listener, server, indicator, TRUE); - - indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_NAME, sender_cb, self); - indicate_listener_get_property_time(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_TIME, time_cb, self); - indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_ICON, icon_cb, self); - indicate_listener_get_property(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_COUNT, count_cb, self); - indicate_listener_get_property_variant(listener, server, indicator, INDICATE_INDICATOR_MESSAGES_PROP_ATTENTION, attention_cb, self); - indicate_listener_get_property(listener, server, indicator, "sender", sender_cb, self); - - g_signal_connect(G_OBJECT(self), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), NULL); - priv->indicator_changed = g_signal_connect(G_OBJECT(listener), INDICATE_LISTENER_SIGNAL_INDICATOR_MODIFIED, G_CALLBACK(indicator_modified_cb), self); - - return self; -} - -/* Gets the number of seconds for the creator - of this item. */ -glong -im_menu_item_get_seconds (ImMenuItem * menuitem) -{ - g_return_val_if_fail(IS_IM_MENU_ITEM(menuitem), 0); - - ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(menuitem); - - if (priv->seconds == 0) { - return priv->creation_seconds; - } else { - return priv->seconds; - } -} - -/* Gets whether or not this indicator item is - asking for attention or not. */ -gboolean -im_menu_item_get_attention (ImMenuItem * menuitem) -{ - g_return_val_if_fail(IS_IM_MENU_ITEM(menuitem), FALSE); - - ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(menuitem); - return priv->attention; -} - -/* This takes care of items that need to be hidden, this is - usually because they go over the count of allowed indicators. - Which is more than a little bit silly. We shouldn't do that. - But we need to enforce it to save users against bad apps. */ -void -im_menu_item_show (ImMenuItem * menuitem, gboolean show) -{ - g_return_if_fail(IS_IM_MENU_ITEM(menuitem)); - - ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(menuitem); - - if (priv->show == show) { - return; - } - - priv->show = show; - /* Tell the app what we're doing to it. If it's being - punished it needs to know about it. */ - indicate_listener_displayed(priv->listener, priv->server, priv->indicator, priv->show); - if (priv->attention) { - /* If we were asking for attention we can ask for it - again if we're being shown, otherwise no. */ - g_signal_emit(G_OBJECT(menuitem), signals[ATTENTION_CHANGED], 0, priv->show, TRUE); - } - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(menuitem), DBUSMENU_MENUITEM_PROP_VISIBLE, priv->show ? "true" : "false"); - - return; -} - -/* Check to see if this item is shown. Accessor for the - internal variable. */ -gboolean -im_menu_item_shown (ImMenuItem * menuitem) -{ - g_return_val_if_fail(IS_IM_MENU_ITEM(menuitem), FALSE); - - ImMenuItemPrivate * priv = IM_MENU_ITEM_GET_PRIVATE(menuitem); - - return priv->show; -} diff --git a/src/im-menu-item.h b/src/im-menu-item.h deleted file mode 100644 index 4279c2e..0000000 --- a/src/im-menu-item.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -An indicator to show information that is in messaging applications -that the user is using. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ -#ifndef __IM_MENU_ITEM_H__ -#define __IM_MENU_ITEM_H__ - -#include <glib.h> -#include <glib-object.h> - -#include <libdbusmenu-glib/menuitem.h> -#include <libindicate/listener.h> - -G_BEGIN_DECLS - -#define IM_MENU_ITEM_TYPE (im_menu_item_get_type ()) -#define IM_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), IM_MENU_ITEM_TYPE, ImMenuItem)) -#define IM_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), IM_MENU_ITEM_TYPE, ImMenuItemClass)) -#define IS_IM_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IM_MENU_ITEM_TYPE)) -#define IS_IM_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), IM_MENU_ITEM_TYPE)) -#define IM_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), IM_MENU_ITEM_TYPE, ImMenuItemClass)) - -#define IM_MENU_ITEM_SIGNAL_TIME_CHANGED "time-changed" -#define IM_MENU_ITEM_SIGNAL_ATTENTION_CHANGED "attention-changed" - -typedef struct _ImMenuItem ImMenuItem; -typedef struct _ImMenuItemClass ImMenuItemClass; - -struct _ImMenuItemClass { - DbusmenuMenuitemClass parent_class; - - void (*time_changed) (glong seconds); - void (*attention_changed) (gboolean requestit); -}; - -struct _ImMenuItem { - DbusmenuMenuitem parent; -}; - -GType im_menu_item_get_type (void); -ImMenuItem * im_menu_item_new (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator); -glong im_menu_item_get_seconds (ImMenuItem * menuitem); -gboolean im_menu_item_get_attention (ImMenuItem * menuitem); -void im_menu_item_show (ImMenuItem * menuitem, gboolean show); -gboolean im_menu_item_shown (ImMenuItem * menuitem); - -G_END_DECLS - -#endif - diff --git a/src/im-source-menu-item.c b/src/im-source-menu-item.c new file mode 100644 index 0000000..269c75d --- /dev/null +++ b/src/im-source-menu-item.c @@ -0,0 +1,410 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Lars Uebernickel <lars.uebernickel@canonical.com> + */ + +#include "im-source-menu-item.h" + +#include <libintl.h> + +struct _ImSourceMenuItemPrivate +{ + GActionGroup *action_group; + gchar *action; + + GtkWidget *icon; + GtkWidget *label; + GtkWidget *detail; +}; + +enum +{ + PROP_0, + PROP_MENU_ITEM, + PROP_ACTION_GROUP, + NUM_PROPERTIES +}; + +static GParamSpec *properties[NUM_PROPERTIES]; + +G_DEFINE_TYPE (ImSourceMenuItem, im_source_menu_item, GTK_TYPE_MENU_ITEM); + +static void +im_source_menu_item_constructed (GObject *object) +{ + ImSourceMenuItemPrivate *priv = IM_SOURCE_MENU_ITEM (object)->priv; + GtkWidget *grid; + gint icon_width; + + gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, NULL); + + priv->icon = g_object_ref (gtk_image_new ()); + gtk_widget_set_margin_left (priv->icon, icon_width + 2); + + priv->label = g_object_ref (gtk_label_new ("")); + + priv->detail = g_object_ref (gtk_label_new ("")); + gtk_widget_set_halign (priv->detail, GTK_ALIGN_END); + gtk_widget_set_hexpand (priv->detail, TRUE); + gtk_misc_set_alignment (GTK_MISC (priv->label), 1.0, 0.5); + gtk_style_context_add_class (gtk_widget_get_style_context (priv->detail), "accelerator"); + + grid = gtk_grid_new (); + gtk_grid_attach (GTK_GRID (grid), priv->icon, 0, 0, 1, 1); + gtk_grid_attach (GTK_GRID (grid), priv->label, 1, 0, 1, 1); + gtk_grid_attach (GTK_GRID (grid), priv->detail, 2, 0, 1, 1); + + gtk_container_add (GTK_CONTAINER (object), grid); + gtk_widget_show_all (grid); + + G_OBJECT_CLASS (im_source_menu_item_parent_class)->constructed (object); +} + +/* collapse_whitespace: + * @str: the source string + * + * Collapses all occurences of consecutive whitespace charactes in @str + * into a single space. + * + * Returns: (transfer full): a newly-allocated string + */ +static gchar * +collapse_whitespace (const gchar *str) +{ + GString *result; + gboolean in_space = FALSE; + + if (str == NULL) + return NULL; + + result = g_string_new (""); + + while (*str) + { + gunichar c = g_utf8_get_char_validated (str, -1); + + if (c < 0) + break; + + if (!g_unichar_isspace (c)) + { + g_string_append_unichar (result, c); + in_space = FALSE; + } + else if (!in_space) + { + g_string_append_c (result, ' '); + in_space = TRUE; + } + + str = g_utf8_next_char (str); + } + + return g_string_free (result, FALSE); +} + +static gchar * +im_source_menu_item_time_span_string (gint64 timestamp) +{ + gchar *str; + gint64 span; + gint hours; + gint minutes; + + span = MAX (g_get_real_time () - timestamp, 0) / G_USEC_PER_SEC; + hours = span / 3600; + minutes = (span / 60) % 60; + + if (hours == 0) + { + /* TRANSLATORS: number of minutes that have passed */ + str = g_strdup_printf (ngettext ("%d m", "%d m", minutes), minutes); + } + else + { + /* TRANSLATORS: number of hours that have passed */ + str = g_strdup_printf (ngettext ("%d h", "%d h", hours), hours); + } + + return str; +} + +static gboolean +im_source_menu_item_set_state (ImSourceMenuItem *self, + GVariant *state) +{ + ImSourceMenuItemPrivate *priv = self->priv; + guint32 count; + gint64 time; + const gchar *str; + gchar *detail; + + g_return_val_if_fail (g_variant_is_of_type (state, G_VARIANT_TYPE ("(uxsb)")), FALSE); + + g_variant_get (state, "(ux&sb)", &count, &time, &str, NULL); + + if (count != 0) + detail = g_strdup_printf ("%d", count); + else if (time != 0) + detail = im_source_menu_item_time_span_string (time); + else if (str != NULL && *str) + detail = collapse_whitespace (str); + else + detail = NULL; + + gtk_label_set_text (GTK_LABEL (priv->detail), detail ? detail : ""); + + g_free (detail); + return TRUE; +} + +static void +im_source_menu_item_set_action_name (ImSourceMenuItem *self, + const gchar *action_name) +{ + ImSourceMenuItemPrivate *priv = self->priv; + gboolean enabled = FALSE; + GVariant *state; + + if (priv->action != NULL) + g_free (priv->action); + + priv->action = g_strdup (action_name); + + if (priv->action_group != NULL && priv->action != NULL && + g_action_group_query_action (priv->action_group, priv->action, + &enabled, NULL, NULL, NULL, &state)) + { + if (!state || !im_source_menu_item_set_state (self, state)) + enabled = FALSE; + + if (state) + g_variant_unref (state); + } + + gtk_widget_set_sensitive (GTK_WIDGET (self), enabled); +} + +static void +im_source_menu_item_action_added (GActionGroup *action_group, + gchar *action_name, + gpointer user_data) +{ + ImSourceMenuItem *self = user_data; + + if (g_strcmp0 (self->priv->action, action_name) == 0) + im_source_menu_item_set_action_name (self, action_name); +} + +static void +im_source_menu_item_action_removed (GActionGroup *action_group, + gchar *action_name, + gpointer user_data) +{ + ImSourceMenuItem *self = user_data; + + if (g_strcmp0 (self->priv->action, action_name) == 0) + { + gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE); + } +} + +static void +im_source_menu_item_action_enabled_changed (GActionGroup *action_group, + gchar *action_name, + gboolean enabled, + gpointer user_data) +{ + ImSourceMenuItem *self = user_data; + + if (g_strcmp0 (self->priv->action, action_name) == 0) + gtk_widget_set_sensitive (GTK_WIDGET (self), enabled); +} + +static void +im_source_menu_item_action_state_changed (GActionGroup *action_group, + gchar *action_name, + GVariant *value, + gpointer user_data) +{ + ImSourceMenuItem *self = user_data; + + if (g_strcmp0 (self->priv->action, action_name) == 0) + im_source_menu_item_set_state (self, value); +} + +static void +im_source_menu_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + ImSourceMenuItem *self = IM_SOURCE_MENU_ITEM (object); + + switch (property_id) + { + case PROP_MENU_ITEM: + im_source_menu_item_set_menu_item (self, G_MENU_ITEM (g_value_get_object (value))); + break; + + case PROP_ACTION_GROUP: + im_source_menu_item_set_action_group (self, G_ACTION_GROUP (g_value_get_object (value))); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +im_source_menu_item_dispose (GObject *object) +{ + ImSourceMenuItem *self = IM_SOURCE_MENU_ITEM (object); + + if (self->priv->action_group) + im_source_menu_item_set_action_group (self, NULL); + + g_clear_object (&self->priv->icon); + g_clear_object (&self->priv->label); + g_clear_object (&self->priv->detail); + + G_OBJECT_CLASS (im_source_menu_item_parent_class)->dispose (object); +} + +static void +im_source_menu_item_finalize (GObject *object) +{ + ImSourceMenuItemPrivate *priv = IM_SOURCE_MENU_ITEM (object)->priv; + + g_free (priv->action); + + G_OBJECT_CLASS (im_source_menu_item_parent_class)->finalize (object); +} + +static void +im_source_menu_item_activate (GtkMenuItem *item) +{ + ImSourceMenuItemPrivate *priv = IM_SOURCE_MENU_ITEM (item)->priv; + + if (priv->action && priv->action_group) + g_action_group_activate_action (priv->action_group, priv->action, NULL); +} + +static void +im_source_menu_item_class_init (ImSourceMenuItemClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkMenuItemClass *menu_item_class = GTK_MENU_ITEM_CLASS (klass); + + g_type_class_add_private (klass, sizeof (ImSourceMenuItemPrivate)); + + object_class->constructed = im_source_menu_item_constructed; + object_class->set_property = im_source_menu_set_property; + object_class->dispose = im_source_menu_item_dispose; + object_class->finalize = im_source_menu_item_finalize; + + menu_item_class->activate = im_source_menu_item_activate; + + properties[PROP_MENU_ITEM] = g_param_spec_object ("menu-item", + "Menu item", + "The model GMenuItem for this menu item", + G_TYPE_MENU_ITEM, + G_PARAM_WRITABLE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_ACTION_GROUP] = g_param_spec_object ("action-group", + "Action group", + "The action group associated with this menu item", + G_TYPE_ACTION_GROUP, + G_PARAM_WRITABLE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, NUM_PROPERTIES, properties); +} + +static void +im_source_menu_item_init (ImSourceMenuItem *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + IM_TYPE_SOURCE_MENU_ITEM, + ImSourceMenuItemPrivate); +} + +void +im_source_menu_item_set_menu_item (ImSourceMenuItem *self, + GMenuItem *menuitem) +{ + gchar *iconstr = NULL; + GIcon *icon = NULL; + gchar *label; + gchar *action = NULL; + + if (g_menu_item_get_attribute (menuitem, "x-canonical-icon", "s", &iconstr)) + { + GError *error; + icon = g_icon_new_for_string (iconstr, &error); + if (icon == NULL) + { + g_warning ("unable to set icon: %s", error->message); + g_error_free (error); + } + g_free (iconstr); + } + gtk_image_set_from_gicon (GTK_IMAGE (self->priv->icon), icon, GTK_ICON_SIZE_MENU); + + g_menu_item_get_attribute (menuitem, "label", "s", &label); + gtk_label_set_label (GTK_LABEL (self->priv->label), label ? label : ""); + + g_menu_item_get_attribute (menuitem, "action", "s", &action); + im_source_menu_item_set_action_name (self, action); + + if (icon) + g_object_unref (icon); + g_free (label); + g_free (action); +} + +void +im_source_menu_item_set_action_group (ImSourceMenuItem *self, + GActionGroup *action_group) +{ + ImSourceMenuItemPrivate *priv = self->priv; + + if (priv->action_group != NULL) + { + g_signal_handlers_disconnect_by_func (priv->action_group, im_source_menu_item_action_added, self); + g_signal_handlers_disconnect_by_func (priv->action_group, im_source_menu_item_action_removed, self); + g_signal_handlers_disconnect_by_func (priv->action_group, im_source_menu_item_action_enabled_changed, self); + g_signal_handlers_disconnect_by_func (priv->action_group, im_source_menu_item_action_state_changed, self); + + g_clear_object (&priv->action_group); + } + + if (action_group != NULL) + { + priv->action_group = g_object_ref (action_group); + + g_signal_connect (priv->action_group, "action-added", + G_CALLBACK (im_source_menu_item_action_added), self); + g_signal_connect (priv->action_group, "action-removed", + G_CALLBACK (im_source_menu_item_action_removed), self); + g_signal_connect (priv->action_group, "action-enabled-changed", + G_CALLBACK (im_source_menu_item_action_enabled_changed), self); + g_signal_connect (priv->action_group, "action-state-changed", + G_CALLBACK (im_source_menu_item_action_state_changed), self); + } +} diff --git a/src/im-source-menu-item.h b/src/im-source-menu-item.h new file mode 100644 index 0000000..c359b94 --- /dev/null +++ b/src/im-source-menu-item.h @@ -0,0 +1,54 @@ +/* + * Copyright 2012 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Lars Uebernickel <lars.uebernickel@canonical.com> + */ + +#ifndef __IM_SOURCE_MENU_ITEM_H__ +#define __IM_SOURCE_MENU_ITEM_H__ + +#include <gtk/gtk.h> + +#define IM_TYPE_SOURCE_MENU_ITEM (im_source_menu_item_get_type ()) +#define IM_SOURCE_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), IM_TYPE_SOURCE_MENU_ITEM, ImSourceMenuItem)) +#define IM_SOURCE_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), IM_TYPE_SOURCE_MENU_ITEM, ImSourceMenuItemClass)) +#define IS_IM_SOURCE_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IM_TYPE_SOURCE_MENU_ITEM)) +#define IS_IM_SOURCE_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), IM_TYPE_SOURCE_MENU_ITEM)) +#define IM_SOURCE_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), IM_TYPE_SOURCE_MENU_ITEM, ImSourceMenuItemClass)) + +typedef struct _ImSourceMenuItem ImSourceMenuItem; +typedef struct _ImSourceMenuItemClass ImSourceMenuItemClass; +typedef struct _ImSourceMenuItemPrivate ImSourceMenuItemPrivate; + +struct _ImSourceMenuItemClass +{ + GtkMenuItemClass parent_class; +}; + +struct _ImSourceMenuItem +{ + GtkMenuItem parent; + ImSourceMenuItemPrivate *priv; +}; + +GType im_source_menu_item_get_type (void); + +void im_source_menu_item_set_menu_item (ImSourceMenuItem *item, + GMenuItem *menuitem); +void im_source_menu_item_set_action_group (ImSourceMenuItem *self, + GActionGroup *action_group); + +#endif diff --git a/src/indicator-messages-service.c b/src/indicator-messages-service.c new file mode 100644 index 0000000..24772c1 --- /dev/null +++ b/src/indicator-messages-service.c @@ -0,0 +1,1465 @@ +/* + * Generated by gdbus-codegen 2.33.8. DO NOT EDIT. + * + * The license of this code is the same as for the source it was derived from. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "indicator-messages-service.h" + +#include <string.h> +#ifdef G_OS_UNIX +# include <gio/gunixfdlist.h> +#endif + +typedef struct +{ + GDBusArgInfo parent_struct; + gboolean use_gvariant; +} _ExtendedGDBusArgInfo; + +typedef struct +{ + GDBusMethodInfo parent_struct; + const gchar *signal_name; + gboolean pass_fdlist; +} _ExtendedGDBusMethodInfo; + +typedef struct +{ + GDBusSignalInfo parent_struct; + const gchar *signal_name; +} _ExtendedGDBusSignalInfo; + +typedef struct +{ + GDBusPropertyInfo parent_struct; + const gchar *hyphen_name; + gboolean use_gvariant; +} _ExtendedGDBusPropertyInfo; + +typedef struct +{ + GDBusInterfaceInfo parent_struct; + const gchar *hyphen_name; +} _ExtendedGDBusInterfaceInfo; + +typedef struct +{ + const _ExtendedGDBusPropertyInfo *info; + guint prop_id; + GValue orig_value; /* the value before the change */ +} ChangedProperty; + +static void +_changed_property_free (ChangedProperty *data) +{ + g_value_unset (&data->orig_value); + g_free (data); +} + +static gboolean +_g_strv_equal0 (gchar **a, gchar **b) +{ + gboolean ret = FALSE; + guint n; + if (a == NULL && b == NULL) + { + ret = TRUE; + goto out; + } + if (a == NULL || b == NULL) + goto out; + if (g_strv_length (a) != g_strv_length (b)) + goto out; + for (n = 0; a[n] != NULL; n++) + if (g_strcmp0 (a[n], b[n]) != 0) + goto out; + ret = TRUE; +out: + return ret; +} + +static gboolean +_g_variant_equal0 (GVariant *a, GVariant *b) +{ + gboolean ret = FALSE; + if (a == NULL && b == NULL) + { + ret = TRUE; + goto out; + } + if (a == NULL || b == NULL) + goto out; + ret = g_variant_equal (a, b); +out: + return ret; +} + +G_GNUC_UNUSED static gboolean +_g_value_equal (const GValue *a, const GValue *b) +{ + gboolean ret = FALSE; + g_assert (G_VALUE_TYPE (a) == G_VALUE_TYPE (b)); + switch (G_VALUE_TYPE (a)) + { + case G_TYPE_BOOLEAN: + ret = (g_value_get_boolean (a) == g_value_get_boolean (b)); + break; + case G_TYPE_UCHAR: + ret = (g_value_get_uchar (a) == g_value_get_uchar (b)); + break; + case G_TYPE_INT: + ret = (g_value_get_int (a) == g_value_get_int (b)); + break; + case G_TYPE_UINT: + ret = (g_value_get_uint (a) == g_value_get_uint (b)); + break; + case G_TYPE_INT64: + ret = (g_value_get_int64 (a) == g_value_get_int64 (b)); + break; + case G_TYPE_UINT64: + ret = (g_value_get_uint64 (a) == g_value_get_uint64 (b)); + break; + case G_TYPE_DOUBLE: + { + /* Avoid -Wfloat-equal warnings by doing a direct bit compare */ + gdouble da = g_value_get_double (a); + gdouble db = g_value_get_double (b); + ret = memcmp (&da, &db, sizeof (gdouble)) == 0; + } + break; + case G_TYPE_STRING: + ret = (g_strcmp0 (g_value_get_string (a), g_value_get_string (b)) == 0); + break; + case G_TYPE_VARIANT: + ret = _g_variant_equal0 (g_value_get_variant (a), g_value_get_variant (b)); + break; + default: + if (G_VALUE_TYPE (a) == G_TYPE_STRV) + ret = _g_strv_equal0 (g_value_get_boxed (a), g_value_get_boxed (b)); + else + g_critical ("_g_value_equal() does not handle type %s", g_type_name (G_VALUE_TYPE (a))); + break; + } + return ret; +} + +/* ------------------------------------------------------------------------ + * Code for interface com.canonical.indicator.messages.service + * ------------------------------------------------------------------------ + */ + +/** + * SECTION:IndicatorMessagesService + * @title: IndicatorMessagesService + * @short_description: Generated C code for the com.canonical.indicator.messages.service D-Bus interface + * + * This section contains code for working with the <link linkend="gdbus-interface-com-canonical-indicator-messages-service.top_of_page">com.canonical.indicator.messages.service</link> D-Bus interface in C. + */ + +/* ---- Introspection data for com.canonical.indicator.messages.service ---- */ + +static const _ExtendedGDBusArgInfo _indicator_messages_service_method_info_register_application_IN_ARG_desktop_id = +{ + { + -1, + (gchar *) "desktop_id", + (gchar *) "s", + NULL + }, + FALSE +}; + +static const _ExtendedGDBusArgInfo _indicator_messages_service_method_info_register_application_IN_ARG_menu_path = +{ + { + -1, + (gchar *) "menu_path", + (gchar *) "o", + NULL + }, + FALSE +}; + +static const _ExtendedGDBusArgInfo * const _indicator_messages_service_method_info_register_application_IN_ARG_pointers[] = +{ + &_indicator_messages_service_method_info_register_application_IN_ARG_desktop_id, + &_indicator_messages_service_method_info_register_application_IN_ARG_menu_path, + NULL +}; + +static const _ExtendedGDBusMethodInfo _indicator_messages_service_method_info_register_application = +{ + { + -1, + (gchar *) "RegisterApplication", + (GDBusArgInfo **) &_indicator_messages_service_method_info_register_application_IN_ARG_pointers, + NULL, + NULL + }, + "handle-register-application", + FALSE +}; + +static const _ExtendedGDBusArgInfo _indicator_messages_service_method_info_unregister_application_IN_ARG_desktop_id = +{ + { + -1, + (gchar *) "desktop_id", + (gchar *) "s", + NULL + }, + FALSE +}; + +static const _ExtendedGDBusArgInfo * const _indicator_messages_service_method_info_unregister_application_IN_ARG_pointers[] = +{ + &_indicator_messages_service_method_info_unregister_application_IN_ARG_desktop_id, + NULL +}; + +static const _ExtendedGDBusMethodInfo _indicator_messages_service_method_info_unregister_application = +{ + { + -1, + (gchar *) "UnregisterApplication", + (GDBusArgInfo **) &_indicator_messages_service_method_info_unregister_application_IN_ARG_pointers, + NULL, + NULL + }, + "handle-unregister-application", + FALSE +}; + +static const _ExtendedGDBusArgInfo _indicator_messages_service_method_info_set_status_IN_ARG_status = +{ + { + -1, + (gchar *) "status", + (gchar *) "s", + NULL + }, + FALSE +}; + +static const _ExtendedGDBusArgInfo * const _indicator_messages_service_method_info_set_status_IN_ARG_pointers[] = +{ + &_indicator_messages_service_method_info_set_status_IN_ARG_status, + NULL +}; + +static const _ExtendedGDBusMethodInfo _indicator_messages_service_method_info_set_status = +{ + { + -1, + (gchar *) "SetStatus", + (GDBusArgInfo **) &_indicator_messages_service_method_info_set_status_IN_ARG_pointers, + NULL, + NULL + }, + "handle-set-status", + FALSE +}; + +static const _ExtendedGDBusMethodInfo * const _indicator_messages_service_method_info_pointers[] = +{ + &_indicator_messages_service_method_info_register_application, + &_indicator_messages_service_method_info_unregister_application, + &_indicator_messages_service_method_info_set_status, + NULL +}; + +static const _ExtendedGDBusArgInfo _indicator_messages_service_signal_info_status_changed_ARG_status = +{ + { + -1, + (gchar *) "status", + (gchar *) "s", + NULL + }, + FALSE +}; + +static const _ExtendedGDBusArgInfo * const _indicator_messages_service_signal_info_status_changed_ARG_pointers[] = +{ + &_indicator_messages_service_signal_info_status_changed_ARG_status, + NULL +}; + +static const _ExtendedGDBusSignalInfo _indicator_messages_service_signal_info_status_changed = +{ + { + -1, + (gchar *) "StatusChanged", + (GDBusArgInfo **) &_indicator_messages_service_signal_info_status_changed_ARG_pointers, + NULL + }, + "status-changed" +}; + +static const _ExtendedGDBusSignalInfo * const _indicator_messages_service_signal_info_pointers[] = +{ + &_indicator_messages_service_signal_info_status_changed, + NULL +}; + +static const _ExtendedGDBusInterfaceInfo _indicator_messages_service_interface_info = +{ + { + -1, + (gchar *) "com.canonical.indicator.messages.service", + (GDBusMethodInfo **) &_indicator_messages_service_method_info_pointers, + (GDBusSignalInfo **) &_indicator_messages_service_signal_info_pointers, + NULL, + NULL + }, + "service", +}; + + +/** + * indicator_messages_service_interface_info: + * + * Gets a machine-readable description of the <link linkend="gdbus-interface-com-canonical-indicator-messages-service.top_of_page">com.canonical.indicator.messages.service</link> D-Bus interface. + * + * Returns: (transfer none): A #GDBusInterfaceInfo. Do not free. + */ +GDBusInterfaceInfo * +indicator_messages_service_interface_info (void) +{ + return (GDBusInterfaceInfo *) &_indicator_messages_service_interface_info.parent_struct; +} + +/** + * indicator_messages_service_override_properties: + * @klass: The class structure for a #GObject<!-- -->-derived class. + * @property_id_begin: The property id to assign to the first overridden property. + * + * Overrides all #GObject properties in the #IndicatorMessagesService interface for a concrete class. + * The properties are overridden in the order they are defined. + * + * Returns: The last property id. + */ +guint +indicator_messages_service_override_properties (GObjectClass *klass, guint property_id_begin) +{ + return property_id_begin - 1; +} + + + +/** + * IndicatorMessagesService: + * + * Abstract interface type for the D-Bus interface <link linkend="gdbus-interface-com-canonical-indicator-messages-service.top_of_page">com.canonical.indicator.messages.service</link>. + */ + +/** + * IndicatorMessagesServiceIface: + * @parent_iface: The parent interface. + * @handle_register_application: Handler for the #IndicatorMessagesService::handle-register-application signal. + * @handle_set_status: Handler for the #IndicatorMessagesService::handle-set-status signal. + * @handle_unregister_application: Handler for the #IndicatorMessagesService::handle-unregister-application signal. + * @status_changed: Handler for the #IndicatorMessagesService::status-changed signal. + * + * Virtual table for the D-Bus interface <link linkend="gdbus-interface-com-canonical-indicator-messages-service.top_of_page">com.canonical.indicator.messages.service</link>. + */ + +static void +indicator_messages_service_default_init (IndicatorMessagesServiceIface *iface) +{ + /* GObject signals for incoming D-Bus method calls: */ + /** + * IndicatorMessagesService::handle-register-application: + * @object: A #IndicatorMessagesService. + * @invocation: A #GDBusMethodInvocation. + * @arg_desktop_id: Argument passed by remote caller. + * @arg_menu_path: Argument passed by remote caller. + * + * Signal emitted when a remote caller is invoking the <link linkend="gdbus-method-com-canonical-indicator-messages-service.RegisterApplication">RegisterApplication()</link> D-Bus method. + * + * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call indicator_messages_service_complete_register_application() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %TRUE if the invocation was handled, %FALSE to let other signal handlers run. + */ + g_signal_new ("handle-register-application", + G_TYPE_FROM_INTERFACE (iface), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IndicatorMessagesServiceIface, handle_register_application), + g_signal_accumulator_true_handled, + NULL, + g_cclosure_marshal_generic, + G_TYPE_BOOLEAN, + 3, + G_TYPE_DBUS_METHOD_INVOCATION, G_TYPE_STRING, G_TYPE_STRING); + + /** + * IndicatorMessagesService::handle-unregister-application: + * @object: A #IndicatorMessagesService. + * @invocation: A #GDBusMethodInvocation. + * @arg_desktop_id: Argument passed by remote caller. + * + * Signal emitted when a remote caller is invoking the <link linkend="gdbus-method-com-canonical-indicator-messages-service.UnregisterApplication">UnregisterApplication()</link> D-Bus method. + * + * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call indicator_messages_service_complete_unregister_application() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %TRUE if the invocation was handled, %FALSE to let other signal handlers run. + */ + g_signal_new ("handle-unregister-application", + G_TYPE_FROM_INTERFACE (iface), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IndicatorMessagesServiceIface, handle_unregister_application), + g_signal_accumulator_true_handled, + NULL, + g_cclosure_marshal_generic, + G_TYPE_BOOLEAN, + 2, + G_TYPE_DBUS_METHOD_INVOCATION, G_TYPE_STRING); + + /** + * IndicatorMessagesService::handle-set-status: + * @object: A #IndicatorMessagesService. + * @invocation: A #GDBusMethodInvocation. + * @arg_status: Argument passed by remote caller. + * + * Signal emitted when a remote caller is invoking the <link linkend="gdbus-method-com-canonical-indicator-messages-service.SetStatus">SetStatus()</link> D-Bus method. + * + * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call indicator_messages_service_complete_set_status() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %TRUE if the invocation was handled, %FALSE to let other signal handlers run. + */ + g_signal_new ("handle-set-status", + G_TYPE_FROM_INTERFACE (iface), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IndicatorMessagesServiceIface, handle_set_status), + g_signal_accumulator_true_handled, + NULL, + g_cclosure_marshal_generic, + G_TYPE_BOOLEAN, + 2, + G_TYPE_DBUS_METHOD_INVOCATION, G_TYPE_STRING); + + /* GObject signals for received D-Bus signals: */ + /** + * IndicatorMessagesService::status-changed: + * @object: A #IndicatorMessagesService. + * @arg_status: Argument. + * + * On the client-side, this signal is emitted whenever the D-Bus signal <link linkend="gdbus-signal-com-canonical-indicator-messages-service.StatusChanged">"StatusChanged"</link> is received. + * + * On the service-side, this signal can be used with e.g. g_signal_emit_by_name() to make the object emit the D-Bus signal. + */ + g_signal_new ("status-changed", + G_TYPE_FROM_INTERFACE (iface), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IndicatorMessagesServiceIface, status_changed), + NULL, + NULL, + g_cclosure_marshal_generic, + G_TYPE_NONE, + 1, G_TYPE_STRING); + +} + +typedef IndicatorMessagesServiceIface IndicatorMessagesServiceInterface; +G_DEFINE_INTERFACE (IndicatorMessagesService, indicator_messages_service, G_TYPE_OBJECT); + +/** + * indicator_messages_service_emit_status_changed: + * @object: A #IndicatorMessagesService. + * @arg_status: Argument to pass with the signal. + * + * Emits the <link linkend="gdbus-signal-com-canonical-indicator-messages-service.StatusChanged">"StatusChanged"</link> D-Bus signal. + */ +void +indicator_messages_service_emit_status_changed ( + IndicatorMessagesService *object, + const gchar *arg_status) +{ + g_signal_emit_by_name (object, "status-changed", arg_status); +} + +/** + * indicator_messages_service_call_register_application: + * @proxy: A #IndicatorMessagesServiceProxy. + * @arg_desktop_id: Argument to pass with the method invocation. + * @arg_menu_path: Argument to pass with the method invocation. + * @cancellable: (allow-none): A #GCancellable or %NULL. + * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL. + * @user_data: User data to pass to @callback. + * + * Asynchronously invokes the <link linkend="gdbus-method-com-canonical-indicator-messages-service.RegisterApplication">RegisterApplication()</link> D-Bus method on @proxy. + * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from. + * You can then call indicator_messages_service_call_register_application_finish() to get the result of the operation. + * + * See indicator_messages_service_call_register_application_sync() for the synchronous, blocking version of this method. + */ +void +indicator_messages_service_call_register_application ( + IndicatorMessagesService *proxy, + const gchar *arg_desktop_id, + const gchar *arg_menu_path, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_dbus_proxy_call (G_DBUS_PROXY (proxy), + "RegisterApplication", + g_variant_new ("(so)", + arg_desktop_id, + arg_menu_path), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + callback, + user_data); +} + +/** + * indicator_messages_service_call_register_application_finish: + * @proxy: A #IndicatorMessagesServiceProxy. + * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to indicator_messages_service_call_register_application(). + * @error: Return location for error or %NULL. + * + * Finishes an operation started with indicator_messages_service_call_register_application(). + * + * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set. + */ +gboolean +indicator_messages_service_call_register_application_finish ( + IndicatorMessagesService *proxy, + GAsyncResult *res, + GError **error) +{ + GVariant *_ret; + _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error); + if (_ret == NULL) + goto _out; + g_variant_get (_ret, + "()"); + g_variant_unref (_ret); +_out: + return _ret != NULL; +} + +/** + * indicator_messages_service_call_register_application_sync: + * @proxy: A #IndicatorMessagesServiceProxy. + * @arg_desktop_id: Argument to pass with the method invocation. + * @arg_menu_path: Argument to pass with the method invocation. + * @cancellable: (allow-none): A #GCancellable or %NULL. + * @error: Return location for error or %NULL. + * + * Synchronously invokes the <link linkend="gdbus-method-com-canonical-indicator-messages-service.RegisterApplication">RegisterApplication()</link> D-Bus method on @proxy. The calling thread is blocked until a reply is received. + * + * See indicator_messages_service_call_register_application() for the asynchronous version of this method. + * + * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set. + */ +gboolean +indicator_messages_service_call_register_application_sync ( + IndicatorMessagesService *proxy, + const gchar *arg_desktop_id, + const gchar *arg_menu_path, + GCancellable *cancellable, + GError **error) +{ + GVariant *_ret; + _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy), + "RegisterApplication", + g_variant_new ("(so)", + arg_desktop_id, + arg_menu_path), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + error); + if (_ret == NULL) + goto _out; + g_variant_get (_ret, + "()"); + g_variant_unref (_ret); +_out: + return _ret != NULL; +} + +/** + * indicator_messages_service_call_unregister_application: + * @proxy: A #IndicatorMessagesServiceProxy. + * @arg_desktop_id: Argument to pass with the method invocation. + * @cancellable: (allow-none): A #GCancellable or %NULL. + * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL. + * @user_data: User data to pass to @callback. + * + * Asynchronously invokes the <link linkend="gdbus-method-com-canonical-indicator-messages-service.UnregisterApplication">UnregisterApplication()</link> D-Bus method on @proxy. + * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from. + * You can then call indicator_messages_service_call_unregister_application_finish() to get the result of the operation. + * + * See indicator_messages_service_call_unregister_application_sync() for the synchronous, blocking version of this method. + */ +void +indicator_messages_service_call_unregister_application ( + IndicatorMessagesService *proxy, + const gchar *arg_desktop_id, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_dbus_proxy_call (G_DBUS_PROXY (proxy), + "UnregisterApplication", + g_variant_new ("(s)", + arg_desktop_id), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + callback, + user_data); +} + +/** + * indicator_messages_service_call_unregister_application_finish: + * @proxy: A #IndicatorMessagesServiceProxy. + * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to indicator_messages_service_call_unregister_application(). + * @error: Return location for error or %NULL. + * + * Finishes an operation started with indicator_messages_service_call_unregister_application(). + * + * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set. + */ +gboolean +indicator_messages_service_call_unregister_application_finish ( + IndicatorMessagesService *proxy, + GAsyncResult *res, + GError **error) +{ + GVariant *_ret; + _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error); + if (_ret == NULL) + goto _out; + g_variant_get (_ret, + "()"); + g_variant_unref (_ret); +_out: + return _ret != NULL; +} + +/** + * indicator_messages_service_call_unregister_application_sync: + * @proxy: A #IndicatorMessagesServiceProxy. + * @arg_desktop_id: Argument to pass with the method invocation. + * @cancellable: (allow-none): A #GCancellable or %NULL. + * @error: Return location for error or %NULL. + * + * Synchronously invokes the <link linkend="gdbus-method-com-canonical-indicator-messages-service.UnregisterApplication">UnregisterApplication()</link> D-Bus method on @proxy. The calling thread is blocked until a reply is received. + * + * See indicator_messages_service_call_unregister_application() for the asynchronous version of this method. + * + * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set. + */ +gboolean +indicator_messages_service_call_unregister_application_sync ( + IndicatorMessagesService *proxy, + const gchar *arg_desktop_id, + GCancellable *cancellable, + GError **error) +{ + GVariant *_ret; + _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy), + "UnregisterApplication", + g_variant_new ("(s)", + arg_desktop_id), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + error); + if (_ret == NULL) + goto _out; + g_variant_get (_ret, + "()"); + g_variant_unref (_ret); +_out: + return _ret != NULL; +} + +/** + * indicator_messages_service_call_set_status: + * @proxy: A #IndicatorMessagesServiceProxy. + * @arg_status: Argument to pass with the method invocation. + * @cancellable: (allow-none): A #GCancellable or %NULL. + * @callback: A #GAsyncReadyCallback to call when the request is satisfied or %NULL. + * @user_data: User data to pass to @callback. + * + * Asynchronously invokes the <link linkend="gdbus-method-com-canonical-indicator-messages-service.SetStatus">SetStatus()</link> D-Bus method on @proxy. + * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from. + * You can then call indicator_messages_service_call_set_status_finish() to get the result of the operation. + * + * See indicator_messages_service_call_set_status_sync() for the synchronous, blocking version of this method. + */ +void +indicator_messages_service_call_set_status ( + IndicatorMessagesService *proxy, + const gchar *arg_status, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_dbus_proxy_call (G_DBUS_PROXY (proxy), + "SetStatus", + g_variant_new ("(s)", + arg_status), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + callback, + user_data); +} + +/** + * indicator_messages_service_call_set_status_finish: + * @proxy: A #IndicatorMessagesServiceProxy. + * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to indicator_messages_service_call_set_status(). + * @error: Return location for error or %NULL. + * + * Finishes an operation started with indicator_messages_service_call_set_status(). + * + * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set. + */ +gboolean +indicator_messages_service_call_set_status_finish ( + IndicatorMessagesService *proxy, + GAsyncResult *res, + GError **error) +{ + GVariant *_ret; + _ret = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error); + if (_ret == NULL) + goto _out; + g_variant_get (_ret, + "()"); + g_variant_unref (_ret); +_out: + return _ret != NULL; +} + +/** + * indicator_messages_service_call_set_status_sync: + * @proxy: A #IndicatorMessagesServiceProxy. + * @arg_status: Argument to pass with the method invocation. + * @cancellable: (allow-none): A #GCancellable or %NULL. + * @error: Return location for error or %NULL. + * + * Synchronously invokes the <link linkend="gdbus-method-com-canonical-indicator-messages-service.SetStatus">SetStatus()</link> D-Bus method on @proxy. The calling thread is blocked until a reply is received. + * + * See indicator_messages_service_call_set_status() for the asynchronous version of this method. + * + * Returns: (skip): %TRUE if the call succeded, %FALSE if @error is set. + */ +gboolean +indicator_messages_service_call_set_status_sync ( + IndicatorMessagesService *proxy, + const gchar *arg_status, + GCancellable *cancellable, + GError **error) +{ + GVariant *_ret; + _ret = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy), + "SetStatus", + g_variant_new ("(s)", + arg_status), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + error); + if (_ret == NULL) + goto _out; + g_variant_get (_ret, + "()"); + g_variant_unref (_ret); +_out: + return _ret != NULL; +} + +/** + * indicator_messages_service_complete_register_application: + * @object: A #IndicatorMessagesService. + * @invocation: (transfer full): A #GDBusMethodInvocation. + * + * Helper function used in service implementations to finish handling invocations of the <link linkend="gdbus-method-com-canonical-indicator-messages-service.RegisterApplication">RegisterApplication()</link> D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar. + * + * This method will free @invocation, you cannot use it afterwards. + */ +void +indicator_messages_service_complete_register_application ( + IndicatorMessagesService *object, + GDBusMethodInvocation *invocation) +{ + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("()")); +} + +/** + * indicator_messages_service_complete_unregister_application: + * @object: A #IndicatorMessagesService. + * @invocation: (transfer full): A #GDBusMethodInvocation. + * + * Helper function used in service implementations to finish handling invocations of the <link linkend="gdbus-method-com-canonical-indicator-messages-service.UnregisterApplication">UnregisterApplication()</link> D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar. + * + * This method will free @invocation, you cannot use it afterwards. + */ +void +indicator_messages_service_complete_unregister_application ( + IndicatorMessagesService *object, + GDBusMethodInvocation *invocation) +{ + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("()")); +} + +/** + * indicator_messages_service_complete_set_status: + * @object: A #IndicatorMessagesService. + * @invocation: (transfer full): A #GDBusMethodInvocation. + * + * Helper function used in service implementations to finish handling invocations of the <link linkend="gdbus-method-com-canonical-indicator-messages-service.SetStatus">SetStatus()</link> D-Bus method. If you instead want to finish handling an invocation by returning an error, use g_dbus_method_invocation_return_error() or similar. + * + * This method will free @invocation, you cannot use it afterwards. + */ +void +indicator_messages_service_complete_set_status ( + IndicatorMessagesService *object, + GDBusMethodInvocation *invocation) +{ + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("()")); +} + +/* ------------------------------------------------------------------------ */ + +/** + * IndicatorMessagesServiceProxy: + * + * The #IndicatorMessagesServiceProxy structure contains only private data and should only be accessed using the provided API. + */ + +/** + * IndicatorMessagesServiceProxyClass: + * @parent_class: The parent class. + * + * Class structure for #IndicatorMessagesServiceProxy. + */ + +struct _IndicatorMessagesServiceProxyPrivate +{ + GData *qdata; +}; + +static void indicator_messages_service_proxy_iface_init (IndicatorMessagesServiceIface *iface); + +G_DEFINE_TYPE_WITH_CODE (IndicatorMessagesServiceProxy, indicator_messages_service_proxy, G_TYPE_DBUS_PROXY, + G_IMPLEMENT_INTERFACE (INDICATOR_MESSAGES_TYPE_SERVICE, indicator_messages_service_proxy_iface_init)); + +static void +indicator_messages_service_proxy_finalize (GObject *object) +{ + IndicatorMessagesServiceProxy *proxy = INDICATOR_MESSAGES_SERVICE_PROXY (object); + g_datalist_clear (&proxy->priv->qdata); + G_OBJECT_CLASS (indicator_messages_service_proxy_parent_class)->finalize (object); +} + +static void +indicator_messages_service_proxy_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ +} + +static void +indicator_messages_service_proxy_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ +} + +static void +indicator_messages_service_proxy_g_signal (GDBusProxy *proxy, + const gchar *sender_name, + const gchar *signal_name, + GVariant *parameters) +{ + _ExtendedGDBusSignalInfo *info; + GVariantIter iter; + GVariant *child; + GValue *paramv; + guint num_params; + guint n; + guint signal_id; + info = (_ExtendedGDBusSignalInfo *) g_dbus_interface_info_lookup_signal ((GDBusInterfaceInfo *) &_indicator_messages_service_interface_info.parent_struct, signal_name); + if (info == NULL) + return; + num_params = g_variant_n_children (parameters); + paramv = g_new0 (GValue, num_params + 1); + g_value_init (¶mv[0], INDICATOR_MESSAGES_TYPE_SERVICE); + g_value_set_object (¶mv[0], proxy); + g_variant_iter_init (&iter, parameters); + n = 1; + while ((child = g_variant_iter_next_value (&iter)) != NULL) + { + _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.args[n - 1]; + if (arg_info->use_gvariant) + { + g_value_init (¶mv[n], G_TYPE_VARIANT); + g_value_set_variant (¶mv[n], child); + n++; + } + else + g_dbus_gvariant_to_gvalue (child, ¶mv[n++]); + g_variant_unref (child); + } + signal_id = g_signal_lookup (info->signal_name, INDICATOR_MESSAGES_TYPE_SERVICE); + g_signal_emitv (paramv, signal_id, 0, NULL); + for (n = 0; n < num_params + 1; n++) + g_value_unset (¶mv[n]); + g_free (paramv); +} + +static void +indicator_messages_service_proxy_g_properties_changed (GDBusProxy *_proxy, + GVariant *changed_properties, + const gchar *const *invalidated_properties) +{ + IndicatorMessagesServiceProxy *proxy = INDICATOR_MESSAGES_SERVICE_PROXY (_proxy); + guint n; + const gchar *key; + GVariantIter *iter; + _ExtendedGDBusPropertyInfo *info; + g_variant_get (changed_properties, "a{sv}", &iter); + while (g_variant_iter_next (iter, "{&sv}", &key, NULL)) + { + info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_indicator_messages_service_interface_info.parent_struct, key); + g_datalist_remove_data (&proxy->priv->qdata, key); + if (info != NULL) + g_object_notify (G_OBJECT (proxy), info->hyphen_name); + } + g_variant_iter_free (iter); + for (n = 0; invalidated_properties[n] != NULL; n++) + { + info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_indicator_messages_service_interface_info.parent_struct, invalidated_properties[n]); + g_datalist_remove_data (&proxy->priv->qdata, invalidated_properties[n]); + if (info != NULL) + g_object_notify (G_OBJECT (proxy), info->hyphen_name); + } +} + +static void +indicator_messages_service_proxy_init (IndicatorMessagesServiceProxy *proxy) +{ + proxy->priv = G_TYPE_INSTANCE_GET_PRIVATE (proxy, INDICATOR_MESSAGES_TYPE_SERVICE_PROXY, IndicatorMessagesServiceProxyPrivate); + g_dbus_proxy_set_interface_info (G_DBUS_PROXY (proxy), indicator_messages_service_interface_info ()); +} + +static void +indicator_messages_service_proxy_class_init (IndicatorMessagesServiceProxyClass *klass) +{ + GObjectClass *gobject_class; + GDBusProxyClass *proxy_class; + + g_type_class_add_private (klass, sizeof (IndicatorMessagesServiceProxyPrivate)); + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = indicator_messages_service_proxy_finalize; + gobject_class->get_property = indicator_messages_service_proxy_get_property; + gobject_class->set_property = indicator_messages_service_proxy_set_property; + + proxy_class = G_DBUS_PROXY_CLASS (klass); + proxy_class->g_signal = indicator_messages_service_proxy_g_signal; + proxy_class->g_properties_changed = indicator_messages_service_proxy_g_properties_changed; + +} + +static void +indicator_messages_service_proxy_iface_init (IndicatorMessagesServiceIface *iface) +{ +} + +/** + * indicator_messages_service_proxy_new: + * @connection: A #GDBusConnection. + * @flags: Flags from the #GDBusProxyFlags enumeration. + * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection. + * @object_path: An object path. + * @cancellable: (allow-none): A #GCancellable or %NULL. + * @callback: A #GAsyncReadyCallback to call when the request is satisfied. + * @user_data: User data to pass to @callback. + * + * Asynchronously creates a proxy for the D-Bus interface <link linkend="gdbus-interface-com-canonical-indicator-messages-service.top_of_page">com.canonical.indicator.messages.service</link>. See g_dbus_proxy_new() for more details. + * + * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from. + * You can then call indicator_messages_service_proxy_new_finish() to get the result of the operation. + * + * See indicator_messages_service_proxy_new_sync() for the synchronous, blocking version of this constructor. + */ +void +indicator_messages_service_proxy_new ( + GDBusConnection *connection, + GDBusProxyFlags flags, + const gchar *name, + const gchar *object_path, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_async_initable_new_async (INDICATOR_MESSAGES_TYPE_SERVICE_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "com.canonical.indicator.messages.service", NULL); +} + +/** + * indicator_messages_service_proxy_new_finish: + * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to indicator_messages_service_proxy_new(). + * @error: Return location for error or %NULL + * + * Finishes an operation started with indicator_messages_service_proxy_new(). + * + * Returns: (transfer full) (type IndicatorMessagesServiceProxy): The constructed proxy object or %NULL if @error is set. + */ +IndicatorMessagesService * +indicator_messages_service_proxy_new_finish ( + GAsyncResult *res, + GError **error) +{ + GObject *ret; + GObject *source_object; + source_object = g_async_result_get_source_object (res); + ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error); + g_object_unref (source_object); + if (ret != NULL) + return INDICATOR_MESSAGES_SERVICE (ret); + else + return NULL; +} + +/** + * indicator_messages_service_proxy_new_sync: + * @connection: A #GDBusConnection. + * @flags: Flags from the #GDBusProxyFlags enumeration. + * @name: (allow-none): A bus name (well-known or unique) or %NULL if @connection is not a message bus connection. + * @object_path: An object path. + * @cancellable: (allow-none): A #GCancellable or %NULL. + * @error: Return location for error or %NULL + * + * Synchronously creates a proxy for the D-Bus interface <link linkend="gdbus-interface-com-canonical-indicator-messages-service.top_of_page">com.canonical.indicator.messages.service</link>. See g_dbus_proxy_new_sync() for more details. + * + * The calling thread is blocked until a reply is received. + * + * See indicator_messages_service_proxy_new() for the asynchronous version of this constructor. + * + * Returns: (transfer full) (type IndicatorMessagesServiceProxy): The constructed proxy object or %NULL if @error is set. + */ +IndicatorMessagesService * +indicator_messages_service_proxy_new_sync ( + GDBusConnection *connection, + GDBusProxyFlags flags, + const gchar *name, + const gchar *object_path, + GCancellable *cancellable, + GError **error) +{ + GInitable *ret; + ret = g_initable_new (INDICATOR_MESSAGES_TYPE_SERVICE_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-connection", connection, "g-object-path", object_path, "g-interface-name", "com.canonical.indicator.messages.service", NULL); + if (ret != NULL) + return INDICATOR_MESSAGES_SERVICE (ret); + else + return NULL; +} + + +/** + * indicator_messages_service_proxy_new_for_bus: + * @bus_type: A #GBusType. + * @flags: Flags from the #GDBusProxyFlags enumeration. + * @name: A bus name (well-known or unique). + * @object_path: An object path. + * @cancellable: (allow-none): A #GCancellable or %NULL. + * @callback: A #GAsyncReadyCallback to call when the request is satisfied. + * @user_data: User data to pass to @callback. + * + * Like indicator_messages_service_proxy_new() but takes a #GBusType instead of a #GDBusConnection. + * + * When the operation is finished, @callback will be invoked in the <link linkend="g-main-context-push-thread-default">thread-default main loop</link> of the thread you are calling this method from. + * You can then call indicator_messages_service_proxy_new_for_bus_finish() to get the result of the operation. + * + * See indicator_messages_service_proxy_new_for_bus_sync() for the synchronous, blocking version of this constructor. + */ +void +indicator_messages_service_proxy_new_for_bus ( + GBusType bus_type, + GDBusProxyFlags flags, + const gchar *name, + const gchar *object_path, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_async_initable_new_async (INDICATOR_MESSAGES_TYPE_SERVICE_PROXY, G_PRIORITY_DEFAULT, cancellable, callback, user_data, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "com.canonical.indicator.messages.service", NULL); +} + +/** + * indicator_messages_service_proxy_new_for_bus_finish: + * @res: The #GAsyncResult obtained from the #GAsyncReadyCallback passed to indicator_messages_service_proxy_new_for_bus(). + * @error: Return location for error or %NULL + * + * Finishes an operation started with indicator_messages_service_proxy_new_for_bus(). + * + * Returns: (transfer full) (type IndicatorMessagesServiceProxy): The constructed proxy object or %NULL if @error is set. + */ +IndicatorMessagesService * +indicator_messages_service_proxy_new_for_bus_finish ( + GAsyncResult *res, + GError **error) +{ + GObject *ret; + GObject *source_object; + source_object = g_async_result_get_source_object (res); + ret = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, error); + g_object_unref (source_object); + if (ret != NULL) + return INDICATOR_MESSAGES_SERVICE (ret); + else + return NULL; +} + +/** + * indicator_messages_service_proxy_new_for_bus_sync: + * @bus_type: A #GBusType. + * @flags: Flags from the #GDBusProxyFlags enumeration. + * @name: A bus name (well-known or unique). + * @object_path: An object path. + * @cancellable: (allow-none): A #GCancellable or %NULL. + * @error: Return location for error or %NULL + * + * Like indicator_messages_service_proxy_new_sync() but takes a #GBusType instead of a #GDBusConnection. + * + * The calling thread is blocked until a reply is received. + * + * See indicator_messages_service_proxy_new_for_bus() for the asynchronous version of this constructor. + * + * Returns: (transfer full) (type IndicatorMessagesServiceProxy): The constructed proxy object or %NULL if @error is set. + */ +IndicatorMessagesService * +indicator_messages_service_proxy_new_for_bus_sync ( + GBusType bus_type, + GDBusProxyFlags flags, + const gchar *name, + const gchar *object_path, + GCancellable *cancellable, + GError **error) +{ + GInitable *ret; + ret = g_initable_new (INDICATOR_MESSAGES_TYPE_SERVICE_PROXY, cancellable, error, "g-flags", flags, "g-name", name, "g-bus-type", bus_type, "g-object-path", object_path, "g-interface-name", "com.canonical.indicator.messages.service", NULL); + if (ret != NULL) + return INDICATOR_MESSAGES_SERVICE (ret); + else + return NULL; +} + + +/* ------------------------------------------------------------------------ */ + +/** + * IndicatorMessagesServiceSkeleton: + * + * The #IndicatorMessagesServiceSkeleton structure contains only private data and should only be accessed using the provided API. + */ + +/** + * IndicatorMessagesServiceSkeletonClass: + * @parent_class: The parent class. + * + * Class structure for #IndicatorMessagesServiceSkeleton. + */ + +struct _IndicatorMessagesServiceSkeletonPrivate +{ + GValue *properties; + GList *changed_properties; + GSource *changed_properties_idle_source; + GMainContext *context; + GMutex lock; +}; + +static void +_indicator_messages_service_skeleton_handle_method_call ( + GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + IndicatorMessagesServiceSkeleton *skeleton = INDICATOR_MESSAGES_SERVICE_SKELETON (user_data); + _ExtendedGDBusMethodInfo *info; + GVariantIter iter; + GVariant *child; + GValue *paramv; + guint num_params; + guint num_extra; + guint n; + guint signal_id; + GValue return_value = G_VALUE_INIT; + info = (_ExtendedGDBusMethodInfo *) g_dbus_method_invocation_get_method_info (invocation); + g_assert (info != NULL); + num_params = g_variant_n_children (parameters); + num_extra = info->pass_fdlist ? 3 : 2; paramv = g_new0 (GValue, num_params + num_extra); + n = 0; + g_value_init (¶mv[n], INDICATOR_MESSAGES_TYPE_SERVICE); + g_value_set_object (¶mv[n++], skeleton); + g_value_init (¶mv[n], G_TYPE_DBUS_METHOD_INVOCATION); + g_value_set_object (¶mv[n++], invocation); + if (info->pass_fdlist) + { +#ifdef G_OS_UNIX + g_value_init (¶mv[n], G_TYPE_UNIX_FD_LIST); + g_value_set_object (¶mv[n++], g_dbus_message_get_unix_fd_list (g_dbus_method_invocation_get_message (invocation))); +#else + g_assert_not_reached (); +#endif + } + g_variant_iter_init (&iter, parameters); + while ((child = g_variant_iter_next_value (&iter)) != NULL) + { + _ExtendedGDBusArgInfo *arg_info = (_ExtendedGDBusArgInfo *) info->parent_struct.in_args[n - num_extra]; + if (arg_info->use_gvariant) + { + g_value_init (¶mv[n], G_TYPE_VARIANT); + g_value_set_variant (¶mv[n], child); + n++; + } + else + g_dbus_gvariant_to_gvalue (child, ¶mv[n++]); + g_variant_unref (child); + } + signal_id = g_signal_lookup (info->signal_name, INDICATOR_MESSAGES_TYPE_SERVICE); + g_value_init (&return_value, G_TYPE_BOOLEAN); + g_signal_emitv (paramv, signal_id, 0, &return_value); + if (!g_value_get_boolean (&return_value)) + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD, "Method %s is not implemented on interface %s", method_name, interface_name); + g_value_unset (&return_value); + for (n = 0; n < num_params + num_extra; n++) + g_value_unset (¶mv[n]); + g_free (paramv); +} + +static GVariant * +_indicator_messages_service_skeleton_handle_get_property ( + GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GError **error, + gpointer user_data) +{ + IndicatorMessagesServiceSkeleton *skeleton = INDICATOR_MESSAGES_SERVICE_SKELETON (user_data); + GValue value = G_VALUE_INIT; + GParamSpec *pspec; + _ExtendedGDBusPropertyInfo *info; + GVariant *ret; + ret = NULL; + info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_indicator_messages_service_interface_info.parent_struct, property_name); + g_assert (info != NULL); + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name); + if (pspec == NULL) + { + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %s", property_name); + } + else + { + g_value_init (&value, pspec->value_type); + g_object_get_property (G_OBJECT (skeleton), info->hyphen_name, &value); + ret = g_dbus_gvalue_to_gvariant (&value, G_VARIANT_TYPE (info->parent_struct.signature)); + g_value_unset (&value); + } + return ret; +} + +static gboolean +_indicator_messages_service_skeleton_handle_set_property ( + GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GVariant *variant, + GError **error, + gpointer user_data) +{ + IndicatorMessagesServiceSkeleton *skeleton = INDICATOR_MESSAGES_SERVICE_SKELETON (user_data); + GValue value = G_VALUE_INIT; + GParamSpec *pspec; + _ExtendedGDBusPropertyInfo *info; + gboolean ret; + ret = FALSE; + info = (_ExtendedGDBusPropertyInfo *) g_dbus_interface_info_lookup_property ((GDBusInterfaceInfo *) &_indicator_messages_service_interface_info.parent_struct, property_name); + g_assert (info != NULL); + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (skeleton), info->hyphen_name); + if (pspec == NULL) + { + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No property with name %s", property_name); + } + else + { + if (info->use_gvariant) + g_value_set_variant (&value, variant); + else + g_dbus_gvariant_to_gvalue (variant, &value); + g_object_set_property (G_OBJECT (skeleton), info->hyphen_name, &value); + g_value_unset (&value); + ret = TRUE; + } + return ret; +} + +static const GDBusInterfaceVTable _indicator_messages_service_skeleton_vtable = +{ + _indicator_messages_service_skeleton_handle_method_call, + _indicator_messages_service_skeleton_handle_get_property, + _indicator_messages_service_skeleton_handle_set_property +}; + +static GDBusInterfaceInfo * +indicator_messages_service_skeleton_dbus_interface_get_info (GDBusInterfaceSkeleton *skeleton) +{ + return indicator_messages_service_interface_info (); +} + +static GDBusInterfaceVTable * +indicator_messages_service_skeleton_dbus_interface_get_vtable (GDBusInterfaceSkeleton *skeleton) +{ + return (GDBusInterfaceVTable *) &_indicator_messages_service_skeleton_vtable; +} + +static GVariant * +indicator_messages_service_skeleton_dbus_interface_get_properties (GDBusInterfaceSkeleton *_skeleton) +{ + IndicatorMessagesServiceSkeleton *skeleton = INDICATOR_MESSAGES_SERVICE_SKELETON (_skeleton); + + GVariantBuilder builder; + guint n; + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + if (_indicator_messages_service_interface_info.parent_struct.properties == NULL) + goto out; + for (n = 0; _indicator_messages_service_interface_info.parent_struct.properties[n] != NULL; n++) + { + GDBusPropertyInfo *info = _indicator_messages_service_interface_info.parent_struct.properties[n]; + if (info->flags & G_DBUS_PROPERTY_INFO_FLAGS_READABLE) + { + GVariant *value; + value = _indicator_messages_service_skeleton_handle_get_property (g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (skeleton)), NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "com.canonical.indicator.messages.service", info->name, NULL, skeleton); + if (value != NULL) + { + g_variant_take_ref (value); + g_variant_builder_add (&builder, "{sv}", info->name, value); + g_variant_unref (value); + } + } + } +out: + return g_variant_builder_end (&builder); +} + +static void +indicator_messages_service_skeleton_dbus_interface_flush (GDBusInterfaceSkeleton *_skeleton) +{ +} + +static void +_indicator_messages_service_on_signal_status_changed ( + IndicatorMessagesService *object, + const gchar *arg_status) +{ + IndicatorMessagesServiceSkeleton *skeleton = INDICATOR_MESSAGES_SERVICE_SKELETON (object); + + GList *connections, *l; + GVariant *signal_variant; + connections = g_dbus_interface_skeleton_get_connections (G_DBUS_INTERFACE_SKELETON (skeleton)); + + signal_variant = g_variant_ref_sink (g_variant_new ("(s)", + arg_status)); + for (l = connections; l != NULL; l = l->next) + { + GDBusConnection *connection = l->data; + g_dbus_connection_emit_signal (connection, + NULL, g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (skeleton)), "com.canonical.indicator.messages.service", "StatusChanged", + signal_variant, NULL); + } + g_variant_unref (signal_variant); + g_list_free_full (connections, g_object_unref); +} + +static void indicator_messages_service_skeleton_iface_init (IndicatorMessagesServiceIface *iface); +G_DEFINE_TYPE_WITH_CODE (IndicatorMessagesServiceSkeleton, indicator_messages_service_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON, + G_IMPLEMENT_INTERFACE (INDICATOR_MESSAGES_TYPE_SERVICE, indicator_messages_service_skeleton_iface_init)); + +static void +indicator_messages_service_skeleton_finalize (GObject *object) +{ + IndicatorMessagesServiceSkeleton *skeleton = INDICATOR_MESSAGES_SERVICE_SKELETON (object); + g_list_free_full (skeleton->priv->changed_properties, (GDestroyNotify) _changed_property_free); + if (skeleton->priv->changed_properties_idle_source != NULL) + g_source_destroy (skeleton->priv->changed_properties_idle_source); + g_main_context_unref (skeleton->priv->context); + g_mutex_clear (&skeleton->priv->lock); + G_OBJECT_CLASS (indicator_messages_service_skeleton_parent_class)->finalize (object); +} + +static void +indicator_messages_service_skeleton_init (IndicatorMessagesServiceSkeleton *skeleton) +{ + skeleton->priv = G_TYPE_INSTANCE_GET_PRIVATE (skeleton, INDICATOR_MESSAGES_TYPE_SERVICE_SKELETON, IndicatorMessagesServiceSkeletonPrivate); + g_mutex_init (&skeleton->priv->lock); + skeleton->priv->context = g_main_context_ref_thread_default (); +} + +static void +indicator_messages_service_skeleton_class_init (IndicatorMessagesServiceSkeletonClass *klass) +{ + GObjectClass *gobject_class; + GDBusInterfaceSkeletonClass *skeleton_class; + + g_type_class_add_private (klass, sizeof (IndicatorMessagesServiceSkeletonPrivate)); + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = indicator_messages_service_skeleton_finalize; + + skeleton_class = G_DBUS_INTERFACE_SKELETON_CLASS (klass); + skeleton_class->get_info = indicator_messages_service_skeleton_dbus_interface_get_info; + skeleton_class->get_properties = indicator_messages_service_skeleton_dbus_interface_get_properties; + skeleton_class->flush = indicator_messages_service_skeleton_dbus_interface_flush; + skeleton_class->get_vtable = indicator_messages_service_skeleton_dbus_interface_get_vtable; +} + +static void +indicator_messages_service_skeleton_iface_init (IndicatorMessagesServiceIface *iface) +{ + iface->status_changed = _indicator_messages_service_on_signal_status_changed; +} + +/** + * indicator_messages_service_skeleton_new: + * + * Creates a skeleton object for the D-Bus interface <link linkend="gdbus-interface-com-canonical-indicator-messages-service.top_of_page">com.canonical.indicator.messages.service</link>. + * + * Returns: (transfer full) (type IndicatorMessagesServiceSkeleton): The skeleton object. + */ +IndicatorMessagesService * +indicator_messages_service_skeleton_new (void) +{ + return INDICATOR_MESSAGES_SERVICE (g_object_new (INDICATOR_MESSAGES_TYPE_SERVICE_SKELETON, NULL)); +} + diff --git a/src/indicator-messages-service.h b/src/indicator-messages-service.h new file mode 100644 index 0000000..cb399f5 --- /dev/null +++ b/src/indicator-messages-service.h @@ -0,0 +1,239 @@ +/* + * Generated by gdbus-codegen 2.33.8. DO NOT EDIT. + * + * The license of this code is the same as for the source it was derived from. + */ + +#ifndef __INDICATOR_MESSAGES_SERVICE_H__ +#define __INDICATOR_MESSAGES_SERVICE_H__ + +#include <gio/gio.h> + +G_BEGIN_DECLS + + +/* ------------------------------------------------------------------------ */ +/* Declarations for com.canonical.indicator.messages.service */ + +#define INDICATOR_MESSAGES_TYPE_SERVICE (indicator_messages_service_get_type ()) +#define INDICATOR_MESSAGES_SERVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_MESSAGES_TYPE_SERVICE, IndicatorMessagesService)) +#define INDICATOR_MESSAGES_IS_SERVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_MESSAGES_TYPE_SERVICE)) +#define INDICATOR_MESSAGES_SERVICE_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), INDICATOR_MESSAGES_TYPE_SERVICE, IndicatorMessagesServiceIface)) + +struct _IndicatorMessagesService; +typedef struct _IndicatorMessagesService IndicatorMessagesService; +typedef struct _IndicatorMessagesServiceIface IndicatorMessagesServiceIface; + +struct _IndicatorMessagesServiceIface +{ + GTypeInterface parent_iface; + + + gboolean (*handle_register_application) ( + IndicatorMessagesService *object, + GDBusMethodInvocation *invocation, + const gchar *arg_desktop_id, + const gchar *arg_menu_path); + + gboolean (*handle_set_status) ( + IndicatorMessagesService *object, + GDBusMethodInvocation *invocation, + const gchar *arg_status); + + gboolean (*handle_unregister_application) ( + IndicatorMessagesService *object, + GDBusMethodInvocation *invocation, + const gchar *arg_desktop_id); + + void (*status_changed) ( + IndicatorMessagesService *object, + const gchar *arg_status); + +}; + +GType indicator_messages_service_get_type (void) G_GNUC_CONST; + +GDBusInterfaceInfo *indicator_messages_service_interface_info (void); +guint indicator_messages_service_override_properties (GObjectClass *klass, guint property_id_begin); + + +/* D-Bus method call completion functions: */ +void indicator_messages_service_complete_register_application ( + IndicatorMessagesService *object, + GDBusMethodInvocation *invocation); + +void indicator_messages_service_complete_unregister_application ( + IndicatorMessagesService *object, + GDBusMethodInvocation *invocation); + +void indicator_messages_service_complete_set_status ( + IndicatorMessagesService *object, + GDBusMethodInvocation *invocation); + + + +/* D-Bus signal emissions functions: */ +void indicator_messages_service_emit_status_changed ( + IndicatorMessagesService *object, + const gchar *arg_status); + + + +/* D-Bus method calls: */ +void indicator_messages_service_call_register_application ( + IndicatorMessagesService *proxy, + const gchar *arg_desktop_id, + const gchar *arg_menu_path, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +gboolean indicator_messages_service_call_register_application_finish ( + IndicatorMessagesService *proxy, + GAsyncResult *res, + GError **error); + +gboolean indicator_messages_service_call_register_application_sync ( + IndicatorMessagesService *proxy, + const gchar *arg_desktop_id, + const gchar *arg_menu_path, + GCancellable *cancellable, + GError **error); + +void indicator_messages_service_call_unregister_application ( + IndicatorMessagesService *proxy, + const gchar *arg_desktop_id, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +gboolean indicator_messages_service_call_unregister_application_finish ( + IndicatorMessagesService *proxy, + GAsyncResult *res, + GError **error); + +gboolean indicator_messages_service_call_unregister_application_sync ( + IndicatorMessagesService *proxy, + const gchar *arg_desktop_id, + GCancellable *cancellable, + GError **error); + +void indicator_messages_service_call_set_status ( + IndicatorMessagesService *proxy, + const gchar *arg_status, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +gboolean indicator_messages_service_call_set_status_finish ( + IndicatorMessagesService *proxy, + GAsyncResult *res, + GError **error); + +gboolean indicator_messages_service_call_set_status_sync ( + IndicatorMessagesService *proxy, + const gchar *arg_status, + GCancellable *cancellable, + GError **error); + + + +/* ---- */ + +#define INDICATOR_MESSAGES_TYPE_SERVICE_PROXY (indicator_messages_service_proxy_get_type ()) +#define INDICATOR_MESSAGES_SERVICE_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_MESSAGES_TYPE_SERVICE_PROXY, IndicatorMessagesServiceProxy)) +#define INDICATOR_MESSAGES_SERVICE_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), INDICATOR_MESSAGES_TYPE_SERVICE_PROXY, IndicatorMessagesServiceProxyClass)) +#define INDICATOR_MESSAGES_SERVICE_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_MESSAGES_TYPE_SERVICE_PROXY, IndicatorMessagesServiceProxyClass)) +#define INDICATOR_MESSAGES_IS_SERVICE_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_MESSAGES_TYPE_SERVICE_PROXY)) +#define INDICATOR_MESSAGES_IS_SERVICE_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), INDICATOR_MESSAGES_TYPE_SERVICE_PROXY)) + +typedef struct _IndicatorMessagesServiceProxy IndicatorMessagesServiceProxy; +typedef struct _IndicatorMessagesServiceProxyClass IndicatorMessagesServiceProxyClass; +typedef struct _IndicatorMessagesServiceProxyPrivate IndicatorMessagesServiceProxyPrivate; + +struct _IndicatorMessagesServiceProxy +{ + /*< private >*/ + GDBusProxy parent_instance; + IndicatorMessagesServiceProxyPrivate *priv; +}; + +struct _IndicatorMessagesServiceProxyClass +{ + GDBusProxyClass parent_class; +}; + +GType indicator_messages_service_proxy_get_type (void) G_GNUC_CONST; + +void indicator_messages_service_proxy_new ( + GDBusConnection *connection, + GDBusProxyFlags flags, + const gchar *name, + const gchar *object_path, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +IndicatorMessagesService *indicator_messages_service_proxy_new_finish ( + GAsyncResult *res, + GError **error); +IndicatorMessagesService *indicator_messages_service_proxy_new_sync ( + GDBusConnection *connection, + GDBusProxyFlags flags, + const gchar *name, + const gchar *object_path, + GCancellable *cancellable, + GError **error); + +void indicator_messages_service_proxy_new_for_bus ( + GBusType bus_type, + GDBusProxyFlags flags, + const gchar *name, + const gchar *object_path, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +IndicatorMessagesService *indicator_messages_service_proxy_new_for_bus_finish ( + GAsyncResult *res, + GError **error); +IndicatorMessagesService *indicator_messages_service_proxy_new_for_bus_sync ( + GBusType bus_type, + GDBusProxyFlags flags, + const gchar *name, + const gchar *object_path, + GCancellable *cancellable, + GError **error); + + +/* ---- */ + +#define INDICATOR_MESSAGES_TYPE_SERVICE_SKELETON (indicator_messages_service_skeleton_get_type ()) +#define INDICATOR_MESSAGES_SERVICE_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_MESSAGES_TYPE_SERVICE_SKELETON, IndicatorMessagesServiceSkeleton)) +#define INDICATOR_MESSAGES_SERVICE_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), INDICATOR_MESSAGES_TYPE_SERVICE_SKELETON, IndicatorMessagesServiceSkeletonClass)) +#define INDICATOR_MESSAGES_SERVICE_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_MESSAGES_TYPE_SERVICE_SKELETON, IndicatorMessagesServiceSkeletonClass)) +#define INDICATOR_MESSAGES_IS_SERVICE_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_MESSAGES_TYPE_SERVICE_SKELETON)) +#define INDICATOR_MESSAGES_IS_SERVICE_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), INDICATOR_MESSAGES_TYPE_SERVICE_SKELETON)) + +typedef struct _IndicatorMessagesServiceSkeleton IndicatorMessagesServiceSkeleton; +typedef struct _IndicatorMessagesServiceSkeletonClass IndicatorMessagesServiceSkeletonClass; +typedef struct _IndicatorMessagesServiceSkeletonPrivate IndicatorMessagesServiceSkeletonPrivate; + +struct _IndicatorMessagesServiceSkeleton +{ + /*< private >*/ + GDBusInterfaceSkeleton parent_instance; + IndicatorMessagesServiceSkeletonPrivate *priv; +}; + +struct _IndicatorMessagesServiceSkeletonClass +{ + GDBusInterfaceSkeletonClass parent_class; +}; + +GType indicator_messages_service_skeleton_get_type (void) G_GNUC_CONST; + +IndicatorMessagesService *indicator_messages_service_skeleton_new (void); + + +G_END_DECLS + +#endif /* __INDICATOR_MESSAGES_SERVICE_H__ */ diff --git a/src/indicator-messages-status-provider-0.5.pc.in.in b/src/indicator-messages-status-provider-0.5.pc.in.in deleted file mode 100644 index 3fe4cf2..0000000 --- a/src/indicator-messages-status-provider-0.5.pc.in.in +++ /dev/null @@ -1,15 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -bindir=@bindir@ -includedir=@includedir@ - -statusproviderdir=@status_provider_dir@ - -Cflags: -I${includedir}/indicator-messages-status-provider-0.@status_provider_api_version@ -Requires: gobject-2.0 -Libs: -L${libdir} -lindicator-messages-status-provider - -Name: indicator-messages-status-provider -Description: Status providers for the indicator-messages menu. -Version: @VERSION@ diff --git a/src/indicator-messages.c b/src/indicator-messages.c index 748b73b..946da55 100644 --- a/src/indicator-messages.c +++ b/src/indicator-messages.c @@ -2,10 +2,11 @@ An indicator to show information that is in messaging applications that the user is using. -Copyright 2009 Canonical Ltd. +Copyright 2012 Canonical Ltd. Authors: Ted Gould <ted@canonical.com> + Lars Uebernickel <lars.uebernickel@canonical.com> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published @@ -29,16 +30,15 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <glib/gi18n-lib.h> #include <gtk/gtk.h> -#include <libdbusmenu-gtk/menu.h> -#include <libdbusmenu-gtk/menuitem.h> - #include <libindicator/indicator.h> #include <libindicator/indicator-object.h> #include <libindicator/indicator-image-helper.h> #include <libindicator/indicator-service-manager.h> #include "dbus-data.h" -#include "gen-messages-service.xml.h" + +#include "im-app-menu-item.h" +#include "im-source-menu-item.h" #define INDICATOR_MESSAGES_TYPE (indicator_messages_get_type ()) #define INDICATOR_MESSAGES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_MESSAGES_TYPE, IndicatorMessages)) @@ -52,12 +52,16 @@ typedef struct _IndicatorMessagesClass IndicatorMessagesClass; struct _IndicatorMessagesClass { IndicatorObjectClass parent_class; - void (*update_a11y_desc) (IndicatorServiceManager * service, gpointer * user_data); }; struct _IndicatorMessages { IndicatorObject parent; IndicatorServiceManager * service; + GActionGroup *actions; + GMenu *menu_wrapper; + GMenuModel *menu; + GtkWidget *image; + gchar *accessible_desc; }; GType indicator_messages_get_type (void); @@ -66,53 +70,25 @@ GType indicator_messages_get_type (void); INDICATOR_SET_VERSION INDICATOR_SET_TYPE(INDICATOR_MESSAGES_TYPE) -/* Globals */ -static GtkWidget * main_image = NULL; -static GDBusProxy * icon_proxy = NULL; -static GDBusNodeInfo * bus_node_info = NULL; -static GDBusInterfaceInfo * bus_interface_info = NULL; -static const gchar * accessible_desc = NULL; -static IndicatorObject * indicator = NULL; - /* Prototypes */ static void indicator_messages_class_init (IndicatorMessagesClass *klass); static void indicator_messages_init (IndicatorMessages *self); static void indicator_messages_dispose (GObject *object); static void indicator_messages_finalize (GObject *object); -static GtkImage * get_icon (IndicatorObject * io); +static GtkImage * get_image (IndicatorObject * io); static GtkMenu * get_menu (IndicatorObject * io); -static void indicator_messages_middle_click (IndicatorObject * io, - IndicatorObjectEntry * entry, - guint time, gpointer data); static const gchar * get_accessible_desc (IndicatorObject * io); static const gchar * get_name_hint (IndicatorObject * io); -static void connection_change (IndicatorServiceManager * sm, - gboolean connected, - gpointer user_data); +static void update_root_item (IndicatorMessages * self); +static void update_menu (IndicatorMessages *self); +static void menu_items_changed (GMenuModel *menu, + gint position, + gint removed, + gint added, + gpointer user_data); G_DEFINE_TYPE (IndicatorMessages, indicator_messages, INDICATOR_OBJECT_TYPE); -static void -update_a11y_desc (void) -{ - g_return_if_fail(IS_INDICATOR_MESSAGES(indicator)); - - GList *entries = indicator_object_get_entries(indicator); - IndicatorObjectEntry * entry = (IndicatorObjectEntry *)entries->data; - - entry->accessible_desc = get_accessible_desc(indicator); - - g_signal_emit(G_OBJECT(indicator), - INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE_ID, - 0, - entry, - TRUE); - - g_list_free(entries); - - return; -} - /* Initialize the one-timers */ static void indicator_messages_class_init (IndicatorMessagesClass *klass) @@ -124,47 +100,55 @@ indicator_messages_class_init (IndicatorMessagesClass *klass) IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass); - io_class->get_image = get_icon; + io_class->get_image = get_image; io_class->get_menu = get_menu; io_class->get_accessible_desc = get_accessible_desc; io_class->get_name_hint = get_name_hint; - io_class->secondary_activate = indicator_messages_middle_click; - - if (bus_node_info == NULL) { - GError * error = NULL; - - bus_node_info = g_dbus_node_info_new_for_xml(_messages_service, &error); - if (error != NULL) { - g_error("Unable to parse Messaging Menu Interface description: %s", error->message); - g_error_free(error); - } - } - - if (bus_interface_info == NULL) { - bus_interface_info = g_dbus_node_info_lookup_interface(bus_node_info, INDICATOR_MESSAGES_DBUS_SERVICE_INTERFACE); - - if (bus_interface_info == NULL) { - g_error("Unable to find interface '" INDICATOR_MESSAGES_DBUS_SERVICE_INTERFACE "'"); - } - } - - return; } /* Build up our per-instance variables */ static void indicator_messages_init (IndicatorMessages *self) { + GDBusConnection *bus; + GError *error = NULL; + /* Default values */ self->service = NULL; /* Complex stuff */ self->service = indicator_service_manager_new_version(INDICATOR_MESSAGES_DBUS_NAME, 1); - g_signal_connect(self->service, INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, G_CALLBACK(connection_change), self); - indicator = INDICATOR_OBJECT(self); + bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + if (!bus) { + g_warning ("error connecting to the session bus: %s", error->message); + g_error_free (error); + return; + } + + self->actions = G_ACTION_GROUP (g_dbus_action_group_get (bus, + INDICATOR_MESSAGES_DBUS_NAME, + INDICATOR_MESSAGES_DBUS_OBJECT)); - return; + self->menu = G_MENU_MODEL (g_dbus_menu_model_get (bus, + INDICATOR_MESSAGES_DBUS_NAME, + INDICATOR_MESSAGES_DBUS_OBJECT)); + + g_signal_connect (self->menu, "items-changed", G_CALLBACK (menu_items_changed), self); + + self->image = g_object_ref_sink (gtk_image_new ()); + gtk_widget_show (self->image); + update_root_item (self); + + self->menu_wrapper = g_menu_new (); + update_menu (self); + + g_object_unref (bus); + + /* make sure custom menu item types are registered (so that + * gtk_model_new_from_menu can pick them up */ + im_app_menu_item_get_type (); + im_source_menu_item_get_type (); } /* Unref stuff */ @@ -174,10 +158,11 @@ indicator_messages_dispose (GObject *object) IndicatorMessages * self = INDICATOR_MESSAGES(object); g_return_if_fail(self != NULL); - if (self->service != NULL) { - g_object_unref(self->service); - self->service = NULL; - } + g_clear_object (&self->service); + g_clear_object (&self->menu_wrapper); + g_clear_object (&self->actions); + g_clear_object (&self->menu); + g_clear_object (&self->image); G_OBJECT_CLASS (indicator_messages_parent_class)->dispose (object); return; @@ -187,6 +172,9 @@ indicator_messages_dispose (GObject *object) static void indicator_messages_finalize (GObject *object) { + IndicatorMessages *self = INDICATOR_MESSAGES (object); + + g_free (self->accessible_desc); G_OBJECT_CLASS (indicator_messages_parent_class)->finalize (object); return; @@ -196,661 +184,121 @@ indicator_messages_finalize (GObject *object) /* Functions */ -/* Signal off of the proxy */ -static void -proxy_signal (GDBusProxy * proxy, const gchar * sender, const gchar * signal, GVariant * params, gpointer user_data) +static GtkImage * +get_image (IndicatorObject * io) { - gboolean prop = g_variant_get_boolean(g_variant_get_child_value(params, 0)); - - if (g_strcmp0("AttentionChanged", signal) == 0) { - if (prop) { - indicator_image_helper_update(GTK_IMAGE(main_image), "indicator-messages-new"); - accessible_desc = _("New Messages"); - } else { - indicator_image_helper_update(GTK_IMAGE(main_image), "indicator-messages"); - accessible_desc = _("Messages"); - } - } else if (g_strcmp0("IconChanged", signal) == 0) { - if (prop) { - gtk_widget_hide(main_image); - } else { - gtk_widget_show(main_image); - } - } else { - g_warning("Unknown signal %s", signal); - } - - update_a11y_desc(); + IndicatorMessages *self = INDICATOR_MESSAGES (io); - return; + return GTK_IMAGE (self->image); } -/* Callback from getting the attention status from the service. */ -static void -attention_cb (GObject * object, GAsyncResult * ares, gpointer user_data) +static GtkMenu * +get_menu (IndicatorObject * io) { - GError * error = NULL; - GVariant * res = g_dbus_proxy_call_finish(G_DBUS_PROXY(object), ares, &error); - - if (error != NULL) { - g_warning("Unable to get attention status: %s", error->message); - g_error_free(error); - return; - } - - gboolean prop = g_variant_get_boolean(g_variant_get_child_value(res, 0)); + IndicatorMessages *self = INDICATOR_MESSAGES (io); + GtkWidget *menu; - if (prop) { - indicator_image_helper_update(GTK_IMAGE(main_image), "indicator-messages-new"); - accessible_desc = _("New Messages"); - } else { - indicator_image_helper_update(GTK_IMAGE(main_image), "indicator-messages"); - accessible_desc = _("Messages"); - } - - update_a11y_desc(); + menu = gtk_menu_new_from_model (G_MENU_MODEL (self->menu_wrapper)); + gtk_widget_insert_action_group (menu, get_name_hint (io), self->actions); - return; + return GTK_MENU (menu); } -/* Change from getting the icon visibility from the service */ -static void -icon_cb (GObject * object, GAsyncResult * ares, gpointer user_data) +static const gchar * +get_accessible_desc (IndicatorObject * io) { - GError * error = NULL; - GVariant * res = g_dbus_proxy_call_finish(G_DBUS_PROXY(object), ares, &error); - - if (error != NULL) { - g_warning("Unable to get icon visibility: %s", error->message); - g_error_free(error); - return; - } - - gboolean prop = g_variant_get_boolean(g_variant_get_child_value(res, 0)); - - if (prop) { - gtk_widget_hide(main_image); - } else { - gtk_widget_show(main_image); - } - - return; + IndicatorMessages *self = INDICATOR_MESSAGES (io); + return self->accessible_desc; } -static guint connection_drop_timeout = 0; - -/* Resets the icon to not having messages if we can't get a good - answer on it from the service. */ -static gboolean -connection_drop_cb (gpointer user_data) +static const gchar * +get_name_hint (IndicatorObject *io) { - if (main_image != NULL) { - indicator_image_helper_update(GTK_IMAGE(main_image), "indicator-messages"); - } - connection_drop_timeout = 0; - return FALSE; + return PACKAGE; } -/* Proxy is setup now.. whoo! */ static void -proxy_ready_cb (GObject * obj, GAsyncResult * res, gpointer user_data) +indicator_messages_accessible_desc_updated (IndicatorMessages *self) { - GError * error = NULL; - GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error); + GList *entries; - if (error != NULL) { - g_warning("Unable to get proxy of service: %s", error->message); - g_error_free(error); - return; - } + entries = indicator_object_get_entries (INDICATOR_OBJECT (self)); + g_return_if_fail (entries != NULL); - icon_proxy = proxy; - - g_signal_connect(G_OBJECT(proxy), "g-signal", G_CALLBACK(proxy_signal), user_data); - - g_dbus_proxy_call(icon_proxy, - "AttentionRequested", - NULL, /* params */ - G_DBUS_CALL_FLAGS_NONE, - -1, /* timeout */ - NULL, /* cancel */ - attention_cb, - user_data); - g_dbus_proxy_call(icon_proxy, - "IconShown", - NULL, /* params */ - G_DBUS_CALL_FLAGS_NONE, - -1, /* timeout */ - NULL, /* cancel */ - icon_cb, - user_data); + g_signal_emit_by_name (self, INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE, entries->data); - return; + g_list_free (entries); } -/* Sets up all the icon information in the proxy. */ -static void -connection_change (IndicatorServiceManager * sm, gboolean connected, gpointer user_data) +static void +update_root_item (IndicatorMessages * self) { - if (connection_drop_timeout != 0) { - g_source_remove(connection_drop_timeout); - connection_drop_timeout = 0; - } + gchar *iconstr; - if (!connected) { - /* Ensure that we're not saying there are messages - when we don't have a connection. */ - connection_drop_timeout = g_timeout_add(400, connection_drop_cb, NULL); + if (g_menu_model_get_n_items (self->menu) == 0) return; - } - if (icon_proxy == NULL) { - g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - bus_interface_info, - INDICATOR_MESSAGES_DBUS_NAME, - INDICATOR_MESSAGES_DBUS_SERVICE_OBJECT, - INDICATOR_MESSAGES_DBUS_SERVICE_INTERFACE, - NULL, /* cancel */ - proxy_ready_cb, - sm); - } else { - g_dbus_proxy_call(icon_proxy, - "AttentionRequested", - NULL, /* params */ - G_DBUS_CALL_FLAGS_NONE, - -1, /* timeout */ - NULL, /* cancel */ - attention_cb, - sm); - g_dbus_proxy_call(icon_proxy, - "IconShown", - NULL, /* params */ - G_DBUS_CALL_FLAGS_NONE, - -1, /* timeout */ - NULL, /* cancel */ - icon_cb, - sm); - } + if (g_menu_model_get_item_attribute (self->menu, 0, "x-canonical-icon", "s", &iconstr)) { + GIcon *icon; + GError *error; - return; -} - -/* Sets the icon when it changes. */ -static void -application_icon_change_cb (DbusmenuMenuitem * mi, gchar * prop, GVariant * value, gpointer user_data) -{ - if (!g_strcmp0(prop, APPLICATION_MENUITEM_PROP_ICON)) { - /* Set the main icon */ - if (GTK_IS_IMAGE(user_data)) { - gtk_image_set_from_icon_name(GTK_IMAGE(user_data), g_variant_get_string(value, NULL), GTK_ICON_SIZE_MENU); + icon = g_icon_new_for_string (iconstr, &error); + if (icon) { + gtk_image_set_from_gicon (GTK_IMAGE (self->image), icon, GTK_ICON_SIZE_MENU); + g_object_unref (icon); } - } - - return; -} - -/* Sets the label when it changes. */ -static void -application_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GVariant * value, gpointer user_data) -{ - if (!g_strcmp0(prop, APPLICATION_MENUITEM_PROP_NAME)) { - /* Set the main label */ - if (GTK_IS_LABEL(user_data)) { - gtk_label_set_text(GTK_LABEL(user_data), g_variant_get_string(value, NULL)); + else { + g_warning ("unable to load icon: %s", error->message); + g_error_free (error); } - } - if (!g_strcmp0(prop, APPLICATION_MENUITEM_PROP_RUNNING)) { - /* TODO: should hide/show the triangle live if the menu was open. - In practice, this is rarely needed. */ + g_free (iconstr); } - return; -} - -/* Draws a triangle on the left, using fg[STATE_TYPE] color. */ -#if GTK_CHECK_VERSION(3, 0, 0) -static gboolean -application_triangle_draw_cb (GtkWidget *widget, cairo_t *cr, gpointer data) -{ -#else -static gboolean -application_triangle_draw_cb (GtkWidget *widget, GdkEventExpose *event, gpointer data) -{ - cairo_t *cr; -#endif - GtkAllocation allocation; - GtkStyle *style; - int x, y, arrow_width, arrow_height; - - if (!GTK_IS_WIDGET (widget)) return FALSE; - if (!DBUSMENU_IS_MENUITEM (data)) return FALSE; - - /* render the triangle indicator only if the application is running */ - if (! dbusmenu_menuitem_property_get_bool (DBUSMENU_MENUITEM(data), APPLICATION_MENUITEM_PROP_RUNNING)) - return FALSE;; - - /* get style */ - style = gtk_widget_get_style (widget); - - /* set arrow position / dimensions */ - arrow_width = 5; /* the pixel-based reference triangle is 5x9 */ - arrow_height = 9; - gtk_widget_get_allocation (widget, &allocation); -#if GTK_CHECK_VERSION(3, 0, 0) - x = 0; - y = allocation.height/2.0 - (double)arrow_height/2.0; -#else - x = allocation.x; - y = allocation.y + allocation.height/2.0 - (double)arrow_height/2.0; -#endif - -#if GTK_CHECK_VERSION(3, 0, 0) - cairo_save (cr); -#else - /* initialize cairo drawing area */ - cr = (cairo_t*) gdk_cairo_create (gtk_widget_get_window (widget)); -#endif - - /* set line width */ - cairo_set_line_width (cr, 1.0); - - /* cairo drawing code */ - cairo_move_to (cr, x, y); - cairo_line_to (cr, x, y + arrow_height); - cairo_line_to (cr, x + arrow_width, y + (double)arrow_height/2.0); - cairo_close_path (cr); - cairo_set_source_rgb (cr, style->fg[gtk_widget_get_state(widget)].red/65535.0, - style->fg[gtk_widget_get_state(widget)].green/65535.0, - style->fg[gtk_widget_get_state(widget)].blue/65535.0); - cairo_fill (cr); - -#if GTK_CHECK_VERSION(3, 0, 0) - cairo_restore (cr); -#else - /* remember to destroy cairo context to avoid leaks */ - cairo_destroy (cr); -#endif - - return FALSE; -} - -static gint -gtk_widget_get_font_size (GtkWidget *widget) -{ -#if GTK_CHECK_VERSION(3, 0, 0) - const PangoFontDescription *font; - - font = gtk_style_context_get_font (gtk_widget_get_style_context (widget), - gtk_widget_get_state_flags (widget)); + g_free (self->accessible_desc); + self->accessible_desc = NULL; - return pango_font_description_get_size (font) / PANGO_SCALE; -#else - return 12; -#endif + g_menu_model_get_item_attribute (self->menu, 0, "x-canonical-accessible-description", + "s", &self->accessible_desc); + indicator_messages_accessible_desc_updated (self); } -/* Custom function to draw rounded rectangle with max radius */ static void -custom_cairo_rounded_rectangle (cairo_t *cr, - double x, double y, double w, double h) +update_menu (IndicatorMessages *self) { - double radius = h / 2.0; - - cairo_move_to (cr, x+radius, y); - cairo_arc (cr, x+w-radius, y+radius, radius, M_PI*1.5, M_PI*2); - cairo_arc (cr, x+w-radius, y+h-radius, radius, 0, M_PI*0.5); - cairo_arc (cr, x+radius, y+h-radius, radius, M_PI*0.5, M_PI); - cairo_arc (cr, x+radius, y+radius, radius, M_PI, M_PI*1.5); -} + GMenuModel *popup; + GMenuItem *item; -/* Draws a rounded rectangle with text inside. */ -#if GTK_CHECK_VERSION(3, 0, 0) -static gboolean -numbers_draw_cb (GtkWidget *widget, cairo_t *cr, gpointer data) -{ -#else -static gboolean -numbers_draw_cb (GtkWidget *widget, GdkEventExpose *event, gpointer data) -{ - cairo_t *cr; -#endif - GtkAllocation allocation; - GtkStyle *style; - double x, y, w, h; - PangoLayout * layout; - PangoRectangle layout_extents; - gint font_size = gtk_widget_get_font_size (widget); - gboolean is_lozenge = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "is-lozenge")); - - if (!GTK_IS_WIDGET (widget)) return FALSE; - - /* let the label handle the drawing if it's not a lozenge */ - if (!is_lozenge) - return FALSE; - - /* get style */ - style = gtk_widget_get_style (widget); - - /* set arrow position / dimensions */ - gtk_widget_get_allocation (widget, &allocation); -#if GTK_CHECK_VERSION(3, 0, 0) - x = 0; - y = 0; -#else - x = allocation.x; - y = allocation.y; -#endif - w = allocation.width; - h = allocation.height; - - layout = gtk_label_get_layout (GTK_LABEL(widget)); - pango_layout_get_extents (layout, NULL, &layout_extents); - pango_extents_to_pixels (&layout_extents, NULL); - - if (layout_extents.width == 0) - return TRUE; - -#if GTK_CHECK_VERSION(3, 0, 0) - cairo_save (cr); -#else - /* initialize cairo drawing area */ - cr = (cairo_t*) gdk_cairo_create (gtk_widget_get_window (widget)); -#endif - - /* set line width */ - cairo_set_line_width (cr, 1.0); - - cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); - - /* cairo drawing code */ - custom_cairo_rounded_rectangle (cr, x - font_size/2.0, y, w + font_size, h); - - cairo_set_source_rgba (cr, style->fg[gtk_widget_get_state(widget)].red/65535.0, - style->fg[gtk_widget_get_state(widget)].green/65535.0, - style->fg[gtk_widget_get_state(widget)].blue/65535.0, 0.5); - - x += (allocation.width - layout_extents.width) / 2.0; - y += (allocation.height - layout_extents.height) / 2.0; - cairo_move_to (cr, floor (x), floor (y)); - pango_cairo_layout_path (cr, layout); - cairo_fill (cr); - -#if GTK_CHECK_VERSION(3, 0, 0) - cairo_restore (cr); -#else - /* remember to destroy cairo context to avoid leaks */ - cairo_destroy (cr); -#endif - - return TRUE; -} - -/* Builds a menu item representing a running application in the - messaging menu */ -static gboolean -new_application_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data) -{ - g_debug ("%s (\"%s\")", __func__, dbusmenu_menuitem_property_get(newitem, APPLICATION_MENUITEM_PROP_NAME)); - - GtkMenuItem * gmi = GTK_MENU_ITEM(gtk_menu_item_new()); - - gint padding = 4; - gtk_widget_style_get(GTK_WIDGET(gmi), "toggle-spacing", &padding, NULL); - -#if GTK_CHECK_VERSION(3, 0, 0) - GtkWidget * hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, padding); -#else - GtkWidget * hbox = gtk_hbox_new(FALSE, padding); -#endif - - GtkWidget * icon = gtk_image_new_from_icon_name(dbusmenu_menuitem_property_get(newitem, APPLICATION_MENUITEM_PROP_ICON), GTK_ICON_SIZE_MENU); - gtk_misc_set_alignment(GTK_MISC(icon), 1.0 /* right aligned */, 0.5); - gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0); - - /* Application name in a label */ - GtkWidget * label = gtk_label_new(dbusmenu_menuitem_property_get(newitem, APPLICATION_MENUITEM_PROP_NAME)); - gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0); + if (g_menu_model_get_n_items (self->menu) == 0) + return; - gtk_container_add(GTK_CONTAINER(gmi), hbox); - gtk_widget_show_all (GTK_WIDGET (gmi)); + popup = g_menu_model_get_item_link (self->menu, 0, G_MENU_LINK_SUBMENU); + if (popup == NULL) + return; - /* Attach some of the standard GTK stuff */ - dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, gmi, parent); + if (g_menu_model_get_n_items (G_MENU_MODEL (self->menu_wrapper)) == 1) + g_menu_remove (self->menu_wrapper, 0); - /* Make sure we can handle the label changing */ - g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(application_prop_change_cb), label); - g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(application_icon_change_cb), icon); -#if GTK_CHECK_VERSION(3, 0, 0) - g_signal_connect_after(G_OBJECT (gmi), "draw", G_CALLBACK (application_triangle_draw_cb), newitem); -#else - g_signal_connect_after(G_OBJECT (gmi), "expose_event", G_CALLBACK (application_triangle_draw_cb), newitem); -#endif + item = g_menu_item_new_section (NULL, popup); + g_menu_item_set_attribute (item, "action-namespace", + "s", get_name_hint (INDICATOR_OBJECT (self))); + g_menu_append_item (self->menu_wrapper, item); - return TRUE; + g_object_unref (item); + g_object_unref (popup); } -typedef struct _indicator_item_t indicator_item_t; -struct _indicator_item_t { - GtkWidget * icon; - GtkWidget * label; - GtkWidget * right; -}; - -/* Whenever we have a property change on a DbusmenuMenuitem - we need to be responsive to that. */ static void -indicator_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GVariant * value, indicator_item_t * mi_data) +menu_items_changed (GMenuModel *menu, + gint position, + gint removed, + gint added, + gpointer user_data) { - if (!g_strcmp0(prop, INDICATOR_MENUITEM_PROP_LABEL)) { - /* Set the main label */ - gtk_label_set_text(GTK_LABEL(mi_data->label), g_variant_get_string(value, NULL)); - } else if (!g_strcmp0(prop, INDICATOR_MENUITEM_PROP_RIGHT)) { - /* Set the right label */ - gtk_label_set_text(GTK_LABEL(mi_data->right), g_variant_get_string(value, NULL)); - } else if (!g_strcmp0(prop, INDICATOR_MENUITEM_PROP_RIGHT_IS_LOZENGE)) { - g_object_set_data (G_OBJECT (mi_data->right), "is-lozenge", GINT_TO_POINTER (TRUE)); - gtk_widget_queue_draw (mi_data->right); - } else if (!g_strcmp0(prop, INDICATOR_MENUITEM_PROP_ICON)) { - /* We don't use the value here, which is probably less efficient, - but it's easier to use the easy function. And since th value - is already cached, shouldn't be a big deal really. */ - GdkPixbuf * pixbuf = dbusmenu_menuitem_property_get_image(mi, INDICATOR_MENUITEM_PROP_ICON); - if (pixbuf != NULL) { - /* If we've got a pixbuf we need to make sure it's of a reasonable - size to fit in the menu. If not, rescale it. */ - GdkPixbuf * resized_pixbuf; - gint width, height; - gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); - if (gdk_pixbuf_get_width(pixbuf) > width || - gdk_pixbuf_get_height(pixbuf) > height) { - g_debug("Resizing icon from %dx%d to %dx%d", gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), width, height); - resized_pixbuf = gdk_pixbuf_scale_simple(pixbuf, - width, - height, - GDK_INTERP_BILINEAR); - g_object_unref(pixbuf); - } else { - g_debug("Happy with icon sized %dx%d", gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf)); - resized_pixbuf = pixbuf; - } - - gtk_image_set_from_pixbuf(GTK_IMAGE(mi_data->icon), resized_pixbuf); - - g_object_unref(resized_pixbuf); - - gtk_widget_show(mi_data->icon); - } else { - gtk_widget_hide(mi_data->icon); - } - } - - return; -} + IndicatorMessages *self = user_data; -/* We have a small little menuitem type that handles all - of the fun stuff for indicators. Mostly this is the - shifting over and putting the icon in with some right - side text that'll be determined by the service. */ -static gboolean -new_indicator_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data) -{ - g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); - g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); - /* Note: not checking parent, it's reasonable for it to be NULL */ - - indicator_item_t * mi_data = g_new0(indicator_item_t, 1); - - GtkMenuItem * gmi = GTK_MENU_ITEM(gtk_menu_item_new()); - - gint padding = 4; - gint font_size = gtk_widget_get_font_size (GTK_WIDGET (gmi)); - gtk_widget_style_get(GTK_WIDGET(gmi), "toggle-spacing", &padding, NULL); - -#if GTK_CHECK_VERSION(3, 0, 0) - GtkWidget * hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, padding); -#else - GtkWidget * hbox = gtk_hbox_new(FALSE, padding); -#endif - - /* Icon, probably someone's face or avatar on an IM */ - mi_data->icon = gtk_image_new(); - - /* Set the minimum size, we always want it to take space */ - gint width, height; - gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height); - gtk_widget_set_size_request(GTK_WIDGET (gmi), -1, height + 4); - -#if GTK_CHECK_VERSION(3, 0, 0) - gtk_widget_set_margin_left (hbox, width + padding); -#endif - - GdkPixbuf * pixbuf = dbusmenu_menuitem_property_get_image(newitem, INDICATOR_MENUITEM_PROP_ICON); - if (pixbuf != NULL) { - /* If we've got a pixbuf we need to make sure it's of a reasonable - size to fit in the menu. If not, rescale it. */ - GdkPixbuf * resized_pixbuf; - if (gdk_pixbuf_get_width(pixbuf) > width || - gdk_pixbuf_get_height(pixbuf) > height) { - g_debug("Resizing icon from %dx%d to %dx%d", gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), width, height); - resized_pixbuf = gdk_pixbuf_scale_simple(pixbuf, - width, - height, - GDK_INTERP_BILINEAR); - g_object_unref(pixbuf); - } else { - g_debug("Happy with icon sized %dx%d", gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf)); - resized_pixbuf = pixbuf; - } - - gtk_image_set_from_pixbuf(GTK_IMAGE(mi_data->icon), resized_pixbuf); - - g_object_unref(resized_pixbuf); - } - gtk_misc_set_alignment(GTK_MISC(mi_data->icon), 0.0, 0.5); - gtk_box_pack_start(GTK_BOX(hbox), mi_data->icon, FALSE, FALSE, 0); - - if (pixbuf != NULL) { - gtk_widget_show(mi_data->icon); - } - - /* Label, probably a username, chat room or mailbox name */ - mi_data->label = gtk_label_new(dbusmenu_menuitem_property_get(newitem, INDICATOR_MENUITEM_PROP_LABEL)); - gtk_misc_set_alignment(GTK_MISC(mi_data->label), 0.0, 0.5); - gtk_box_pack_start(GTK_BOX(hbox), mi_data->label, TRUE, TRUE, 0); - gtk_widget_show(mi_data->label); - - /* Usually either the time or the count on the individual - item. */ - mi_data->right = gtk_label_new(dbusmenu_menuitem_property_get(newitem, INDICATOR_MENUITEM_PROP_RIGHT)); - g_object_set_data (G_OBJECT (mi_data->right), - "is-lozenge", - GINT_TO_POINTER (dbusmenu_menuitem_property_get_bool (newitem, INDICATOR_MENUITEM_PROP_RIGHT_IS_LOZENGE))); - /* install extra decoration overlay */ -#if GTK_CHECK_VERSION(3, 0, 0) - g_signal_connect (G_OBJECT (mi_data->right), "draw", - G_CALLBACK (numbers_draw_cb), NULL); -#else - g_signal_connect (G_OBJECT (mi_data->right), "expose_event", - G_CALLBACK (numbers_draw_cb), NULL); -#endif - - gtk_misc_set_alignment(GTK_MISC(mi_data->right), 1.0, 0.5); - gtk_box_pack_start(GTK_BOX(hbox), mi_data->right, FALSE, FALSE, padding + font_size/2.0); - gtk_label_set_width_chars (GTK_LABEL (mi_data->right), 2); -#if GTK_CHECK_VERSION(3, 0, 0) - gtk_style_context_add_class (gtk_widget_get_style_context (mi_data->right), - "accelerator"); -#endif - gtk_widget_show(mi_data->right); - - gtk_container_add(GTK_CONTAINER(gmi), hbox); - gtk_widget_show(hbox); - - dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, gmi, parent); - - g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(indicator_prop_change_cb), mi_data); - g_object_weak_ref(G_OBJECT(newitem), (GWeakNotify)g_free, mi_data); - - return TRUE; -} - -/* Builds the main image icon using the libindicator helper. */ -static GtkImage * -get_icon (IndicatorObject * io) -{ - main_image = GTK_WIDGET(indicator_image_helper("indicator-messages")); - gtk_widget_show(main_image); - - return GTK_IMAGE(main_image); -} - -/* Builds the menu for the indicator */ -static GtkMenu * -get_menu (IndicatorObject * io) -{ - DbusmenuGtkMenu * menu = dbusmenu_gtkmenu_new(INDICATOR_MESSAGES_DBUS_NAME, INDICATOR_MESSAGES_DBUS_OBJECT); - DbusmenuGtkClient * client = dbusmenu_gtkmenu_get_client(menu); - - dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), INDICATOR_MENUITEM_TYPE, new_indicator_item); - dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), APPLICATION_MENUITEM_TYPE, new_application_item); - - return GTK_MENU(menu); -} - -/* Returns the accessible description of the indicator */ -static const gchar * -get_accessible_desc (IndicatorObject * io) -{ - return accessible_desc; -} - -/* Returns the name hint of the indicator */ -static const gchar * -get_name_hint (IndicatorObject *io) -{ - return PACKAGE; -} - -/* Hide the notifications on middle-click over the indicator-messages */ -static void -indicator_messages_middle_click (IndicatorObject * io, IndicatorObjectEntry * entry, - guint time, gpointer data) -{ - if (icon_proxy == NULL) { - return; + if (position == 0) { + update_root_item (self); + update_menu (self); } - - g_dbus_proxy_call(icon_proxy, - "ClearAttention", - NULL, /* params */ - G_DBUS_CALL_FLAGS_NONE, - -1, /* timeout */ - NULL, /* cancel */ - NULL, - NULL); - - return; } diff --git a/src/launcher-menu-item.c b/src/launcher-menu-item.c deleted file mode 100644 index 91cbbb8..0000000 --- a/src/launcher-menu-item.c +++ /dev/null @@ -1,395 +0,0 @@ -/* -An indicator to show information that is in messaging applications -that the user is using. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <gdk/gdk.h> -#include <glib/gi18n.h> -#include <gio/gdesktopappinfo.h> -#include <libindicator/indicator-desktop-shortcuts.h> -#include "launcher-menu-item.h" -#include "dbus-data.h" -#include "default-applications.h" -#include "seen-db.h" - -enum { - NAME_CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -typedef struct _LauncherMenuItemPrivate LauncherMenuItemPrivate; -struct _LauncherMenuItemPrivate -{ - GAppInfo * appinfo; - GKeyFile * keyfile; - gchar * desktop; - IndicatorDesktopShortcuts * ids; - GList * shortcuts; -}; - -#define LAUNCHER_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), LAUNCHER_MENU_ITEM_TYPE, LauncherMenuItemPrivate)) - -#define NICK_DATA "ids-nick-data" - -/* Prototypes */ -static void launcher_menu_item_class_init (LauncherMenuItemClass *klass); -static void launcher_menu_item_init (LauncherMenuItem *self); -static void launcher_menu_item_dispose (GObject *object); -static void launcher_menu_item_finalize (GObject *object); -static void activate_cb (LauncherMenuItem * self, guint timestamp, gpointer data); -static void nick_activate_cb (LauncherMenuItem * self, guint timestamp, gpointer data); - - -G_DEFINE_TYPE (LauncherMenuItem, launcher_menu_item, DBUSMENU_TYPE_MENUITEM); - -static void -launcher_menu_item_class_init (LauncherMenuItemClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (LauncherMenuItemPrivate)); - - object_class->dispose = launcher_menu_item_dispose; - object_class->finalize = launcher_menu_item_finalize; - - signals[NAME_CHANGED] = g_signal_new(LAUNCHER_MENU_ITEM_SIGNAL_NAME_CHANGED, - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (LauncherMenuItemClass, name_changed), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); - - return; -} - -static void -launcher_menu_item_init (LauncherMenuItem *self) -{ - g_debug("Building new Launcher Menu Item"); - LauncherMenuItemPrivate * priv = LAUNCHER_MENU_ITEM_GET_PRIVATE(self); - - priv->appinfo = NULL; - priv->desktop = NULL; - priv->keyfile = NULL; - - priv->ids = NULL; - priv->shortcuts = NULL; - - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_TYPE, APPLICATION_MENUITEM_TYPE); - - return; -} - -static void -func_unref (gpointer data, gpointer user_data) -{ - g_object_unref(G_OBJECT(data)); - return; -} - -static void -launcher_menu_item_dispose (GObject *object) -{ - LauncherMenuItem * self = LAUNCHER_MENU_ITEM(object); - LauncherMenuItemPrivate * priv = LAUNCHER_MENU_ITEM_GET_PRIVATE(self); - - if (priv->appinfo != NULL) { - g_object_unref(priv->appinfo); - priv->appinfo = NULL; - } - - if (priv->keyfile != NULL) { - g_object_unref(priv->keyfile); - priv->keyfile = NULL; - } - - if (priv->ids != NULL) { - g_object_unref(priv->ids); - priv->ids = NULL; - } - - if (priv->shortcuts != NULL) { - g_list_foreach(priv->shortcuts, func_unref, NULL); - g_list_free(priv->shortcuts); - priv->shortcuts = NULL; - } - - G_OBJECT_CLASS (launcher_menu_item_parent_class)->dispose (object); -} - -static void -launcher_menu_item_finalize (GObject *object) -{ - LauncherMenuItem * self = LAUNCHER_MENU_ITEM(object); - LauncherMenuItemPrivate * priv = LAUNCHER_MENU_ITEM_GET_PRIVATE(self); - - if (priv->desktop != NULL) { - g_free(priv->desktop); - priv->desktop = NULL; - } - - G_OBJECT_CLASS (launcher_menu_item_parent_class)->finalize (object); - - return; -} - -LauncherMenuItem * -launcher_menu_item_new (const gchar * desktop_file) -{ - LauncherMenuItem * self = g_object_new(LAUNCHER_MENU_ITEM_TYPE, NULL); - g_debug("\tDesktop file: %s", desktop_file); - - LauncherMenuItemPrivate * priv = LAUNCHER_MENU_ITEM_GET_PRIVATE(self); - - /* Parse the desktop file we've been given. */ - priv->appinfo = G_APP_INFO(g_desktop_app_info_new_from_filename(desktop_file)); - priv->keyfile = g_key_file_new(); - g_key_file_load_from_file(priv->keyfile, desktop_file, G_KEY_FILE_NONE, NULL); - priv->desktop = g_strdup(desktop_file); - - /* Set the appropriate values on this menu item based on the - app info that we've parsed */ - g_debug("\tName: %s", launcher_menu_item_get_name(self)); - - const gchar * default_name = NULL; - - if (seen_db_seen(desktop_file)) { - default_name = get_default_name(desktop_file); - } else { - default_name = get_default_setup(desktop_file); - } - - if (default_name == NULL) { - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_LABEL, launcher_menu_item_get_name(self)); - } else { - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_LABEL, _(default_name)); - } - - gchar * iconstr; - if (default_name == NULL) { - iconstr = launcher_menu_item_get_icon(self); - } else { - iconstr = g_strdup(get_default_icon(desktop_file)); - } - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_ICON_NAME, iconstr); - g_free(iconstr); - dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); - - g_signal_connect(G_OBJECT(self), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(activate_cb), NULL); - - /* Start to build static shortcuts */ - if (seen_db_seen(desktop_file)) { - priv->ids = indicator_desktop_shortcuts_new(priv->desktop, "Messaging Menu"); - const gchar ** nicks = indicator_desktop_shortcuts_get_nicks(priv->ids); - gint i; - for (i = 0; nicks[i] != NULL; i++) { - DbusmenuMenuitem * mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_TYPE, APPLICATION_MENUITEM_TYPE); - g_object_set_data(G_OBJECT(mi), NICK_DATA, (gpointer)nicks[i]); - - gchar *name = indicator_desktop_shortcuts_nick_get_name(priv->ids, nicks[i]); - dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_LABEL, name); - g_free(name); - - g_signal_connect(G_OBJECT(mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(nick_activate_cb), self); - - priv->shortcuts = g_list_append(priv->shortcuts, mi); - } - } - - /* Check to see if we should be eclipsed */ - if (priv->appinfo == NULL) { - launcher_menu_item_set_eclipsed(self, TRUE); - } - - return self; -} - -const gchar * -launcher_menu_item_get_name (LauncherMenuItem * appitem) -{ - LauncherMenuItemPrivate * priv = LAUNCHER_MENU_ITEM_GET_PRIVATE(appitem); - - if (priv->appinfo == NULL) { - return NULL; - } else { - return g_app_info_get_name(priv->appinfo); - } -} - -/* Respond to one of the shortcuts getting clicked on. */ -static void -nick_activate_cb (LauncherMenuItem * self, guint timestamp, gpointer data) -{ - gchar * nick = (gchar *)g_object_get_data(G_OBJECT(self), NICK_DATA); - LauncherMenuItem * lmi = LAUNCHER_MENU_ITEM(data); - - g_return_if_fail(nick != NULL); - g_return_if_fail(lmi != NULL); - - LauncherMenuItemPrivate * priv = LAUNCHER_MENU_ITEM_GET_PRIVATE(lmi); - - g_return_if_fail(priv->ids != NULL); - - if (!indicator_desktop_shortcuts_nick_exec(priv->ids, nick)) { - g_warning("Unable to execute nick '%s' for desktop file '%s'", nick, priv->desktop); - } - - return; -} - -/* Figure out the appropriate icon for this launcher */ -gchar * -launcher_menu_item_get_icon (LauncherMenuItem * appitem) -{ - LauncherMenuItemPrivate * priv = LAUNCHER_MENU_ITEM_GET_PRIVATE(appitem); - gchar * retval = NULL; - - /* Check to see if there is a specific icon for the messaging - menu first. */ - if (g_key_file_has_key(priv->keyfile, G_KEY_FILE_DESKTOP_GROUP, ICON_KEY, NULL) && retval == NULL) { - GError * error = NULL; - - retval = g_key_file_get_string(priv->keyfile, G_KEY_FILE_DESKTOP_GROUP, ICON_KEY, &error); - - if (error != NULL) { - /* Can't figure out why this would happen, but sure, let's print something */ - g_warning("Error getting '" ICON_KEY "' from desktop file: %s", error->message); - g_error_free(error); - } - } - - /* If there's not, or there is an error, we'll use the one - from the application info */ - if (priv->appinfo != NULL && retval == NULL) { - GIcon * icon = g_app_info_get_icon(priv->appinfo); - retval = g_icon_to_string(icon); - } - - return retval; -} - -/* When the menu item is clicked on it tries to launch - the application that is represented by the desktop file */ -static void -activate_cb (LauncherMenuItem * self, guint timestamp, gpointer data) -{ - LauncherMenuItemPrivate * priv = LAUNCHER_MENU_ITEM_GET_PRIVATE(self); - g_return_if_fail(priv->appinfo != NULL); - - GError * error = NULL; - if (!g_app_info_launch(priv->appinfo, NULL, NULL, &error)) { - g_warning("Application failed to launch '%s' because: %s", launcher_menu_item_get_name(self), error->message); - g_error_free(error); - } - - return; -} - -const gchar * -launcher_menu_item_get_desktop (LauncherMenuItem * launchitem) -{ - g_return_val_if_fail(IS_LAUNCHER_MENU_ITEM(launchitem), NULL); - LauncherMenuItemPrivate * priv = LAUNCHER_MENU_ITEM_GET_PRIVATE(launchitem); - return priv->desktop; -} - -/* Gets the decription for the item that should - go in the messaging menu */ -const gchar * -launcher_menu_item_get_description (LauncherMenuItem * li) -{ - g_return_val_if_fail(IS_LAUNCHER_MENU_ITEM(li), NULL); - LauncherMenuItemPrivate * priv = LAUNCHER_MENU_ITEM_GET_PRIVATE(li); - return g_app_info_get_description(priv->appinfo); -} - -/* Apply the eclipse value to all the shortcuts */ -static void -eclipse_shortcuts_cb (gpointer data, gpointer user_data) -{ - DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(data); - g_return_if_fail(mi != NULL); - - gboolean eclipsed = GPOINTER_TO_UINT(user_data); - - dbusmenu_menuitem_property_set_bool(mi, DBUSMENU_MENUITEM_PROP_VISIBLE, !eclipsed); - return; -} - -/* Hides the menu item based on whether it is eclipsed - or not. */ -void -launcher_menu_item_set_eclipsed (LauncherMenuItem * li, gboolean eclipsed) -{ - g_return_if_fail(IS_LAUNCHER_MENU_ITEM(li)); - LauncherMenuItemPrivate * priv = LAUNCHER_MENU_ITEM_GET_PRIVATE(li); - - g_debug("Laucher '%s' is %s", launcher_menu_item_get_name(li), eclipsed ? "now eclipsed" : "shown again"); - dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(li), DBUSMENU_MENUITEM_PROP_VISIBLE, !eclipsed); - - g_list_foreach(priv->shortcuts, eclipse_shortcuts_cb, GINT_TO_POINTER(eclipsed)); - - /* If we're being reshown let's re-evaluate how we should be - showing the label */ - if (!eclipsed) { - const gchar * default_name = NULL; - - if (seen_db_seen(priv->desktop)) { - default_name = get_default_name(priv->desktop); - } else { - default_name = get_default_setup(priv->desktop); - } - - if (default_name == NULL) { - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(li), DBUSMENU_MENUITEM_PROP_LABEL, launcher_menu_item_get_name(li)); - } else { - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(li), DBUSMENU_MENUITEM_PROP_LABEL, _(default_name)); - } - } - - return; -} - -/* Check to see if this item is eclipsed */ -gboolean -launcher_menu_item_get_eclipsed (LauncherMenuItem * li) -{ - gboolean show = dbusmenu_menuitem_property_get_bool(DBUSMENU_MENUITEM(li), DBUSMENU_MENUITEM_PROP_VISIBLE); - g_debug("Launcher check eclipse: %s", show ? "false" : "true"); - return !show; -} - -/* Gets the shortcuts that are associated with this - launcher. They're a list of DbusmenuMenuitems */ -GList * -launcher_menu_item_get_items (LauncherMenuItem * li) -{ - g_return_val_if_fail(IS_LAUNCHER_MENU_ITEM(li), NULL); - LauncherMenuItemPrivate * priv = LAUNCHER_MENU_ITEM_GET_PRIVATE(li); - return priv->shortcuts; -} diff --git a/src/launcher-menu-item.h b/src/launcher-menu-item.h deleted file mode 100644 index ace1f85..0000000 --- a/src/launcher-menu-item.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -An indicator to show information that is in messaging applications -that the user is using. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef __LAUNCHER_MENU_ITEM_H__ -#define __LAUNCHER_MENU_ITEM_H__ - -#include <glib.h> -#include <glib-object.h> - -#include <libdbusmenu-glib/menuitem.h> - -G_BEGIN_DECLS - -#define LAUNCHER_MENU_ITEM_TYPE (launcher_menu_item_get_type ()) -#define LAUNCHER_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LAUNCHER_MENU_ITEM_TYPE, LauncherMenuItem)) -#define LAUNCHER_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LAUNCHER_MENU_ITEM_TYPE, LauncherMenuItemClass)) -#define IS_LAUNCHER_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LAUNCHER_MENU_ITEM_TYPE)) -#define IS_LAUNCHER_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LAUNCHER_MENU_ITEM_TYPE)) -#define LAUNCHER_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), LAUNCHER_MENU_ITEM_TYPE, LauncherMenuItemClass)) - -#define LAUNCHER_MENU_ITEM_SIGNAL_NAME_CHANGED "name-changed" - -typedef struct _LauncherMenuItem LauncherMenuItem; -typedef struct _LauncherMenuItemClass LauncherMenuItemClass; - -struct _LauncherMenuItemClass { - DbusmenuMenuitemClass parent_class; - - void (* name_changed) (gchar * name); -}; - -struct _LauncherMenuItem { - DbusmenuMenuitem parent; -}; - -GType launcher_menu_item_get_type (void); -LauncherMenuItem * launcher_menu_item_new (const gchar * desktop_file); -const gchar * launcher_menu_item_get_name (LauncherMenuItem * appitem); -const gchar * launcher_menu_item_get_desktop (LauncherMenuItem * launchitem); -const gchar * launcher_menu_item_get_description (LauncherMenuItem * li); -gchar * launcher_menu_item_get_icon (LauncherMenuItem * appitem); -void launcher_menu_item_set_eclipsed (LauncherMenuItem * li, gboolean eclipsed); -gboolean launcher_menu_item_get_eclipsed (LauncherMenuItem * li); -GList * launcher_menu_item_get_items (LauncherMenuItem * li); - -G_END_DECLS - -#endif /* __LAUNCHER_MENU_ITEM_H__ */ - diff --git a/src/messages-service-dbus.c b/src/messages-service-dbus.c deleted file mode 100644 index 2b72f2e..0000000 --- a/src/messages-service-dbus.c +++ /dev/null @@ -1,472 +0,0 @@ -/* -An indicator to show information that is in messaging applications -that the user is using. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <gio/gio.h> -#include "messages-service-dbus.h" -#include "dbus-data.h" -#include "gen-messages-service.xml.h" - -enum { - ATTENTION_CHANGED, - ICON_CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -typedef struct _MessageServiceDbusPrivate MessageServiceDbusPrivate; - -struct _MessageServiceDbusPrivate -{ - GDBusConnection * connection; - GCancellable * accounts_cancel; - GDBusProxy * accounts_user; - gboolean dot; - gboolean hidden; -}; - -#define MESSAGE_SERVICE_DBUS_GET_PRIVATE(o) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((o), MESSAGE_SERVICE_DBUS_TYPE, MessageServiceDbusPrivate)) - -static void message_service_dbus_class_init (MessageServiceDbusClass *klass); -static void message_service_dbus_init (MessageServiceDbus *self); -static void message_service_dbus_dispose (GObject *object); -static void message_service_dbus_finalize (GObject *object); -static void bus_method_call (GDBusConnection * connection, - const gchar * sender, - const gchar * path, - const gchar * interface, - const gchar * method, - GVariant * params, - GDBusMethodInvocation * invocation, - gpointer user_data); - -static GDBusNodeInfo * bus_node_info = NULL; -static GDBusInterfaceInfo * bus_interface_info = NULL; -static const GDBusInterfaceVTable bus_interface_table = { - method_call: bus_method_call, - get_property: NULL, /* No properties */ - set_property: NULL /* No properties */ -}; - -G_DEFINE_TYPE (MessageServiceDbus, message_service_dbus, G_TYPE_OBJECT); - - -static void -message_service_dbus_class_init (MessageServiceDbusClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (MessageServiceDbusPrivate)); - - object_class->dispose = message_service_dbus_dispose; - object_class->finalize = message_service_dbus_finalize; - - signals[ATTENTION_CHANGED] = g_signal_new(MESSAGE_SERVICE_DBUS_SIGNAL_ATTENTION_CHANGED, - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MessageServiceDbusClass, attention_changed), - NULL, NULL, - g_cclosure_marshal_VOID__BOOLEAN, - G_TYPE_NONE, 1, G_TYPE_BOOLEAN); - - signals[ICON_CHANGED] = g_signal_new(MESSAGE_SERVICE_DBUS_SIGNAL_ICON_CHANGED, - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MessageServiceDbusClass, icon_changed), - NULL, NULL, - g_cclosure_marshal_VOID__BOOLEAN, - G_TYPE_NONE, 1, G_TYPE_BOOLEAN); - - if (bus_node_info == NULL) { - GError * error = NULL; - - bus_node_info = g_dbus_node_info_new_for_xml(_messages_service, &error); - if (error != NULL) { - g_error("Unable to parse Messaging Menu Interface description: %s", error->message); - g_error_free(error); - } - } - - if (bus_interface_info == NULL) { - bus_interface_info = g_dbus_node_info_lookup_interface(bus_node_info, INDICATOR_MESSAGES_DBUS_SERVICE_INTERFACE); - - if (bus_interface_info == NULL) { - g_error("Unable to find interface '" INDICATOR_MESSAGES_DBUS_SERVICE_INTERFACE "'"); - } - } - - return; -} - -static void -connection_cb (GObject * object, GAsyncResult * res, gpointer user_data) -{ - GError * error = NULL; - GDBusConnection * connection = g_bus_get_finish(res, &error); - - if (error != NULL) { - g_error("Unable to connect to the session bus: %s", error->message); - g_error_free(error); - return; - } - - MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(user_data); - priv->connection = connection; - - g_dbus_connection_register_object(connection, - INDICATOR_MESSAGES_DBUS_SERVICE_OBJECT, - bus_interface_info, - &bus_interface_table, - user_data, - NULL, /* destroy */ - &error); - - if (error != NULL) { - g_error("Unable to register on session bus: %s", error->message); - g_error_free(error); - return; - } - - g_debug("Service on session bus"); - - return; -} - -static void -accounts_notify_cb (GObject *source_object, GAsyncResult *res, - gpointer user_data) -{ - GError * error = NULL; - GVariant * answer = g_dbus_proxy_call_finish(G_DBUS_PROXY(source_object), res, &error); - - if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_error_free(error); - return; /* Must exit before accessing freed memory */ - } - - MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(user_data); - - if (priv->accounts_cancel != NULL) { - g_object_unref(priv->accounts_cancel); - priv->accounts_cancel = NULL; - } - - if (error != NULL) { - g_warning("Unable to get notify accounts service of message status: %s", error->message); - g_error_free(error); - return; - } - - g_variant_unref (answer); -} - -static void -accounts_notify (MessageServiceDbus *self) -{ - MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(self); - - if (priv->accounts_user == NULL) - return; /* We're not able to talk to accounts service */ - - if (priv->accounts_cancel != NULL) { - /* Cancel old notify before starting new one */ - g_cancellable_cancel(priv->accounts_cancel); - g_object_unref(priv->accounts_cancel); - priv->accounts_cancel = NULL; - } - - priv->accounts_cancel = g_cancellable_new(); - g_dbus_proxy_call(priv->accounts_user, - "SetXHasMessages", - g_variant_new ("(b)", priv->dot), - G_DBUS_CALL_FLAGS_NONE, - -1, /* timeout */ - priv->accounts_cancel, - accounts_notify_cb, - self); -} - -static void -get_accounts_user_proxy_cb (GObject *source_object, GAsyncResult *res, - gpointer user_data) -{ - GError * error = NULL; - GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error); - - if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_error_free(error); - return; /* Must exit before accessing freed memory */ - } - - MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(user_data); - - if (priv->accounts_cancel != NULL) { - g_object_unref(priv->accounts_cancel); - priv->accounts_cancel = NULL; - } - - if (error != NULL) { - g_warning("Unable to get proxy of accountsservice: %s", error->message); - g_error_free(error); - return; - } - - priv->accounts_user = proxy; - accounts_notify (MESSAGE_SERVICE_DBUS (user_data)); -} - -static void -get_accounts_user_find_user_cb (GObject *source_object, GAsyncResult *res, - gpointer user_data) -{ - GError * error = NULL; - GVariant * answer = g_dbus_proxy_call_finish(G_DBUS_PROXY(source_object), res, &error); - - /* We're done with main accounts proxy now */ - g_object_unref (source_object); - - if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_error_free(error); - return; /* Must exit before accessing freed memory */ - } - - MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(user_data); - - if (priv->accounts_cancel != NULL) { - g_object_unref(priv->accounts_cancel); - priv->accounts_cancel = NULL; - } - - if (error != NULL) { - g_warning("Unable to get object name of user from accountsservice: %s", error->message); - g_error_free(error); - return; - } - - if (!g_variant_is_of_type (answer, G_VARIANT_TYPE ("(o)"))) { - g_warning("Unexpected type from FindUserByName: %s", g_variant_get_type_string (answer)); - g_variant_unref(answer); - return; - } - - const gchar *path; - g_variant_get(answer, "(&o)", &path); - - priv->accounts_cancel = g_cancellable_new(); - g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.Accounts", - path, - "org.freedesktop.Accounts.User", - priv->accounts_cancel, - get_accounts_user_proxy_cb, - user_data); - - g_variant_unref (answer); -} - -static void -get_accounts_proxy_cb (GObject *source_object, GAsyncResult *res, - gpointer user_data) -{ - GError * error = NULL; - GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error); - - if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_error_free(error); - return; /* Must exit before accessing freed memory */ - } - - MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(user_data); - - if (priv->accounts_cancel != NULL) { - g_object_unref(priv->accounts_cancel); - priv->accounts_cancel = NULL; - } - - if (error != NULL) { - g_warning("Unable to get proxy of accountsservice: %s", error->message); - g_error_free(error); - return; - } - - priv->accounts_cancel = g_cancellable_new(); - g_dbus_proxy_call(proxy, - "FindUserByName", - g_variant_new ("(s)", g_get_user_name ()), - G_DBUS_CALL_FLAGS_NONE, - -1, /* timeout */ - priv->accounts_cancel, - get_accounts_user_find_user_cb, - user_data); -} - -static void -get_accounts_proxy (MessageServiceDbus *self) -{ - MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(self); - - g_return_if_fail(priv->accounts_cancel == NULL); - - priv->accounts_cancel = g_cancellable_new(); - g_dbus_proxy_new_for_bus(G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.Accounts", - "/org/freedesktop/Accounts", - "org.freedesktop.Accounts", - priv->accounts_cancel, - get_accounts_proxy_cb, - self); -} - -static void -message_service_dbus_init (MessageServiceDbus *self) -{ - g_bus_get(G_BUS_TYPE_SESSION, NULL, connection_cb, self); - get_accounts_proxy (self); - - MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(self); - - priv->dot = FALSE; - priv->hidden = FALSE; - - return; -} - -static void -message_service_dbus_dispose (GObject *object) -{ - MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(object); - - if (priv->connection != NULL) { - g_object_unref(priv->connection); - priv->connection = NULL; - } - - if (priv->accounts_cancel != NULL) { - g_cancellable_cancel(priv->accounts_cancel); - g_object_unref(priv->accounts_cancel); - priv->accounts_cancel = NULL; - } - - if (priv->accounts_user != NULL) { - g_object_unref(priv->accounts_user); - priv->accounts_user = NULL; - } - - G_OBJECT_CLASS (message_service_dbus_parent_class)->dispose (object); - return; -} - -static void -message_service_dbus_finalize (GObject *object) -{ - - - G_OBJECT_CLASS (message_service_dbus_parent_class)->finalize (object); - return; -} - -MessageServiceDbus * -message_service_dbus_new (void) -{ - return MESSAGE_SERVICE_DBUS(g_object_new(MESSAGE_SERVICE_DBUS_TYPE, NULL)); -} - -/* Method request off of DBus */ -static void -bus_method_call (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * method, GVariant * params, GDBusMethodInvocation * invocation, gpointer user_data) -{ - MessageServiceDbus * ms = MESSAGE_SERVICE_DBUS(user_data); - if (ms == NULL) { return; } - - MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(ms); - - if (g_strcmp0("AttentionRequested", method) == 0) { - g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", priv->dot)); - return; - } else if (g_strcmp0("IconShown", method) == 0) { - g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", priv->hidden)); - return; - } else if (g_strcmp0("ClearAttention", method) == 0) { - message_service_dbus_set_attention(ms, FALSE); - g_dbus_method_invocation_return_value(invocation, NULL); - return; - } else { - g_warning("Unknown function call '%s'", method); - } - - return; -} - -void -message_service_dbus_set_attention (MessageServiceDbus * self, gboolean attention) -{ - MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(self); - /* Do signal */ - if (attention != priv->dot) { - priv->dot = attention; - g_signal_emit(G_OBJECT(self), signals[ATTENTION_CHANGED], 0, priv->dot, TRUE); - - if (priv->connection != NULL) { - g_dbus_connection_emit_signal(priv->connection, - NULL, - INDICATOR_MESSAGES_DBUS_SERVICE_OBJECT, - INDICATOR_MESSAGES_DBUS_SERVICE_INTERFACE, - "AttentionChanged", - g_variant_new("(b)", priv->dot), - NULL); - } - - accounts_notify (self); - } - return; -} - -void -message_service_dbus_set_icon (MessageServiceDbus * self, gboolean hidden) -{ - MessageServiceDbusPrivate * priv = MESSAGE_SERVICE_DBUS_GET_PRIVATE(self); - /* Do signal */ - if (hidden != priv->hidden) { - priv->hidden = hidden; - g_signal_emit(G_OBJECT(self), signals[ICON_CHANGED], 0, priv->hidden, TRUE); - - if (priv->connection != NULL) { - g_dbus_connection_emit_signal(priv->connection, - NULL, - INDICATOR_MESSAGES_DBUS_SERVICE_OBJECT, - INDICATOR_MESSAGES_DBUS_SERVICE_INTERFACE, - "IconChanged", - g_variant_new("(b)", priv->hidden), - NULL); - } - } - return; -} diff --git a/src/messages-service-dbus.h b/src/messages-service-dbus.h deleted file mode 100644 index 7a8574e..0000000 --- a/src/messages-service-dbus.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -An indicator to show information that is in messaging applications -that the user is using. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef __MESSAGE_SERVICE_DBUS_H__ -#define __MESSAGE_SERVICE_DBUS_H__ - -#include <glib.h> -#include <glib-object.h> - -G_BEGIN_DECLS - -#define MESSAGE_SERVICE_DBUS_TYPE (message_service_dbus_get_type ()) -#define MESSAGE_SERVICE_DBUS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MESSAGE_SERVICE_DBUS_TYPE, MessageServiceDbus)) -#define MESSAGE_SERVICE_DBUS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MESSAGE_SERVICE_DBUS_TYPE, MessageServiceDbusClass)) -#define IS_MESSAGE_SERVICE_DBUS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MESSAGE_SERVICE_DBUS_TYPE)) -#define IS_MESSAGE_SERVICE_DBUS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MESSAGE_SERVICE_DBUS_TYPE)) -#define MESSAGE_SERVICE_DBUS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MESSAGE_SERVICE_DBUS_TYPE, MessageServiceDbusClass)) - -#define MESSAGE_SERVICE_DBUS_SIGNAL_ATTENTION_CHANGED "attention-changed" -#define MESSAGE_SERVICE_DBUS_SIGNAL_ICON_CHANGED "icon-changed" - -typedef struct _MessageServiceDbus MessageServiceDbus; -typedef struct _MessageServiceDbusClass MessageServiceDbusClass; - -struct _MessageServiceDbusClass { - GObjectClass parent_class; - - void (*attention_changed) (gboolean dot); - void (*icon_changed) (gboolean hidden); -}; - -struct _MessageServiceDbus { - GObject parent; -}; - -GType message_service_dbus_get_type (void); -MessageServiceDbus * message_service_dbus_new (void); -void message_service_dbus_set_attention (MessageServiceDbus * self, gboolean attention); -void message_service_dbus_set_icon (MessageServiceDbus * self, gboolean hidden); - -G_END_DECLS - -#endif diff --git a/src/messages-service.c b/src/messages-service.c index 078cee3..407b8ba 100644 --- a/src/messages-service.c +++ b/src/messages-service.c @@ -2,10 +2,11 @@ An indicator to show information that is in messaging applications that the user is using. -Copyright 2009 Canonical Ltd. +Copyright 2012 Canonical Ltd. Authors: Ted Gould <ted@canonical.com> + Lars Uebernickel <lars.uebernickel@canonical.com> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published @@ -20,1512 +21,461 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <string.h> -#include <locale.h> -#include <libintl.h> #include <config.h> -#include <pango/pango-utils.h> -#include <libindicate/listener.h> +#include <locale.h> #include <libindicator/indicator-service.h> #include <gio/gio.h> +#include <gio/gdesktopappinfo.h> #include <glib/gi18n.h> -#include <libdbusmenu-glib/client.h> -#include <libdbusmenu-glib/server.h> - -#include "im-menu-item.h" -#include "app-menu-item.h" -#include "launcher-menu-item.h" +#include "app-section.h" #include "dbus-data.h" -#include "dirs.h" -#include "messages-service-dbus.h" -#include "seen-db.h" -#include "status-items.h" - -static IndicatorService * service = NULL; -static IndicateListener * listener = NULL; -static GList * serverList = NULL; -static GList * launcherList = NULL; - -static DbusmenuMenuitem * root_menuitem = NULL; -static DbusmenuMenuitem * status_separator = NULL; -static DbusmenuMenuitem * clear_attention = NULL; -static GMainLoop * mainloop = NULL; - -static MessageServiceDbus * dbus_interface = NULL; - -#define DESKTOP_FILE_GROUP "Messaging Menu" -#define DESKTOP_FILE_KEY_DESKTOP "DesktopFile" - -static void server_shortcut_added (AppMenuItem * appitem, DbusmenuMenuitem * mi, gpointer data); -static void server_shortcut_removed (AppMenuItem * appitem, DbusmenuMenuitem * mi, gpointer data); -static void server_count_changed (AppMenuItem * appitem, guint count, gpointer data); -static void server_name_changed (AppMenuItem * appitem, gchar * name, gpointer data); -static void im_time_changed (ImMenuItem * imitem, glong seconds, gpointer data); -static void resort_menu (DbusmenuMenuitem * menushell); -static void indicator_removed (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gpointer data); -static void check_eclipses (AppMenuItem * ai); -static void remove_eclipses (AppMenuItem * ai); -static gboolean build_launcher (gpointer data); -static gboolean build_launcher_keyfile (gpointer data); -static void build_launcher_core (const gchar * desktop); -static gboolean build_launchers (gpointer data); -static gboolean blacklist_init (gpointer data); -static gboolean blacklist_add (gpointer data); -static gchar * desktop_file_from_keyfile (const gchar * definition_file); -static gboolean blacklist_keyfile_add (gpointer udata); -static void blacklist_add_core (gchar * desktop, gchar * definition); -static gboolean blacklist_remove (gpointer data); -static void blacklist_dir_changed (GFileMonitor * monitor, GFile * file, GFile * other_file, GFileMonitorEvent event_type, gpointer user_data); -static void app_dir_changed (GFileMonitor * monitor, GFile * file, GFile * other_file, GFileMonitorEvent event_type, gpointer user_data); -static gboolean destroy_launcher (gpointer data); -static void check_hidden (void); +#include "gactionmuxer.h" +#include "gsettingsstrv.h" +#include "gmenuutils.h" +#include "indicator-messages-service.h" +static GHashTable *applications; -/* - * Server List - */ - -typedef struct _serverList_t serverList_t; -struct _serverList_t { - IndicateListenerServer * server; - AppMenuItem * menuitem; - DbusmenuMenuitem * separator; - gboolean attention; - guint count; - GList * imList; -}; +IndicatorMessagesService *messages_service; +static GSimpleActionGroup *actions; +static GActionMuxer *action_muxer; +static GMenu *toplevel_menu; +static GMenu *menu; +static GMenuModel *chat_section; +static GSettings *settings; -static gint -serverList_equal (gconstpointer a, gconstpointer b) -{ - serverList_t * pa, * pb; - pa = (serverList_t *)a; - pb = (serverList_t *)b; +static gchar * +g_app_info_get_simple_id (GAppInfo *appinfo) +{ + const gchar *id; - const gchar * pan = INDICATE_LISTENER_SERVER_DBUS_NAME(pa->server); - const gchar * pbn = INDICATE_LISTENER_SERVER_DBUS_NAME(pb->server); - const gchar * pap = indicate_listener_server_get_dbuspath(pa->server); - const gchar * pbp = indicate_listener_server_get_dbuspath(pb->server); + id = g_app_info_get_id (appinfo); + if (!id) + return NULL; - if (g_strcmp0(pan, pbn) == 0) - return g_strcmp0(pap, pbp); + if (g_str_has_suffix (id, ".desktop")) + return g_strndup (id, strlen (id) - 8); else - return 1; + return g_strdup (id); } -static gint -serverList_sort (gconstpointer a, gconstpointer b) +static void +actions_changed (GObject *object, + GParamSpec *pspec, + gpointer user_data) { - serverList_t * pa, * pb; + AppSection *section = APP_SECTION (object); + gchar *id; + GActionGroup *actions; - pa = (serverList_t *)a; - pb = (serverList_t *)b; + id = g_app_info_get_simple_id (app_section_get_app_info (section)); + actions = app_section_get_actions (section); - const gchar * pan = app_menu_item_get_name(pa->menuitem); - const gchar * pbn = app_menu_item_get_name(pb->menuitem); - - return g_strcmp0(pan, pbn); + g_action_muxer_insert (action_muxer, id, actions); + g_free (id); } -/* - * Item List - */ - -typedef struct _imList_t imList_t; -struct _imList_t { - IndicateListenerServer * server; - IndicateListenerIndicator * indicator; - DbusmenuMenuitem * menuitem; - gulong timechange_cb; - gulong attentionchange_cb; -}; static gboolean -imList_equal (gconstpointer a, gconstpointer b) -{ - imList_t * pa, * pb; - - pa = (imList_t *)a; - pb = (imList_t *)b; - - const gchar * pas = INDICATE_LISTENER_SERVER_DBUS_NAME(pa->server); - const gchar * pbs = INDICATE_LISTENER_SERVER_DBUS_NAME(pb->server); - - guint pai = INDICATE_LISTENER_INDICATOR_ID(pa->indicator); - guint pbi = INDICATE_LISTENER_INDICATOR_ID(pb->indicator); - - g_debug("\tComparing (%s %d) to (%s %d)", pas, pai, pbs, pbi); - - return !((!g_strcmp0(pas, pbs)) && (pai == pbi)); -} - -static gint -imList_sort (gconstpointer a, gconstpointer b) -{ - imList_t * pa, * pb; - - pa = (imList_t *)a; - pb = (imList_t *)b; - - return (gint)(im_menu_item_get_seconds(IM_MENU_ITEM(pb->menuitem)) - im_menu_item_get_seconds(IM_MENU_ITEM(pa->menuitem))); -} - -/* - * Launcher List - */ - -typedef struct _launcherList_t launcherList_t; -struct _launcherList_t { - LauncherMenuItem * menuitem; - DbusmenuMenuitem * separator; - GList * appdiritems; -}; - -static gint -launcherList_sort (gconstpointer a, gconstpointer b) +app_section_draws_attention (gpointer key, + gpointer value, + gpointer user_data) { - launcherList_t * pa, * pb; - - pa = (launcherList_t *)a; - pb = (launcherList_t *)b; - - const gchar * pan = launcher_menu_item_get_name(pa->menuitem); - const gchar * pbn = launcher_menu_item_get_name(pb->menuitem); - - return g_strcmp0(pan, pbn); + AppSection *section = value; + return app_section_get_draws_attention (section); } static void -launcherList_count_helper (gpointer data, gpointer user_data) +draws_attention_changed (GObject *object, + GParamSpec *pspec, + gpointer user_data) { - guint * count = (guint *)user_data; - launcherList_t * li = (launcherList_t *)data; - - if (!launcher_menu_item_get_eclipsed(li->menuitem)) { - *count = *count + 1; - } - - return; -} - -static guint -launcherList_count (void) -{ - guint count = 0; - - g_list_foreach(launcherList, launcherList_count_helper, &count); - - return count; -} - -/* - * Black List - */ - -static GHashTable * blacklist = NULL; -static GFileMonitor * blacklistdirmon = NULL; - -/* Initialize the black list and start to setup - handlers for it. */ -static gboolean -blacklist_init (gpointer data) -{ - blacklist = g_hash_table_new_full(g_str_hash, g_str_equal, - g_free, g_free); - - gchar * blacklistdir = g_build_filename(g_get_user_config_dir(), USER_BLACKLIST_DIR, NULL); - g_debug("Looking at blacklist: %s", blacklistdir); - if (!g_file_test(blacklistdir, G_FILE_TEST_IS_DIR)) { - g_free(blacklistdir); - return FALSE; - } - - GFile * filedir = g_file_new_for_path(blacklistdir); - blacklistdirmon = g_file_monitor_directory(filedir, G_FILE_MONITOR_NONE, NULL, NULL); - if (blacklistdirmon != NULL) { - g_signal_connect(G_OBJECT(blacklistdirmon), "changed", G_CALLBACK(blacklist_dir_changed), NULL); - } - - GError * error = NULL; - GDir * dir = g_dir_open(blacklistdir, 0, &error); - if (dir == NULL) { - g_warning("Unable to open blacklist directory (%s): %s", blacklistdir, error == NULL ? "No Message" : error->message); - g_error_free(error); - g_free(blacklistdir); - return FALSE; - } + GSimpleAction *messages; + GSimpleAction *clear; + gboolean attention; - const gchar * filename = NULL; - while ((filename = g_dir_read_name(dir)) != NULL) { - g_debug("Found file: %s", filename); - gchar * path = g_build_filename(blacklistdir, filename, NULL); - if (g_str_has_suffix(path, "keyfile")) { - g_idle_add(blacklist_keyfile_add, path); - } else { - g_idle_add(blacklist_add, path); - } - } + messages = G_SIMPLE_ACTION (g_simple_action_group_lookup (actions, "messages")); + clear = G_SIMPLE_ACTION (g_simple_action_group_lookup (actions, "clear")); + g_return_if_fail (messages != NULL && clear != NULL); - g_dir_close(dir); - g_free(blacklistdir); + attention = g_hash_table_find (applications, app_section_draws_attention, NULL) != NULL; - return FALSE; + g_simple_action_set_state (messages, g_variant_new_boolean (attention)); + g_simple_action_set_enabled (clear, attention); } -/* Parses through a keyfile to find the desktop file entry and - pushes them into the blacklist. */ static gboolean -blacklist_keyfile_add (gpointer udata) +app_section_uses_chat (gpointer key, + gpointer value, + gpointer user_data) { - gchar * definition_file = (gchar *)udata; - gchar * desktopfile = desktop_file_from_keyfile(definition_file); - if (desktopfile != NULL) { - blacklist_add_core(desktopfile, definition_file); - g_free(desktopfile); - } - return FALSE; + AppSection *section = value; + return app_section_get_uses_chat_status (section); } -/* Takes a keyfile and finds the desktop file in it for - us. With some error handling. */ -static gchar * -desktop_file_from_keyfile (const gchar * definition_file) +static void +uses_chat_status_changed (GObject *object, + GParamSpec *pspec, + gpointer user_data) { - GKeyFile * keyfile = g_key_file_new(); - GError * error = NULL; + gboolean show_chat; + GMenuModel *first_section; - if (!g_key_file_load_from_file(keyfile, definition_file, G_KEY_FILE_NONE, &error)) { - g_warning("Unable to load keyfile '%s' because: %s", definition_file, error == NULL ? "unknown" : error->message); - g_error_free(error); - g_key_file_free(keyfile); - return NULL; - } + show_chat = g_hash_table_find (applications, app_section_uses_chat, NULL) != NULL; - if (!g_key_file_has_group(keyfile, DESKTOP_FILE_GROUP)) { - g_warning("Unable to use keyfile '%s' as it has no '" DESKTOP_FILE_GROUP "' group.", definition_file); - g_key_file_free(keyfile); - return NULL; + first_section = g_menu_model_get_item_link (G_MENU_MODEL (menu), 0, G_MENU_LINK_SECTION); + if (first_section == chat_section) { + if (!show_chat) + g_menu_remove (menu, 0); } - - if (!g_key_file_has_key(keyfile, DESKTOP_FILE_GROUP, DESKTOP_FILE_KEY_DESKTOP, &error)) { - g_warning("Unable to use keyfile '%s' as there is no key '" DESKTOP_FILE_KEY_DESKTOP "' in the group '" DESKTOP_FILE_GROUP "' because: %s", definition_file, error == NULL ? "unknown" : error->message); - g_error_free(error); - g_key_file_free(keyfile); - return NULL; + else { + if (show_chat) + g_menu_insert_section (menu, 0, NULL, chat_section); } - - gchar * desktopfile = g_key_file_get_string(keyfile, DESKTOP_FILE_GROUP, DESKTOP_FILE_KEY_DESKTOP, &error); - g_key_file_free(keyfile); - return desktopfile; } -/* Check if path is a symlink and return its target if it is */ -static gchar * -get_symlink_target (const gchar *path) +static AppSection * +add_application (const gchar *desktop_id) { - GFile *file; - GFileInfo *fileinfo; - gchar *target = NULL; - - file = g_file_new_for_path (path); + GDesktopAppInfo *appinfo; + gchar *id; + AppSection *section; - fileinfo = g_file_query_info (file, "standard::is-symlink", - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - NULL, NULL); - g_object_unref (file); - - if (!fileinfo) + appinfo = g_desktop_app_info_new (desktop_id); + if (!appinfo) { + g_warning ("could not add '%s', there's no desktop file with that id", desktop_id); return NULL; + } - if (g_file_info_get_is_symlink (fileinfo)) - target = g_strdup (g_file_info_get_symlink_target (fileinfo)); + id = g_app_info_get_simple_id (G_APP_INFO (appinfo)); + section = g_hash_table_lookup (applications, id); - g_object_unref (fileinfo); - return target; -} + if (!section) { + GMenuItem *menuitem; -/* Add a definition file into the black list and eclipse - any launchers that have the same file. */ -static gboolean -blacklist_add (gpointer udata) -{ - gchar * definition_file = (gchar *)udata; - gchar * symlink_target = get_symlink_target (definition_file); - gchar * contents = NULL; + section = app_section_new(appinfo); + g_hash_table_insert (applications, g_strdup (id), section); - if (symlink_target) - { - blacklist_add_core (symlink_target, definition_file); - g_free (symlink_target); - } - else if (g_str_has_suffix (definition_file, ".desktop")) - { - blacklist_add_core(definition_file, definition_file); - } - else if (g_file_get_contents (definition_file, &contents, NULL, NULL)) - { - gchar *trimmed = pango_trim_string (contents); - blacklist_add_core (trimmed, definition_file); - g_free (trimmed); - g_free (contents); + g_action_muxer_insert (action_muxer, id, app_section_get_actions (section)); + g_signal_connect (section, "notify::actions", + G_CALLBACK (actions_changed), NULL); + g_signal_connect (section, "notify::draws-attention", + G_CALLBACK (draws_attention_changed), NULL); + g_signal_connect (section, "notify::uses-chat-status", + G_CALLBACK (uses_chat_status_changed), NULL); + + /* TODO insert it at the right position (alphabetically by application name) */ + menuitem = g_menu_item_new_section (NULL, app_section_get_menu (section)); + g_menu_item_set_attribute (menuitem, "action-namespace", "s", id); + g_menu_insert_item (menu, g_menu_model_get_n_items (G_MENU_MODEL (menu)) -1, menuitem); + g_object_unref (menuitem); } - else - g_warning ("invalid blacklist entry: %s", definition_file); - return FALSE; + g_free (id); + g_object_unref (appinfo); + return section; } -/* This takes a desktop file and tries to add it to the black - list for applications in the messaging menu. If it can, - then the launcher item gets marked as eclipsed and hidden - from the user. */ static void -blacklist_add_core (gchar * desktop, gchar * definition) +remove_application (const char *desktop_id) { - gchar *basename = g_path_get_basename(desktop); - - /* Check for conflicts */ - gpointer data = g_hash_table_lookup(blacklist, basename); - if (data != NULL) { - gchar * oldfile = (gchar *)data; - if (!g_strcmp0(oldfile, definition)) { - g_warning("Already added file '%s'", oldfile); - } else { - g_warning("Already have desktop file '%s' in blacklist file '%s' not adding from '%s'", desktop, oldfile, definition); - } - - g_free(basename); - return; - } + GDesktopAppInfo *appinfo; + gchar *id; + AppSection *section; - /* Actually blacklist this thing */ - g_hash_table_insert(blacklist, g_strdup(basename), g_strdup(definition)); - g_debug("Adding Blacklist item '%s' for desktop '%s'", definition, desktop); - - /* Go through and eclipse folks */ - GList * launcher; - for (launcher = launcherList; launcher != NULL; launcher = launcher->next) { - launcherList_t * item = (launcherList_t *)launcher->data; - gchar * item_basename = g_path_get_basename(launcher_menu_item_get_desktop(item->menuitem)); - if (!g_strcmp0(basename, item_basename)) { - launcher_menu_item_set_eclipsed(item->menuitem, TRUE); - dbusmenu_menuitem_property_set_bool(item->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); - } - g_free(item_basename); + appinfo = g_desktop_app_info_new (desktop_id); + if (!appinfo) { + g_warning ("could not remove '%s', there's no desktop file with that id", desktop_id); + return; } - check_hidden(); - /* Shouldn't need a resort here as hiding shouldn't cause things to - move other than this item disappearing. */ + id = g_app_info_get_simple_id (G_APP_INFO (appinfo)); - g_free(basename); - return; -} + section = g_hash_table_lookup (applications, id); + if (section) { + int pos = g_menu_find_section (menu, app_section_get_menu (section)); + if (pos >= 0) + g_menu_remove (menu, pos); + g_action_muxer_remove (action_muxer, id); -/* Remove a black list item based on the definition file - and uneclipse those launchers blocked by it. */ -static gboolean -blacklist_remove (gpointer data) -{ - gchar * definition_file = (gchar *)data; - g_debug("Removing: %s", definition_file); - - GHashTableIter iter; - gpointer key, value; - gboolean found = FALSE; - - g_hash_table_iter_init(&iter, blacklist); - while (g_hash_table_iter_next(&iter, &key, &value)) { - if (!g_strcmp0((gchar *)value, definition_file)) { - found = TRUE; - break; - } + g_signal_handlers_disconnect_by_func (section, actions_changed, NULL); + g_signal_handlers_disconnect_by_func (section, draws_attention_changed, NULL); + g_signal_handlers_disconnect_by_func (section, uses_chat_status_changed, NULL); } - - if (!found) { - g_debug("\tNot found!"); - return FALSE; + else { + g_warning ("could not remove '%s', it's not registered", desktop_id); } - - GList * launcheritem; - for (launcheritem = launcherList; launcheritem != NULL; launcheritem = launcheritem->next) { - launcherList_t * li = (launcherList_t *)launcheritem->data; - if (!g_strcmp0(launcher_menu_item_get_desktop(li->menuitem), (gchar *)key)) { - GList * serveritem; - for (serveritem = serverList; serveritem != NULL; serveritem = serveritem->next) { - serverList_t * si = (serverList_t *)serveritem->data; - if (!g_strcmp0(app_menu_item_get_desktop(si->menuitem), (gchar *)key)) { - break; - } - } - if (serveritem == NULL) { - launcher_menu_item_set_eclipsed(li->menuitem, FALSE); - dbusmenu_menuitem_property_set_bool(li->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); - } - } - } - - if (!g_hash_table_remove(blacklist, key)) { - g_warning("Unable to remove '%s' with value '%s'", definition_file, (gchar *)key); - } - - check_hidden(); - resort_menu(root_menuitem); - - return FALSE; + + g_hash_table_remove (applications, id); + g_free (id); + g_object_unref (appinfo); } -/* Check to see if a particular desktop file is - in the blacklist. */ +/* This function turns a specific desktop id into a menu + item and registers it appropriately with everyone */ static gboolean -blacklist_check (const gchar * desktop_file) +build_launcher (gpointer data) { - gchar *basename = g_path_get_basename(desktop_file); - gboolean found; + gchar *desktop_id = data; - g_debug("Checking blacklist for: %s", basename); + add_application (desktop_id); - if (blacklist && g_hash_table_lookup(blacklist, basename)) { - g_debug("\tFound!"); - found = TRUE; - } - else - found = FALSE; - - g_free(basename); - return found; -} - -/* A callback everytime the blacklist directory changes - in some way. It needs to handle that. */ -static void -blacklist_dir_changed (GFileMonitor * monitor, GFile * file, GFile * other_file, GFileMonitorEvent event_type, gpointer user_data) -{ - g_debug("Blacklist directory changed!"); - - switch (event_type) { - case G_FILE_MONITOR_EVENT_DELETED: { - gchar * path = g_file_get_path(file); - g_debug("\tDelete: %s", path); - g_idle_add(blacklist_remove, path); - break; - } - case G_FILE_MONITOR_EVENT_CREATED: { - gchar * path = g_file_get_path(file); - g_debug("\tCreate: %s", path); - g_idle_add(blacklist_add, path); - break; - } - default: - break; - } - - return; + g_free (desktop_id); + return FALSE; } -/* - * More code - */ - -/* Goes through all the servers and sees if any of them - want attention. If they do, then well we'll give it - to them. If they don't, let's not bother the user - any, shall we? */ -static void -check_attention (void) +/* This function goes through all the launchers that we're + supposed to be grabbing and decides to show turn them + into menu items or not. It doens't do the work, but it + makes the decision. */ +static gboolean +build_launchers (gpointer data) { - GList * pointer; - for (pointer = serverList; pointer != NULL; pointer = g_list_next(pointer)) { - serverList_t * slt = (serverList_t *)pointer->data; - if (slt->attention) { - message_service_dbus_set_attention(dbus_interface, TRUE); - return; - } - } - message_service_dbus_set_attention(dbus_interface, FALSE); - return; -} + gchar **applications = g_settings_get_strv (settings, "applications"); + gchar **app; -/* This checks a server listing to see if it should - have attention. It can get attention through it's - count or by having an indicator that is requestion - attention. */ -static void -server_attention (serverList_t * slt) -{ - /* Count, easy yes and out. */ - if (slt->count > 0) { - slt->attention = TRUE; - return; - } + g_return_val_if_fail (applications != NULL, FALSE); - /* Check to see if any of the indicators want attention */ - GList * pointer; - for (pointer = slt->imList; pointer != NULL; pointer = g_list_next(pointer)) { - imList_t * ilt = (imList_t *)pointer->data; - if (im_menu_item_get_attention(IM_MENU_ITEM(ilt->menuitem))) { - slt->attention = TRUE; - return; - } + for (app = applications; *app; app++) + { + g_idle_add(build_launcher, g_strdup (*app)); } - /* Nope, no one */ - slt->attention = FALSE; - return; + g_strfreev (applications); + return FALSE; } -/* A new server has been created on the indicate bus. - We need to check to see if we like it. And build - structures for it if so. */ static void -server_added (IndicateListener * listener, IndicateListenerServer * server, gchar * type, gpointer data) -{ - g_debug("Server Added '%s' of type '%s'.", INDICATE_LISTENER_SERVER_DBUS_NAME(server), type); - if (type == NULL) { - return; - } - - if (type[0] == '\0') { - return; - } - - if (strncmp(type, "message", strlen("message"))) { - g_debug("\tServer type '%s' is not a message based type.", type); - return; - } - - DbusmenuMenuitem * menushell = DBUSMENU_MENUITEM(data); - if (menushell == NULL) { - g_error("\tData in callback is not a menushell"); - return; - } - - /* Build the Menu item */ - AppMenuItem * menuitem = app_menu_item_new(listener, server); - - /* Build a possible server structure */ - serverList_t * sl_item = g_new0(serverList_t, 1); - sl_item->server = server; - sl_item->menuitem = menuitem; - sl_item->imList = NULL; - sl_item->attention = FALSE; - sl_item->count = 0; - - /* Incase we got an indicator first */ - GList * alreadythere = g_list_find_custom(serverList, sl_item, serverList_equal); - if (alreadythere != NULL) { - /* Use the one we already had */ - g_free(sl_item); - sl_item = (serverList_t *)alreadythere->data; - sl_item->menuitem = menuitem; - serverList = g_list_sort(serverList, serverList_sort); - } else { - /* Insert the new one in the list */ - serverList = g_list_insert_sorted(serverList, sl_item, serverList_sort); - } - - /* Build a separator */ - sl_item->separator = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(sl_item->separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); - - /* Connect the signals up to the menu item */ - g_signal_connect(G_OBJECT(menuitem), APP_MENU_ITEM_SIGNAL_COUNT_CHANGED, G_CALLBACK(server_count_changed), sl_item); - g_signal_connect(G_OBJECT(menuitem), APP_MENU_ITEM_SIGNAL_NAME_CHANGED, G_CALLBACK(server_name_changed), menushell); - g_signal_connect(G_OBJECT(menuitem), APP_MENU_ITEM_SIGNAL_SHORTCUT_ADDED, G_CALLBACK(server_shortcut_added), menushell); - g_signal_connect(G_OBJECT(menuitem), APP_MENU_ITEM_SIGNAL_SHORTCUT_REMOVED, G_CALLBACK(server_shortcut_removed), menushell); - - /* Put our new menu item in, with the separator behind it. - resort_menu will take care of whether it should be hidden - or not. */ - dbusmenu_menuitem_child_append(menushell, DBUSMENU_MENUITEM(menuitem)); - - GList * shortcuts = app_menu_item_get_items(sl_item->menuitem); - while (shortcuts != NULL) { - DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(shortcuts->data); - g_debug("\tAdding shortcut: %s", dbusmenu_menuitem_property_get(mi, DBUSMENU_MENUITEM_PROP_LABEL)); - dbusmenu_menuitem_child_append(menushell, mi); - shortcuts = g_list_next(shortcuts); - } - - dbusmenu_menuitem_child_append(menushell, DBUSMENU_MENUITEM(sl_item->separator)); - - resort_menu(menushell); - check_hidden(); - - return; -} - -/* Server shortcut has been added */ -static void -server_shortcut_added (AppMenuItem * appitem, DbusmenuMenuitem * mi, gpointer data) -{ - g_debug("Application Shortcut added: %s", mi != NULL ? dbusmenu_menuitem_property_get(mi, DBUSMENU_MENUITEM_PROP_LABEL) : "none"); - DbusmenuMenuitem * shell = DBUSMENU_MENUITEM(data); - if (mi != NULL) { - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_ICON_NAME, DBUSMENU_MENUITEM_ICON_NAME_BLANK); - dbusmenu_menuitem_child_append(shell, mi); - } - resort_menu(shell); - return; -} - -/* Server shortcut has been removed */ -static void -server_shortcut_removed (AppMenuItem * appitem, DbusmenuMenuitem * mi, gpointer data) +service_shutdown (IndicatorService * service, gpointer user_data) { - g_debug("Application Shortcut removed: %s", mi != NULL ? dbusmenu_menuitem_property_get(mi, DBUSMENU_MENUITEM_PROP_LABEL) : "none"); - DbusmenuMenuitem * shell = DBUSMENU_MENUITEM(data); - dbusmenu_menuitem_child_delete(shell, mi); - return; -} + GMainLoop *mainloop = user_data; -/* The name of a server has changed, we probably - need to reorder the menu to keep it in alphabetical - order. This happens often after we read the destkop - file from disk. */ -static void -server_name_changed (AppMenuItem * appitem, gchar * name, gpointer data) -{ - serverList = g_list_sort(serverList, serverList_sort); - check_eclipses(appitem); - resort_menu(DBUSMENU_MENUITEM(data)); - return; + g_warning("Shutting down service!"); + g_main_loop_quit(mainloop); } -/* If the count on the server changes, we need to know - whether that should be grabbing attention or not. If - it is, we need to reevaluate whether the whole thing - should be grabbing attention or not. */ static void -server_count_changed (AppMenuItem * appitem, guint count, gpointer data) +app_section_remove_attention (gpointer key, + gpointer value, + gpointer user_data) { - serverList_t * slt = (serverList_t *)data; - slt->count = count; - - if (count == 0 && slt->attention) { - /* Regen based on indicators if the count isn't going to cause it. */ - server_attention(slt); - /* If we're dropping let's see if we're the last. */ - if (!slt->attention) { - check_attention(); - } - } - - if (count != 0 && !slt->attention) { - slt->attention = TRUE; - /* Let's tell everyone about us! */ - message_service_dbus_set_attention(dbus_interface, TRUE); - } - - return; + AppSection *section = value; + app_section_clear_draws_attention (section); } -/* Respond to the IM entrie's time changing - which results in it needing to resort the list - and rebuild the menu to match. */ static void -im_time_changed (ImMenuItem * imitem, glong seconds, gpointer data) +clear_action_activate (GSimpleAction *simple, + GVariant *param, + gpointer user_data) { - serverList_t * sl = (serverList_t *)data; - sl->imList = g_list_sort(sl->imList, imList_sort); - resort_menu(root_menuitem); - return; + g_hash_table_foreach (applications, app_section_remove_attention, NULL); } -/* The IM entrie's request for attention has changed - so we need to pass that up the stack. */ static void -im_attention_changed (ImMenuItem * imitem, gboolean requestit, gpointer data) +radio_item_activate (GSimpleAction *action, + GVariant *parameter, + gpointer user_data) { - serverList_t * sl = (serverList_t *)data; - - if (requestit) { - sl->attention = TRUE; - message_service_dbus_set_attention(dbus_interface, TRUE); - } else { - server_attention(sl); - if (!sl->attention) { - check_attention(); - } - } - - return; + g_action_change_state (G_ACTION (action), parameter); } -/* Run when a server is removed from the indicator bus. It figures - out if we have it somewhere, and if so then we dump it out and - clean up all of it's entries. */ -static void -server_removed (IndicateListener * listener, IndicateListenerServer * server, gchar * type, gpointer data) +static gboolean +g_action_state_equal (GAction *action, + GVariant *value) { - /* Look for the server */ - g_debug("Removing server: %s", INDICATE_LISTENER_SERVER_DBUS_NAME(server)); - serverList_t slt = {0}; - slt.server = server; - GList * lookup = g_list_find_custom(serverList, &slt, serverList_equal); - - /* If we don't have it, exit */ - if (lookup == NULL) { - g_debug("\tUnable to find server: %s", INDICATE_LISTENER_SERVER_DBUS_NAME(server)); - return; - } - - serverList_t * sltp = (serverList_t *)lookup->data; - - /* Removing indicators from this server */ - while (sltp->imList) { - imList_t * imitem = (imList_t *)sltp->imList->data; - indicator_removed(listener, server, imitem->indicator, data); - } + GVariant *state; + gboolean eq; - /* Remove from the server list */ - serverList = g_list_remove(serverList, sltp); - - /* Remove launchers this could be eclipsing */ - remove_eclipses(sltp->menuitem); - - /* If there is a menu item, let's get rid of it. */ - if (sltp->menuitem != NULL) { - /* If there are shortcuts remove them */ - GList * shortcuts = app_menu_item_get_items(sltp->menuitem); - while (shortcuts != NULL) { - g_debug("\tRemoving shortcut: %s", dbusmenu_menuitem_property_get(DBUSMENU_MENUITEM(shortcuts->data), DBUSMENU_MENUITEM_PROP_LABEL)); - dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(shortcuts->data), DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); - dbusmenu_menuitem_child_delete(DBUSMENU_MENUITEM(data), DBUSMENU_MENUITEM(shortcuts->data)); - shortcuts = g_list_next(shortcuts); - } - - g_debug("\tRemoving item"); - dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(sltp->menuitem), DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); - dbusmenu_menuitem_child_delete(DBUSMENU_MENUITEM(data), DBUSMENU_MENUITEM(sltp->menuitem)); - g_object_unref(G_OBJECT(sltp->menuitem)); - } else { - g_debug("\tNo menuitem"); - } - - /* If there is a separator, let's get rid of it. */ - if (sltp->separator != NULL) { - g_debug("\tRemoving separator"); - dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(sltp->separator), DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); - dbusmenu_menuitem_child_delete(DBUSMENU_MENUITEM(data), DBUSMENU_MENUITEM(sltp->separator)); - g_object_unref(G_OBJECT(sltp->separator)); - } else { - g_debug("\tNo separator"); - } - - if (sltp->attention) { - /* Check to see if this was the server causing the menu item to - be lit up. */ - check_attention(); - } + state = g_action_get_state (action); + g_return_val_if_fail (state != NULL, FALSE); - g_free(sltp); + eq = g_variant_equal (state, value); - check_hidden(); - - return; + g_variant_unref (state); + return eq; } -typedef struct _menushell_location menushell_location_t; -struct _menushell_location { - const IndicateListenerServer * server; - gint position; - gboolean found; -}; - static void -menushell_foreach_cb (DbusmenuMenuitem * data_mi, gpointer data_ms) { - menushell_location_t * msl = (menushell_location_t *)data_ms; - - if (msl->found) return; - - if (!IS_APP_MENU_ITEM(data_mi)) { - msl->position++; - return; - } - - AppMenuItem * appmenu = APP_MENU_ITEM(data_mi); - if (!g_strcmp0(INDICATE_LISTENER_SERVER_DBUS_NAME((IndicateListenerServer*)msl->server), INDICATE_LISTENER_SERVER_DBUS_NAME(app_menu_item_get_server(appmenu)))) { - msl->found = TRUE; - /* Return a position at the end of our shortcuts */ - msl->position += g_list_length(app_menu_item_get_items(appmenu)); - } else { - msl->position++; - } - - return; -} - -static void -check_hidden (void) +change_status_action (GSimpleAction *action, + GVariant *value, + gpointer user_data) { - g_debug("Checking Hidden..."); - gboolean hide = FALSE; - if (launcherList_count() == 0) { - g_debug("\tZero Launchers"); - /* If we don't have visible launchers we need to look more */ - if (g_list_length(serverList) == 0) { - g_debug("\tZero Applications"); - hide = TRUE; - } - } + const gchar *status; - message_service_dbus_set_icon(dbus_interface, hide); - return; -} + g_variant_get (value, "&s", &status); -/* This function takes care of putting the menu in the right order. - It basically it rebuilds the order by looking through all the - applications and launchers and puts them in the right place. The - menu functions will handle the cases where they don't move so this - is a good way to ensure everything is right. */ -static void -resort_menu (DbusmenuMenuitem * menushell) -{ - guint position = 0; - GList * serverentry; - GList * launcherentry = launcherList; - - g_debug("Reordering Menu:"); - - if (DBUSMENU_IS_MENUITEM(status_separator)) { - position = dbusmenu_menuitem_get_position(status_separator, root_menuitem) + 1; - g_debug("\tPriming with location of status separator: %d", position); - } + g_return_if_fail (g_str_equal (status, "available") || + g_str_equal (status, "away")|| + g_str_equal (status, "busy") || + g_str_equal (status, "invisible") || + g_str_equal (status, "offline")); - for (serverentry = serverList; serverentry != NULL; serverentry = serverentry->next) { - serverList_t * si = (serverList_t *)serverentry->data; - - /* Looking to see if there are any launchers we need to insert - into the menu structure. We put as many as we need to. */ - if (launcherentry != NULL) { - launcherList_t * li = (launcherList_t *)launcherentry->data; - while (launcherentry != NULL && g_strcmp0(launcher_menu_item_get_name(li->menuitem), app_menu_item_get_name(si->menuitem)) < 0) { - /* Putting the launcher item in */ - g_debug("\tMoving launcher '%s' to position %d", launcher_menu_item_get_name(li->menuitem), position); - dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(menushell), DBUSMENU_MENUITEM(li->menuitem), position); - position++; - - /* Inserting the shortcuts from the launcher */ - GList * shortcuts = launcher_menu_item_get_items(li->menuitem); - while (shortcuts != NULL) { - g_debug("\t\tMoving shortcut to position %d", position); - dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(menushell), DBUSMENU_MENUITEM(shortcuts->data), position); - position++; - shortcuts = g_list_next(shortcuts); - } - - /* Putting the launcher separator in */ - g_debug("\tMoving launcher separator to position %d", position); - dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(menushell), DBUSMENU_MENUITEM(li->separator), position); - if (!launcher_menu_item_get_eclipsed(li->menuitem)) { - /* Only clear the visiblity if we're not eclipsed */ - dbusmenu_menuitem_property_set_bool(li->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); - } - position++; - - launcherentry = launcherentry->next; - if (launcherentry != NULL) { - li = (launcherList_t *)launcherentry->data; - } - } - } - - /* Putting the app menu item in */ - if (si->menuitem != NULL) { - g_debug("\tMoving app %s to position %d", INDICATE_LISTENER_SERVER_DBUS_NAME(si->server), position); - dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(menushell), DBUSMENU_MENUITEM(si->menuitem), position); - position++; - - /* Inserting the shortcuts from the launcher */ - GList * shortcuts = app_menu_item_get_items(si->menuitem); - while (shortcuts != NULL) { - g_debug("\t\tMoving shortcut to position %d", position); - dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(menushell), DBUSMENU_MENUITEM(shortcuts->data), position); - position++; - shortcuts = g_list_next(shortcuts); - } - } - - /* Putting all the indicators that are related to this application - after it. */ - GList * imentry; - for (imentry = si->imList; imentry != NULL; imentry = imentry->next) { - imList_t * imi = (imList_t *)imentry->data; - - if (imi->menuitem != NULL) { - g_debug("\tMoving indicator on %s id %d to position %d", INDICATE_LISTENER_SERVER_DBUS_NAME(imi->server), INDICATE_LISTENER_INDICATOR_ID(imi->indicator), position); - - if (si->menuitem == NULL || !dbusmenu_menuitem_property_get_bool(DBUSMENU_MENUITEM(si->menuitem), DBUSMENU_MENUITEM_PROP_VISIBLE)) { - dbusmenu_menuitem_property_set_bool(imi->menuitem, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); - } else { - dbusmenu_menuitem_property_set_bool(imi->menuitem, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); - } - - dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(menushell), DBUSMENU_MENUITEM(imi->menuitem), position); - position++; - } - } - - /* Lastly putting the separator in */ - if (si->separator != NULL) { - g_debug("\tMoving app %s separator to position %d", INDICATE_LISTENER_SERVER_DBUS_NAME(si->server), position); - - if (si->menuitem == NULL || !dbusmenu_menuitem_property_get_bool(DBUSMENU_MENUITEM(si->menuitem), DBUSMENU_MENUITEM_PROP_VISIBLE)) { - dbusmenu_menuitem_property_set_bool(si->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); - /* Note, this isn't the last if we can't see it */ - } else { - dbusmenu_menuitem_property_set_bool(si->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); - } - - dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(menushell), DBUSMENU_MENUITEM(si->separator), position); - position++; - } + if (!g_action_state_equal (G_ACTION (action), value)) { + g_message ("%s", status); + g_simple_action_set_state (action, value); + indicator_messages_service_emit_status_changed (messages_service, status); } - - /* Put any leftover launchers in at the end of the list. */ - while (launcherentry != NULL) { - launcherList_t * li = (launcherList_t *)launcherentry->data; - - /* Putting the launcher in */ - g_debug("\tMoving launcher '%s' to position %d", launcher_menu_item_get_name(li->menuitem), position); - dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(menushell), DBUSMENU_MENUITEM(li->menuitem), position); - position++; - - /* Inserting the shortcuts from the launcher */ - GList * shortcuts = launcher_menu_item_get_items(li->menuitem); - while (shortcuts != NULL) { - g_debug("\t\tMoving shortcut to position %d", position); - dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(menushell), DBUSMENU_MENUITEM(shortcuts->data), position); - position++; - shortcuts = g_list_next(shortcuts); - } - - /* Putting the launcher separator in */ - g_debug("\tMoving launcher separator to position %d", position); - dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(menushell), DBUSMENU_MENUITEM(li->separator), position); - if (!launcher_menu_item_get_eclipsed(li->menuitem)) { - /* Only clear the visiblity if we're not eclipsed */ - dbusmenu_menuitem_property_set_bool(li->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); - } - position++; - - launcherentry = launcherentry->next; - } - - if (clear_attention != NULL) { - dbusmenu_menuitem_child_reorder(DBUSMENU_MENUITEM(menushell), clear_attention, position); - position++; /* Not needed, but reduce bugs on code tacked on here, compiler will remove */ - } - - return; } -/* Responding to a new indicator showing up on the bus. We - need to create a menuitem for it and start populating the - internal structures to track it. */ static void -indicator_added (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gpointer data) -{ - DbusmenuMenuitem * menushell = DBUSMENU_MENUITEM(data); - if (menushell == NULL) { - g_error("Data in callback is not a menushell"); +register_application (IndicatorMessagesService *service, + GDBusMethodInvocation *invocation, + const gchar *desktop_id, + const gchar *menu_path, + gpointer user_data) +{ + AppSection *section; + GDBusConnection *bus; + const gchar *sender; + + section = add_application (desktop_id); + if (!section) return; - } - imList_t * listItem = g_new0(imList_t, 1); - listItem->server = server; - listItem->indicator = indicator; - - /* Building the IM Menu Item which is a subclass - of DBus Menuitem */ - ImMenuItem * menuitem = im_menu_item_new(listener, server, indicator); - listItem->menuitem = DBUSMENU_MENUITEM(menuitem); - - /* Looking for a server entry to attach this indicator - to. If we can't find one then we have to build one - and attach the indicator to it. */ - serverList_t sl_item_local = {0}; - serverList_t * sl_item = NULL; - sl_item_local.server = server; - GList * serverentry = g_list_find_custom(serverList, &sl_item_local, serverList_equal); - - if (serverentry == NULL) { - /* This sucks, we got an indicator before the server. I guess - that's the joy of being asynchronous */ - sl_item = g_new0(serverList_t, 1); - sl_item->server = server; - sl_item->menuitem = NULL; - sl_item->imList = NULL; - sl_item->attention = FALSE; - sl_item->count = 0; - sl_item->separator = NULL; - - serverList = g_list_insert_sorted(serverList, sl_item, serverList_sort); - } else { - sl_item = (serverList_t *)serverentry->data; - } + bus = g_dbus_interface_skeleton_get_connection (G_DBUS_INTERFACE_SKELETON (service)); + sender = g_dbus_method_invocation_get_sender (invocation); - /* Added a this entry into the IM list */ - sl_item->imList = g_list_insert_sorted(sl_item->imList, listItem, imList_sort); - listItem->timechange_cb = g_signal_connect(G_OBJECT(menuitem), IM_MENU_ITEM_SIGNAL_TIME_CHANGED, G_CALLBACK(im_time_changed), sl_item); - listItem->attentionchange_cb = g_signal_connect(G_OBJECT(menuitem), IM_MENU_ITEM_SIGNAL_ATTENTION_CHANGED, G_CALLBACK(im_attention_changed), sl_item); - - /* Check the length of the list. If we've got more inidactors - than we allow. Well. Someone's gotta pay. Sorry. I didn't - want to do this, but you did it to yourself. */ - if (g_list_length(sl_item->imList) > MAX_NUMBER_OF_INDICATORS) { - GList * indicatoritem; - gint count; - for (indicatoritem = sl_item->imList, count = 0; indicatoritem != NULL; indicatoritem = g_list_next(indicatoritem), count++) { - imList_t * im = (imList_t *)indicatoritem->data; - im_menu_item_show(IM_MENU_ITEM(im->menuitem), count < MAX_NUMBER_OF_INDICATORS); - } - } + app_section_set_object_path (section, bus, sender, menu_path); + g_settings_strv_append_unique (settings, "applications", desktop_id); - /* Placing the item into the shell. Look to see if - we can find our server and slip in there. Otherwise - we'll just append. */ - menushell_location_t msl; - msl.found = FALSE; - msl.position = 0; - msl.server = server; - - dbusmenu_menuitem_foreach(DBUSMENU_MENUITEM(menushell), menushell_foreach_cb, &msl); - if (msl.found) { - dbusmenu_menuitem_child_add_position(menushell, DBUSMENU_MENUITEM(menuitem), msl.position); - } else { - g_warning("Unable to find server menu item"); - dbusmenu_menuitem_child_append(menushell, DBUSMENU_MENUITEM(menuitem)); - resort_menu (root_menuitem); - } - - return; + indicator_messages_service_complete_register_application (service, invocation); } -/* Process and indicator getting removed from the system. We - first need to ensure that it's one of ours and figure out - where we put it. When we find all that out we can go through - the process of removing the effect it had on the system. */ static void -indicator_removed (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gpointer data) +unregister_application (IndicatorMessagesService *service, + GDBusMethodInvocation *invocation, + const gchar *desktop_id, + gpointer user_data) { - g_debug("Removing %s %d", INDICATE_LISTENER_SERVER_DBUS_NAME(server), INDICATE_LISTENER_INDICATOR_ID(indicator)); - - gboolean removed = FALSE; + remove_application (desktop_id); + g_settings_strv_remove (settings, "applications", desktop_id); - /* Find the server that was related to this item */ - serverList_t sl_item_local = {0}; - serverList_t * sl_item = NULL; - sl_item_local.server = server; - GList * serverentry = g_list_find_custom(serverList, &sl_item_local, serverList_equal); - if (serverentry == NULL) { - /* We didn't care about that server */ - return; - } - sl_item = (serverList_t *)serverentry->data; - - /* Look in the IM Hash Table */ - imList_t listData = {0}; - listData.server = server; - listData.indicator = indicator; - - GList * listItem = g_list_find_custom(sl_item->imList, &listData, imList_equal); - DbusmenuMenuitem * menuitem = NULL; - imList_t * ilt = NULL; - if (listItem != NULL) { - ilt = (imList_t *)listItem->data; - menuitem = ilt->menuitem; - } - - /* If we found a menu item and an imList_t item then - we can go ahead and remove it. Otherwise we can - skip this and exit. */ - if (!removed && menuitem != NULL) { - sl_item->imList = g_list_remove(sl_item->imList, ilt); - g_signal_handler_disconnect(menuitem, ilt->timechange_cb); - g_signal_handler_disconnect(menuitem, ilt->attentionchange_cb); - g_free(ilt); - - if (im_menu_item_get_attention(IM_MENU_ITEM(menuitem)) && im_menu_item_shown(IM_MENU_ITEM(menuitem))) { - /* If the removed indicator menu item was asking for - attention we need to see if this server should still - be asking for attention. */ - server_attention(sl_item); - /* If the server is no longer asking for attention then - we need to check if the whole system should be. */ - if (!sl_item->attention) { - check_attention(); - } - } - - if (im_menu_item_shown(IM_MENU_ITEM(menuitem)) && g_list_length(sl_item->imList) >= MAX_NUMBER_OF_INDICATORS) { - /* In this case we need to show a different indicator - becasue a shown one has left. But we're going to be - easy and set all the values. */ - GList * indicatoritem; - gint count; - for (indicatoritem = sl_item->imList, count = 0; indicatoritem != NULL; indicatoritem = g_list_next(indicatoritem), count++) { - imList_t * im = (imList_t *)indicatoritem->data; - im_menu_item_show(IM_MENU_ITEM(im->menuitem), count < MAX_NUMBER_OF_INDICATORS); - } - } - - /* Hide the item immediately, and then remove it - which might take a little longer. */ - dbusmenu_menuitem_property_set_bool(menuitem, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); - dbusmenu_menuitem_child_delete(DBUSMENU_MENUITEM(data), menuitem); - removed = TRUE; - } - - if (!removed) { - g_warning("We were asked to remove %s %d but we didn't.", INDICATE_LISTENER_SERVER_DBUS_NAME(server), INDICATE_LISTENER_INDICATOR_ID(indicator)); - } - - return; + indicator_messages_service_complete_unregister_application (service, invocation); } static void -app_dir_changed (GFileMonitor * monitor, GFile * file, GFile * other_file, GFileMonitorEvent event_type, gpointer user_data) +set_status (IndicatorMessagesService *service, + GDBusMethodInvocation *invocation, + const gchar *status_str, + gpointer user_data) { - gchar * directory = (gchar *)user_data; - g_debug("Application directory changed: %s", directory); - - switch (event_type) { - case G_FILE_MONITOR_EVENT_DELETED: { - gchar * path = g_file_get_path(file); - g_debug("\tDelete: %s", path); - g_idle_add(destroy_launcher, path); - break; - } - case G_FILE_MONITOR_EVENT_CREATED: { - gchar * path = g_file_get_path(file); - g_debug("\tCreate: %s", path); - if (g_str_has_suffix(path, "keyfile")) { - g_idle_add(build_launcher_keyfile, path); - } else { - g_idle_add(build_launcher, path); - } - break; - } - default: - break; - } + GAction *status; - return; -} + status = g_simple_action_group_lookup (actions, "status"); + g_return_if_fail (status != NULL); -/* Check to see if a new desktop file causes - any of the launchers to be eclipsed by a running - process */ -static void -check_eclipses (AppMenuItem * ai) -{ - g_debug("Checking eclipsing"); - const gchar * aidesktop = app_menu_item_get_desktop(ai); - if (aidesktop == NULL) return; - g_debug("\tApp desktop: %s", aidesktop); - - GList * llitem; - for (llitem = launcherList; llitem != NULL; llitem = llitem->next) { - launcherList_t * ll = (launcherList_t *)llitem->data; - const gchar * lidesktop = launcher_menu_item_get_desktop(ll->menuitem); - g_debug("\tLauncher desktop: %s", lidesktop); - - if (!g_strcmp0(aidesktop, lidesktop)) { - launcher_menu_item_set_eclipsed(ll->menuitem, TRUE); - dbusmenu_menuitem_property_set_bool(ll->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); - break; - } - } + g_action_change_state (status, g_variant_new_string (status_str)); - return; + indicator_messages_service_complete_set_status (service, invocation); } -/* Remove any eclipses that might have been caused - by this app item that is now retiring */ -static void -remove_eclipses (AppMenuItem * ai) +static GSimpleActionGroup * +create_action_group (void) { - const gchar * aidesktop = app_menu_item_get_desktop(ai); - if (aidesktop == NULL) return; - - if (blacklist_check(aidesktop)) return; - - GList * llitem; - for (llitem = launcherList; llitem != NULL; llitem = llitem->next) { - launcherList_t * ll = (launcherList_t *)llitem->data; - const gchar * lidesktop = launcher_menu_item_get_desktop(ll->menuitem); - - if (!g_strcmp0(aidesktop, lidesktop)) { - launcher_menu_item_set_eclipsed(ll->menuitem, FALSE); - dbusmenu_menuitem_property_set_bool(ll->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); - break; - } - } + GSimpleActionGroup *actions; + GSimpleAction *messages; + GSimpleAction *clear; + GSimpleAction *status; - return; -} - -/* Remove a launcher from the system. We need to figure - out what it's up to! */ -static gboolean -destroy_launcher (gpointer data) -{ - gchar * appdirentry = (gchar *)data; - - GList * listitem; - GList * direntry; - launcherList_t * li; - gchar * appdir; - - for (listitem = launcherList; listitem != NULL; listitem = listitem->next) { - li = (launcherList_t *)listitem->data; - for (direntry = li->appdiritems; direntry != NULL; direntry = direntry->next) { - appdir = (gchar *)direntry->data; - if (!g_strcmp0(appdir, appdirentry)) { - break; - } - } - - if (direntry != NULL) { - break; - } - } + actions = g_simple_action_group_new (); - if (listitem == NULL) { - g_warning("Removed '%s' by the way of it not seeming to exist anywhere.", appdirentry); - return FALSE; - } + /* state of the messages action mirrors "draws-attention" */ + messages = g_simple_action_new_stateful ("messages", G_VARIANT_TYPE ("b"), + g_variant_new_boolean (FALSE)); - if (g_list_length(li->appdiritems) > 1) { - /* Just remove this item, and we can move on */ - g_debug("Just removing file entry: %s", appdir); - li->appdiritems = g_list_remove(li->appdiritems, appdir); - g_free(appdir); - return FALSE; - } + status = g_simple_action_new_stateful ("status", G_VARIANT_TYPE ("s"), + g_variant_new ("s", "offline")); + g_signal_connect (status, "activate", G_CALLBACK (radio_item_activate), NULL); + g_signal_connect (status, "change-state", G_CALLBACK (change_status_action), NULL); - /* Full Destroy */ - g_free(appdir); - g_list_free(li->appdiritems); - - if (li->menuitem != NULL) { - /* If there are shortcuts remove them */ - GList * shortcuts = launcher_menu_item_get_items(li->menuitem); - while (shortcuts != NULL) { - dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(shortcuts->data), DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); - dbusmenu_menuitem_child_delete(DBUSMENU_MENUITEM(data), DBUSMENU_MENUITEM(shortcuts->data)); - shortcuts = g_list_next(shortcuts); - } - - dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(li->menuitem), DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); - dbusmenu_menuitem_child_delete(root_menuitem, DBUSMENU_MENUITEM(li->menuitem)); - g_object_unref(G_OBJECT(li->menuitem)); - li->menuitem = NULL; - } + clear = g_simple_action_new ("clear", NULL); + g_simple_action_set_enabled (clear, FALSE); + g_signal_connect (clear, "activate", G_CALLBACK (clear_action_activate), NULL); - launcherList = g_list_remove(launcherList, li); - g_free(li); + g_simple_action_group_insert (actions, G_ACTION (messages)); + g_simple_action_group_insert (actions, G_ACTION (status)); + g_simple_action_group_insert (actions, G_ACTION (clear)); - return FALSE; + return actions; } -/* This function turns a specific file into a menu - item and registers it appropriately with everyone */ -static gboolean -build_launcher (gpointer data) +static GMenuModel * +create_status_section (void) { - /* Read the file get the data */ - gchar * path = (gchar *)data; - g_debug("\tpath: %s", path); - gchar * desktop = NULL; - - g_file_get_contents(path, &desktop, NULL, NULL); - - if (desktop == NULL) { - g_free(path); - return FALSE; - } + GMenu *menu; - gchar * trimdesktop = pango_trim_string(desktop); - g_free(desktop); - g_debug("\tcontents: %s", trimdesktop); + menu = g_menu_new (); + g_menu_append_with_icon_name (menu, _("Available"), "user-available", "status::available"); + g_menu_append_with_icon_name (menu, _("Away"), "user-away", "status::away"); + g_menu_append_with_icon_name (menu, _("Busy"), "user-busy", "status::busy"); + g_menu_append_with_icon_name (menu, _("Invisible"), "user-invisible", "status::invisible"); + g_menu_append_with_icon_name (menu, _("Offline"), "user-offline", "status::offline"); - build_launcher_core(trimdesktop); - g_free(trimdesktop); - g_free(path); - return FALSE; -} - -/* Use a key file to find the desktop file. */ -static gboolean -build_launcher_keyfile (gpointer data) -{ - gchar * path = (gchar *)data; - gchar * desktop = desktop_file_from_keyfile (path); - if (desktop != NULL) { - build_launcher_core(desktop); - g_free(desktop); - } - g_free(path); - return FALSE; + return G_MENU_MODEL (menu); } -/* The core action of dealing with a desktop file that should - be a launcher */ static void -build_launcher_core (const gchar * desktop) +got_bus (GObject *object, + GAsyncResult * res, + gpointer user_data) { - /* Check to see if we already have a launcher */ - GList * listitem; - for (listitem = launcherList; listitem != NULL; listitem = listitem->next) { - launcherList_t * li = (launcherList_t *)listitem->data; - if (!g_strcmp0(launcher_menu_item_get_desktop(li->menuitem), desktop)) { - break; - } - } - - if (listitem == NULL) { - /* If not */ - /* Build the item */ - launcherList_t * ll = g_new0(launcherList_t, 1); - ll->menuitem = launcher_menu_item_new(desktop); - ll->appdiritems = g_list_append(NULL, g_strdup(desktop)); - - /* Build a separator */ - ll->separator = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(ll->separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); - - /* Add it to the list */ - launcherList = g_list_insert_sorted(launcherList, ll, launcherList_sort); - - /* Add it to the menu */ - dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(ll->menuitem), DBUSMENU_MENUITEM_PROP_TYPE, APPLICATION_MENUITEM_TYPE); - dbusmenu_menuitem_child_append(root_menuitem, DBUSMENU_MENUITEM(ll->menuitem)); - GList * shortcuts = launcher_menu_item_get_items(ll->menuitem); - while (shortcuts != NULL) { - dbusmenu_menuitem_child_append(root_menuitem, DBUSMENU_MENUITEM(shortcuts->data)); - shortcuts = g_list_next(shortcuts); - } - dbusmenu_menuitem_child_append(root_menuitem, DBUSMENU_MENUITEM(ll->separator)); - - /* If we're in the black list or we've gotten eclipsed - by something else, hide the item and the separator. */ - if (blacklist_check(launcher_menu_item_get_desktop(ll->menuitem)) || - launcher_menu_item_get_eclipsed(ll->menuitem)) { - launcher_menu_item_set_eclipsed(ll->menuitem, TRUE); - dbusmenu_menuitem_property_set_bool(ll->separator, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); - } - - /* Check to see if any of the current applications should - be eclipsing us. */ - GList * server; - for (server = serverList; server != NULL; server = g_list_next(server)) { - serverList_t * slt = (serverList_t *)server->data; - check_eclipses(slt->menuitem); - } - - resort_menu(root_menuitem); - check_hidden(); - } else { - /* If so add ourselves */ - launcherList_t * ll = (launcherList_t *)listitem->data; - ll->appdiritems = g_list_append(ll->appdiritems, g_strdup(desktop)); - } - - return; -} + GDBusConnection *bus; + GError *error = NULL; -/* This function goes through all the launchers that we're - supposed to be grabbing and decides to show turn them - into menu items or not. It doens't do the work, but it - makes the decision. */ -static gboolean -build_launchers (gpointer data) -{ - gchar * directory = (gchar *)data; - - if (!g_file_test(directory, G_FILE_TEST_IS_DIR)) { - return FALSE; + bus = g_bus_get_finish (res, &error); + if (!bus) { + g_warning ("unable to connect to the session bus: %s", error->message); + g_error_free (error); + return; } - GFile * filedir = g_file_new_for_path(directory); - GFileMonitor * dirmon = g_file_monitor_directory(filedir, G_FILE_MONITOR_NONE, NULL, NULL); - if (dirmon != NULL) { - g_signal_connect(G_OBJECT(dirmon), "changed", G_CALLBACK(app_dir_changed), directory); + g_dbus_connection_export_action_group (bus, INDICATOR_MESSAGES_DBUS_OBJECT, + G_ACTION_GROUP (action_muxer), &error); + if (error) { + g_warning ("unable to export action group on dbus: %s", error->message); + g_error_free (error); + return; } - GError * error = NULL; - GDir * dir = g_dir_open(directory, 0, &error); - if (dir == NULL) { - g_warning("Unable to open system apps directory: %s", error->message); - g_error_free(error); - return FALSE; + g_dbus_connection_export_menu_model (bus, INDICATOR_MESSAGES_DBUS_OBJECT, + G_MENU_MODEL (toplevel_menu), &error); + if (error) { + g_warning ("unable to export menu on dbus: %s", error->message); + g_error_free (error); + return; } - const gchar * filename = NULL; - while ((filename = g_dir_read_name(dir)) != NULL) { - g_debug("Found file: %s", filename); - gchar * path = g_build_filename(directory, filename, NULL); - if (g_str_has_suffix(path, "keyfile")) { - g_idle_add(build_launcher_keyfile, path); - } else { - g_idle_add(build_launcher, path); - } + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (messages_service), + bus, INDICATOR_MESSAGES_DBUS_SERVICE_OBJECT, + &error); + if (error) { + g_warning ("unable to export messages service on dbus: %s", error->message); + g_error_free (error); + return; } - g_dir_close(dir); - launcherList = g_list_sort(launcherList, launcherList_sort); - return FALSE; -} - -static void -service_shutdown (IndicatorService * service, gpointer user_data) -{ - g_warning("Shutting down service!"); - g_main_loop_quit(mainloop); - return; + g_object_unref (bus); } -/* Respond to changing status by updating the icon that - is on the panel */ -static void -status_update_callback (void) -{ - return; -} - -/* The clear attention item has been clicked on, what to do? */ -static void -clear_attention_activate (DbusmenuMenuitem * mi, guint timestamp, MessageServiceDbus * dbus) -{ - message_service_dbus_set_attention(dbus, FALSE); - return; -} - -/* Handle an update of the active state to ensure that we're - only enabled when we could do something. */ -static void -clear_attention_handler (MessageServiceDbus * msd, gboolean attention, DbusmenuMenuitem * clearitem) -{ - dbusmenu_menuitem_property_set_bool(clearitem, DBUSMENU_MENUITEM_PROP_ENABLED, attention); - return; -} - -/* Oh, if you don't know what main() is for - we really shouldn't be talking. */ int main (int argc, char ** argv) { + GMainLoop * mainloop = NULL; + IndicatorService * service = NULL; + GMenuItem *header; + GIcon *icon; + gchar *iconstr; + /* Glib init */ g_type_init(); + mainloop = g_main_loop_new (NULL, FALSE); + /* Create the Indicator Service interface */ service = indicator_service_new_version(INDICATOR_MESSAGES_DBUS_NAME, 1); - g_signal_connect(service, INDICATOR_SERVICE_SIGNAL_SHUTDOWN, G_CALLBACK(service_shutdown), NULL); + g_signal_connect(service, INDICATOR_SERVICE_SIGNAL_SHUTDOWN, G_CALLBACK(service_shutdown), mainloop); /* Setting up i18n and gettext. Apparently, we need all of these. */ @@ -1533,58 +483,52 @@ main (int argc, char ** argv) bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); textdomain (GETTEXT_PACKAGE); - /* Create the Seen DB */ - seen_db_init(); - /* Bring up the service DBus interface */ - dbus_interface = message_service_dbus_new(); - - /* Build the base menu */ - root_menuitem = dbusmenu_menuitem_new(); - DbusmenuServer * server = dbusmenu_server_new(INDICATOR_MESSAGES_DBUS_OBJECT); - dbusmenu_server_set_root(server, root_menuitem); - - /* Add status items */ - GList * statusitems = status_items_build(&status_update_callback); - while (statusitems != NULL) { - dbusmenu_menuitem_child_append(root_menuitem, DBUSMENU_MENUITEM(statusitems->data)); - statusitems = g_list_next(statusitems); - } - status_separator = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(status_separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); - dbusmenu_menuitem_child_append(root_menuitem, status_separator); - - /* Add in the clear attention item */ - clear_attention = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(clear_attention, DBUSMENU_MENUITEM_PROP_LABEL, _("Clear")); - dbusmenu_menuitem_child_append(root_menuitem, clear_attention); - g_signal_connect(G_OBJECT(dbus_interface), MESSAGE_SERVICE_DBUS_SIGNAL_ATTENTION_CHANGED, G_CALLBACK(clear_attention_handler), clear_attention); - g_signal_connect(G_OBJECT(clear_attention), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(clear_attention_activate), dbus_interface); - - /* Start up the libindicate listener */ - listener = indicate_listener_ref_default(); - serverList = NULL; - - g_signal_connect(listener, INDICATE_LISTENER_SIGNAL_INDICATOR_ADDED, G_CALLBACK(indicator_added), root_menuitem); - g_signal_connect(listener, INDICATE_LISTENER_SIGNAL_INDICATOR_REMOVED, G_CALLBACK(indicator_removed), root_menuitem); - g_signal_connect(listener, INDICATE_LISTENER_SIGNAL_SERVER_ADDED, G_CALLBACK(server_added), root_menuitem); - g_signal_connect(listener, INDICATE_LISTENER_SIGNAL_SERVER_REMOVED, G_CALLBACK(server_removed), root_menuitem); - - /* Find launchers by looking through the config directories - in the idle loop */ - g_idle_add(blacklist_init, NULL); - g_idle_add(build_launchers, SYSTEM_APPS_DIR); - g_idle_add(build_launchers, SYSTEM_APPS_DIR_OLD); - gchar * userdir = g_build_filename(g_get_user_config_dir(), USER_APPS_DIR, NULL); - g_idle_add(build_launchers, userdir); - - /* Let's run a mainloop */ - mainloop = g_main_loop_new(NULL, FALSE); + messages_service = indicator_messages_service_skeleton_new (); + + g_bus_get (G_BUS_TYPE_SESSION, NULL, got_bus, NULL); + + actions = create_action_group (); + + action_muxer = g_action_muxer_new (); + g_action_muxer_insert (action_muxer, NULL, G_ACTION_GROUP (actions)); + + g_signal_connect (messages_service, "handle-register-application", + G_CALLBACK (register_application), NULL); + g_signal_connect (messages_service, "handle-unregister-application", + G_CALLBACK (unregister_application), NULL); + g_signal_connect (messages_service, "handle-set-status", + G_CALLBACK (set_status), NULL); + + menu = g_menu_new (); + chat_section = create_status_section (); + g_menu_append (menu, _("Clear"), "clear"); + + icon = g_themed_icon_new ("indicator-messages"); + iconstr = g_icon_to_string (icon); + + toplevel_menu = g_menu_new (); + header = g_menu_item_new (NULL, "messages"); + g_menu_item_set_submenu (header, G_MENU_MODEL (menu)); + g_menu_item_set_attribute (header, "x-canonical-icon", "s", iconstr); + g_menu_item_set_attribute (header, "x-canonical-accessible-description", "s", _("Messages")); + g_menu_append_item (toplevel_menu, header); + g_object_unref (header); + + settings = g_settings_new ("com.canonical.indicator.messages"); + + applications = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + + g_idle_add(build_launchers, NULL); + g_main_loop_run(mainloop); /* Clean up */ - status_items_cleanup(); - g_free(userdir); - + g_free (iconstr); + g_object_unref (icon); + g_object_unref (messages_service); + g_object_unref (chat_section); + g_object_unref (settings); + g_hash_table_unref (applications); return 0; } diff --git a/src/messages-service.xml b/src/messages-service.xml index d79049e..edd47c7 100644 --- a/src/messages-service.xml +++ b/src/messages-service.xml @@ -2,21 +2,21 @@ <node name="/"> <interface name="com.canonical.indicator.messages.service"> -<!-- Methods --> - <method name="AttentionRequested"> - <arg type="b" name="dot" direction="out" /> + <method name="RegisterApplication"> + <arg type="s" name="desktop_id" direction="in" /> + <arg type="o" name="menu_path" direction="in" /> </method> - <method name="IconShown"> - <arg type="b" name="hidden" direction="out" /> + + <method name="UnregisterApplication"> + <arg type="s" name="desktop_id" direction="in" /> </method> - <method name="ClearAttention" /> -<!-- Signals --> - <signal name="AttentionChanged"> - <arg type="b" name="dot" direction="out" /> - </signal> - <signal name="IconChanged"> - <arg type="b" name="hidden" direction="out" /> + <method name="SetStatus"> + <arg type="s" name="status" direction="in" /> + </method> + + <signal name="StatusChanged"> + <arg type="s" name="status" direction="in" /> </signal> </interface> diff --git a/src/seen-db.c b/src/seen-db.c deleted file mode 100644 index 57765cc..0000000 --- a/src/seen-db.c +++ /dev/null @@ -1,177 +0,0 @@ -/* -A small database of which desktop files we've seen. - -Copyright 2010 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "seen-db.h" - -#define GROUP_NAME "Seen Database" -#define KEY_NAME "DesktopFiles" - -GHashTable * seendb = NULL; -gchar * filename = NULL; -gchar * dirname = NULL; -guint write_process = 0; - -/* Build the hashtable and then see if we have a keyfile that - we can get the history of desktop files we've seen. */ -void -seen_db_init(void) -{ - g_return_if_fail(seendb == NULL); - - seendb = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); - - /* Build the filename for the seen database. We're putting - it in the cache directory because it could get deleted and - it really wouldn't be a big deal. */ - if (dirname == NULL) { - dirname = g_build_filename(g_get_user_cache_dir(), "indicators", "messages", NULL); - } - if (filename == NULL) { - filename = g_build_filename(dirname, "seen-db.keyfile", NULL); - } - - if (g_file_test(filename, G_FILE_TEST_EXISTS)) { - GKeyFile * keyfile = g_key_file_new(); - - /* Load from file */ - if (!g_key_file_load_from_file(keyfile, filename, G_KEY_FILE_NONE, NULL)) { - g_key_file_free(keyfile); - keyfile = NULL; - } - - /* Check for keys */ - if (keyfile != NULL && !g_key_file_has_key(keyfile, GROUP_NAME, KEY_NAME, NULL)) { - g_warning("Seen DB '%s' does not have key '%s' in group '%s'", filename, KEY_NAME, GROUP_NAME); - g_key_file_free(keyfile); - keyfile = NULL; - } - - /* Grab them and put in DB */ - if (keyfile != NULL) { - gchar ** desktops = g_key_file_get_string_list(keyfile, GROUP_NAME, KEY_NAME, NULL, NULL); - gint i = 0; - - while (desktops[i] != NULL) { - g_hash_table_insert(seendb, - g_strdup(desktops[i]), - GINT_TO_POINTER(TRUE)); - i++; - } - - g_strfreev(desktops); - } - - /* Clean up our file */ - if (keyfile != NULL) { - g_key_file_free(keyfile); - } - } - - return; -} - -/* A function to write out the seen database after it's been - modified for a while. */ -static gboolean -write_seen_db (gpointer user_data) -{ - write_process = 0; - - /* Build up the key file */ - GKeyFile * keyfile = g_key_file_new(); - GArray * desktops = g_array_new(FALSE, FALSE, sizeof(gchar *)); - - /* Get the keys from the hashtable and make them - into an array */ - if (keyfile != NULL) { - GList * desktop_keys = g_hash_table_get_keys(seendb); - GList * head = NULL; - - for (head = desktop_keys; head != NULL; head = g_list_next(head)) { - g_array_append_val(desktops, head->data); - } - - g_list_free(desktop_keys); - } - - /* Use the array to dump the strings into the keyfile */ - g_key_file_set_string_list(keyfile, - GROUP_NAME, - KEY_NAME, - (const gchar * const *)desktops->data, - desktops->len); - g_array_free(desktops, TRUE); - - /* Dump the key file to string */ - gchar * keydump = NULL; - gsize keydumplen = 0; - keydump = g_key_file_to_data(keyfile, &keydumplen, NULL); - g_key_file_free(keyfile); - - /* Ensure the directory exists */ - if (g_mkdir_with_parents(dirname, 0700) != 0) { - g_warning("Unable to make directory: %s", dirname); - g_free(keydump); - return FALSE; - } - - /* Dump out the file */ - GError * error = NULL; - if (!g_file_set_contents(filename, keydump, keydumplen, &error)) { - g_warning("Unable to write out file '%s': %s", filename, error->message); - g_error_free(error); - } - - /* Clean up */ - g_free(keydump); - - return FALSE; -} - -/* Add a new desktop file to the seen database. Also sets up a timer - to do the write out. */ -void -seen_db_add (const gchar * desktop) -{ - /* If this is a new one, let's set up the timer. If - there's already one clear it. */ - if (!seen_db_seen(desktop)) { - if (write_process != 0) { - g_source_remove(write_process); - write_process = 0; - } - - write_process = g_timeout_add_seconds(60, write_seen_db, NULL); - } - - g_hash_table_insert(seendb, - g_strdup(desktop), - GINT_TO_POINTER(TRUE)); - - return; -} - -/* Checks to see if a desktop file has been seen. */ -gboolean -seen_db_seen (const gchar * desktop) -{ - return GPOINTER_TO_INT(g_hash_table_lookup(seendb, desktop)); -} diff --git a/src/seen-db.h b/src/seen-db.h deleted file mode 100644 index a998ff0..0000000 --- a/src/seen-db.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -A small database of which desktop files we've seen. - -Copyright 2010 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef SEEN_DB_H__ -#define SEEN_DB_H__ 1 - -#include <glib.h> - -void seen_db_init(void); -void seen_db_add (const gchar * desktop); -gboolean seen_db_seen (const gchar * desktop); - -#endif /* SEEN_DB_H__ */ diff --git a/src/status-items.c b/src/status-items.c deleted file mode 100644 index 70a2ad9..0000000 --- a/src/status-items.c +++ /dev/null @@ -1,318 +0,0 @@ -/* -Code to build and maintain the status adjustment menuitems. - -Copyright 2011 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include <glib.h> -#include <glib/gi18n.h> -#include <gio/gio.h> -#include <libdbusmenu-glib/dbusmenu-glib.h> - -#include "status-items.h" -#include "status-provider.h" - -static const gchar * status_strings [STATUS_PROVIDER_STATUS_LAST] = { - /* STATUS_PROVIDER_STATUS_ONLINE, */ N_("Available"), - /* STATUS_PROVIDER_STATUS_AWAY, */ N_("Away"), - /* STATUS_PROVIDER_STATUS_DND */ N_("Busy"), - /* STATUS_PROVIDER_STATUS_INVISIBLE */ N_("Invisible"), - /* STATUS_PROVIDER_STATUS_OFFLINE, */ N_("Offline"), - /* STATUS_PROVIDER_STATUS_DISCONNECTED*/ N_("Offline") -}; - -static const gchar * status_icons[STATUS_PROVIDER_STATUS_LAST] = { - /* STATUS_PROVIDER_STATUS_ONLINE, */ "user-available", - /* STATUS_PROVIDER_STATUS_AWAY, */ "user-away", - /* STATUS_PROVIDER_STATUS_DND, */ "user-busy", - /* STATUS_PROVIDER_STATUS_INVISIBLE, */ "user-invisible", - /* STATUS_PROVIDER_STATUS_OFFLINE */ "user-offline", - /* STATUS_PROVIDER_STATUS_DISCONNECTED */ "user-offline-panel" -}; - -static const gchar * panel_icons[STATUS_PROVIDER_STATUS_LAST] = { - /* STATUS_PROVIDER_STATUS_ONLINE, */ "indicator-messages-user-available", - /* STATUS_PROVIDER_STATUS_AWAY, */ "indicator-messages-user-away", - /* STATUS_PROVIDER_STATUS_DND, */ "indicator-messages-user-busy", - /* STATUS_PROVIDER_STATUS_INVISIBLE, */ "indicator-messages-user-invisible", - /* STATUS_PROVIDER_STATUS_OFFLINE */ "indicator-messages-user-offline", - /* STATUS_PROVIDER_STATUS_DISCONNECTED */ "indicator-messages-user-disconnected" -}; - -static const gchar * panel_active_icons[STATUS_PROVIDER_STATUS_LAST] = { - /* STATUS_PROVIDER_STATUS_ONLINE, */ "indicator-messages-new-user-available", - /* STATUS_PROVIDER_STATUS_AWAY, */ "indicator-messages-new-user-away", - /* STATUS_PROVIDER_STATUS_DND, */ "indicator-messages-new-user-busy", - /* STATUS_PROVIDER_STATUS_INVISIBLE, */ "indicator-messages-new-user-invisible", - /* STATUS_PROVIDER_STATUS_OFFLINE */ "indicator-messages-new-user-offline", - /* STATUS_PROVIDER_STATUS_DISCONNECTED */ "indicator-messages-new-user-disconnected" -}; - -/* Prototypes */ -static gboolean provider_directory_parse (gpointer dir); -static gboolean load_status_provider (gpointer dir); -static void user_status_change (DbusmenuMenuitem * item, guint timestamp, gpointer pstatus); - -/* Globals */ -static StatusProviderStatus current_status = STATUS_PROVIDER_STATUS_DISCONNECTED; -static GList * menuitems = NULL; -static GList * status_providers = NULL; -static StatusUpdateFunc update_func = NULL; - -/* Build the inital status items and start kicking off the async code - for handling all the statuses */ -GList * -status_items_build (StatusUpdateFunc status_update_func) -{ - int i; - for (i = STATUS_PROVIDER_STATUS_ONLINE; i < STATUS_PROVIDER_STATUS_DISCONNECTED; i++) { - DbusmenuMenuitem * item = dbusmenu_menuitem_new(); - - dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_LABEL, _(status_strings[i])); - dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_ICON_NAME, status_icons[i]); - - dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); - dbusmenu_menuitem_property_set_bool(item, DBUSMENU_MENUITEM_PROP_ENABLED, FALSE); - - dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, DBUSMENU_MENUITEM_TOGGLE_RADIO); - dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED); - - g_signal_connect(G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(user_status_change), GINT_TO_POINTER(i)); - - menuitems = g_list_append(menuitems, item); - } - - update_func = status_update_func; - - const gchar * status_providers_env = g_getenv("INDICATOR_MESSAGES_STATUS_PROVIDER_DIR"); - if (status_providers_env == NULL) { - g_idle_add(provider_directory_parse, STATUS_PROVIDER_DIR); - } else { - g_idle_add(provider_directory_parse, (gpointer)status_providers_env); - } - - return menuitems; -} - -/* Clean up our globals and stop with all this allocation - of memory */ -void -status_items_cleanup (void) -{ - while (status_providers != NULL) { - StatusProvider * sprovider = STATUS_PROVIDER(status_providers->data); - g_object_unref(sprovider); - status_providers = g_list_remove(status_providers, sprovider); - } - - return; -} - -/* Get the icon that should be shown on the panel */ -const gchar * -status_current_panel_icon (gboolean alert) -{ - if (alert) { - return panel_active_icons[current_status]; - } else { - return panel_icons[current_status]; - } -} - -/* Update status from all the providers */ -static void -update_status (void) -{ - StatusProviderStatus status = STATUS_PROVIDER_STATUS_DISCONNECTED; - GList * provider; - - for (provider = status_providers; provider != NULL; provider = g_list_next(provider)) { - StatusProviderStatus localstatus = status_provider_get_status(STATUS_PROVIDER(provider->data)); - - if (localstatus < status) { - status = localstatus; - } - } - - if (status == current_status) { - return; - } - - current_status = status; - - if (update_func != NULL) { - update_func(); - } - - GList * menu; - int i; - for (menu = menuitems, i = 0; menu != NULL && i < STATUS_PROVIDER_STATUS_DISCONNECTED; menu = g_list_next(menu), i++) { - /* If we're the seleced status or if we're disconnected - show the user that we're offline */ - if (i == current_status || (current_status == STATUS_PROVIDER_STATUS_DISCONNECTED && i == STATUS_PROVIDER_STATUS_OFFLINE)) { - dbusmenu_menuitem_property_set_int(DBUSMENU_MENUITEM(menu->data), DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED); - } else { - dbusmenu_menuitem_property_set_int(DBUSMENU_MENUITEM(menu->data), DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED); - } - - if (current_status == STATUS_PROVIDER_STATUS_DISCONNECTED) { - dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(menu->data), DBUSMENU_MENUITEM_PROP_ENABLED, FALSE); - } else { - dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(menu->data), DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); - } - } - - return; -} - -/* Handle the user requesting a status change */ -static void -user_status_change (DbusmenuMenuitem * item, guint timestamp, gpointer pstatus) -{ - StatusProviderStatus status = GPOINTER_TO_INT(pstatus); - GList * provider; - - /* Set each provider to this status */ - for (provider = status_providers; provider != NULL; provider = g_list_next(provider)) { - status_provider_set_status(STATUS_PROVIDER(provider->data), status); - } - - /* See what we really are now */ - update_status(); - return; -} - -/* Start parsing a directory and setting up the entires in the idle loop */ -static gboolean -provider_directory_parse (gpointer directory) -{ - const gchar * dirname = (const gchar *)directory; - g_debug("Looking for status providers in: %s", dirname); - - if (!g_file_test(dirname, G_FILE_TEST_EXISTS)) { - return FALSE; - } - - GDir * dir = g_dir_open(dirname, 0, NULL); - if (dir == NULL) { - return FALSE; - } - - const gchar * name; - while ((name = g_dir_read_name(dir)) != NULL) { - if (!g_str_has_suffix(name, G_MODULE_SUFFIX)) { - continue; - } - - gchar * fullname = g_build_filename(dirname, name, NULL); - g_idle_add(load_status_provider, fullname); - } - - g_dir_close(dir); - - return FALSE; -} - -/* Close the module as an idle function so that we know - it's all cleaned up */ -static gboolean -module_destroy_in_idle_helper (gpointer data) -{ - GModule * module = (GModule *)data; - if (module != NULL) { - g_debug("Unloading module: %s", g_module_name(module)); - g_module_close(module); - } - return FALSE; -} - -/* Set up an idle function to close the module */ -static void -module_destroy_in_idle (gpointer data) -{ - g_idle_add_full(G_PRIORITY_LOW, module_destroy_in_idle_helper, data, NULL); - return; -} - -/* Load a particular status provider */ -static gboolean -load_status_provider (gpointer dir) -{ - gchar * provider = dir; - - /* load the module */ - GModule * module = NULL; - if (g_file_test(provider, G_FILE_TEST_EXISTS)) { - g_debug("Loading status provider: %s", provider); - module = g_module_open(provider, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); - if (module == NULL) { - g_warning("Unable to open module: %s", provider); - } - } - - /* find the status provider's GType */ - GType provider_type = 0; - if (module != NULL) { - GType (*type_func) (void); - if (!g_module_symbol(module, STATUS_PROVIDER_EXPORT_S, (gpointer *)&type_func)) { - g_warning("Unable to find type symbol in: %s", provider); - } else { - provider_type = type_func(); - if (provider_type == 0) { - g_warning("Unable to create type from: %s", provider); - } - } - } - - /* instantiate the status provider */ - StatusProvider * sprovider = NULL; - if (provider_type != 0) { - sprovider = STATUS_PROVIDER(g_object_new(provider_type, NULL)); - if (sprovider == NULL) { - g_warning("Unable to build provider from: %s", provider); - } - } - - /* use the provider */ - if (sprovider != NULL) { - /* On update let's talk to all of them and create the aggregate - value to export */ - g_signal_connect(G_OBJECT(sprovider), - STATUS_PROVIDER_SIGNAL_STATUS_CHANGED, - G_CALLBACK(update_status), NULL); - - /* Attach the module object to the status provider so - that when the status provider is free'd the module - is closed automatically. */ - g_object_set_data_full(G_OBJECT(sprovider), - "status-provider-module", - module, module_destroy_in_idle); - module = NULL; /* don't close module in this func */ - - status_providers = g_list_prepend(status_providers, sprovider); - - /* Force an update to ensure a consistent state */ - update_status(); - } - - /* cleanup */ - if (module != NULL) - g_module_close(module); - g_free(provider); - return FALSE; /* only call this idle func once */ -} diff --git a/src/status-items.h b/src/status-items.h deleted file mode 100644 index fe7900c..0000000 --- a/src/status-items.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -Code to build and maintain the status adjustment menuitems. - -Copyright 2011 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef __STATUS_ITEMS_H__ -#define __STATUS_ITEMS_H__ - -#include <glib.h> - -G_BEGIN_DECLS - -typedef void (*StatusUpdateFunc) (void); - -GList * status_items_build (StatusUpdateFunc update_func); -const gchar * status_current_panel_icon (gboolean alert); -void status_items_cleanup (void); - -G_END_DECLS - -#endif /* __STATUS_ITEMS_H__ */ - diff --git a/src/status-provider-emesene.c b/src/status-provider-emesene.c deleted file mode 100644 index 5aa6698..0000000 --- a/src/status-provider-emesene.c +++ /dev/null @@ -1,348 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2011 Canonical Ltd. - -Authors: - Stefano Candori <stefano.candori@gmail.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "status-provider.h" -#include "status-provider-emesene.h" - -#include <dbus/dbus-glib.h> - -typedef enum { - EM_STATUS_ONLINE, - EM_STATUS_INVISIBLE, - EM_STATUS_BUSY, - EM_STATUS_AWAY, - EM_STATUS_IDLE, - EM_STATUS_OFFLINE -} em_status_t; - -static const StatusProviderStatus em_to_sp_map[] = { - /* EM_STATUS_ONLINE, */ STATUS_PROVIDER_STATUS_ONLINE, - /* EM_STATUS_INVISIBLE, */ STATUS_PROVIDER_STATUS_INVISIBLE, - /* EM_STATUS_BUSY, */ STATUS_PROVIDER_STATUS_DND, - /* EM_STATUS_AWAY, */ STATUS_PROVIDER_STATUS_AWAY, - /* EM_STATUS_IDLE, */ STATUS_PROVIDER_STATUS_AWAY, - /* EM_STATUS_OFFLINE, */ STATUS_PROVIDER_STATUS_OFFLINE -}; - -static const em_status_t sp_to_em_map[STATUS_PROVIDER_STATUS_LAST] = { - /* STATUS_PROVIDER_STATUS_ONLINE, */ EM_STATUS_ONLINE, - /* STATUS_PROVIDER_STATUS_AWAY, */ EM_STATUS_AWAY, - /* STATUS_PROVIDER_STATUS_DND */ EM_STATUS_BUSY, - /* STATUS_PROVIDER_STATUS_INVISIBLE*/ EM_STATUS_INVISIBLE, - /* STATUS_PROVIDER_STATUS_OFFLINE */ EM_STATUS_OFFLINE, - /* STATUS_PROVIDER_STATUS_DISCONNECTED*/ EM_STATUS_OFFLINE -}; - -typedef struct _StatusProviderEmesenePrivate StatusProviderEmesenePrivate; -struct _StatusProviderEmesenePrivate { - DBusGProxy * proxy; - DBusGProxy * dbus_proxy; - em_status_t em_status; -}; - -#define STATUS_PROVIDER_EMESENE_GET_PRIVATE(o) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((o), STATUS_PROVIDER_EMESENE_TYPE, StatusProviderEmesenePrivate)) - -/* Prototypes */ -/* GObject stuff */ -static void status_provider_emesene_class_init (StatusProviderEmeseneClass *klass); -static void status_provider_emesene_init (StatusProviderEmesene *self); -static void status_provider_emesene_dispose (GObject *object); -static void status_provider_emesene_finalize (GObject *object); -/* Internal Funcs */ -static void set_status (StatusProvider * sp, StatusProviderStatus status); -static StatusProviderStatus get_status (StatusProvider * sp); -static void setup_emesene_proxy (StatusProviderEmesene * self); -static void dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderEmesene * self); - -G_DEFINE_TYPE (StatusProviderEmesene, status_provider_emesene, STATUS_PROVIDER_TYPE); - -STATUS_PROVIDER_EXPORT_TYPE(STATUS_PROVIDER_EMESENE_TYPE) - -static void -status_provider_emesene_class_init (StatusProviderEmeseneClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (StatusProviderEmesenePrivate)); - - object_class->dispose = status_provider_emesene_dispose; - object_class->finalize = status_provider_emesene_finalize; - - StatusProviderClass * spclass = STATUS_PROVIDER_CLASS(klass); - - spclass->set_status = set_status; - spclass->get_status = get_status; - - return; -} - -static void -status_cb (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata) -{ - StatusProviderEmesene * spe = STATUS_PROVIDER_EMESENE(userdata); - StatusProviderEmesenePrivate * priv = STATUS_PROVIDER_EMESENE_GET_PRIVATE(spe); - - GError * error = NULL; - gint status = 0; - if (!dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_INT, &status, G_TYPE_INVALID)) { - g_warning("Unable to get status from Emesene: %s", error->message); - g_error_free(error); - return; - } - - priv->em_status = status; - g_signal_emit(G_OBJECT(spe), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, em_to_sp_map[priv->em_status], TRUE); - return; -} - -static void -changed_status (DBusGProxy * proxy, gint status, StatusProviderEmesene * spe) -{ - StatusProviderEmesenePrivate * priv = STATUS_PROVIDER_EMESENE_GET_PRIVATE(spe); - g_debug("Emesene changed status to %d", status); - priv->em_status = status; - g_signal_emit(G_OBJECT(spe), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, em_to_sp_map[priv->em_status], TRUE); - return; -} - -static void -proxy_destroy (DBusGProxy * proxy, StatusProviderEmesene * spe) -{ - StatusProviderEmesenePrivate * priv = STATUS_PROVIDER_EMESENE_GET_PRIVATE(spe); - - priv->proxy = NULL; - priv->em_status = EM_STATUS_OFFLINE; - - g_signal_emit(G_OBJECT(spe), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, em_to_sp_map[priv->em_status], TRUE); - return; -} - -static void -status_provider_emesene_init (StatusProviderEmesene *self) -{ - StatusProviderEmesenePrivate * priv = STATUS_PROVIDER_EMESENE_GET_PRIVATE(self); - - priv->proxy = NULL; - priv->em_status = EM_STATUS_OFFLINE; - - DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); - g_return_if_fail(bus != NULL); /* Can't do anymore DBus stuff without this, - all non-DBus stuff should be done */ - - GError * error = NULL; - - /* Set up the dbus Proxy */ - priv->dbus_proxy = dbus_g_proxy_new_for_name_owner (bus, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS, - &error); - if (error != NULL) { - g_warning("Unable to connect to DBus events: %s", error->message); - g_error_free(error); - return; - } - - /* Configure the name owner changing */ - dbus_g_proxy_add_signal(priv->dbus_proxy, "NameOwnerChanged", - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal(priv->dbus_proxy, "NameOwnerChanged", - G_CALLBACK(dbus_namechange), - self, NULL); - - setup_emesene_proxy(self); - - return; -} - -/* Watch to see if the Emesene comes up on Dbus */ -static void -dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderEmesene * self) -{ - g_return_if_fail(name != NULL); - g_return_if_fail(new != NULL); - - if (g_strcmp0(name, "org.emesene.Service") == 0) { - setup_emesene_proxy(self); - } - return; -} - -/* Setup the Emesene proxy so that we can talk to it - and get signals from it. */ -static void -setup_emesene_proxy (StatusProviderEmesene * self) -{ - StatusProviderEmesenePrivate * priv = STATUS_PROVIDER_EMESENE_GET_PRIVATE(self); - - if (priv->proxy != NULL) { - g_debug("Doh!We were asked to set up a Emesene proxy when we already had one."); - return; - } - - DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); - g_return_if_fail(bus != NULL); /* Can't do anymore DBus stuff without this, - all non-DBus stuff should be done */ - - GError * error = NULL; - - /* Set up the Emesene Proxy */ - priv->proxy = dbus_g_proxy_new_for_name_owner (bus, - "org.emesene.Service", - "/org/emesene/Service", - "org.emesene.Service", - &error); - /* Report any errors */ - if (error != NULL) { - g_debug("Unable to get Emesene proxy: %s", error->message); - g_error_free(error); - } - - /* If we have a proxy, let's start using it */ - if (priv->proxy != NULL) { - /* Set the proxy to NULL if it's destroyed */ - g_object_add_weak_pointer (G_OBJECT(priv->proxy), (gpointer *)&priv->proxy); - /* If it's destroyed, let's clean up as well */ - g_signal_connect(G_OBJECT(priv->proxy), "destroy", - G_CALLBACK(proxy_destroy), self); - - /* Watching for the status change coming from the - Emesene side of things. */ - g_debug("Adding Emesene Signals"); - dbus_g_proxy_add_signal (priv->proxy, - "status_changed", - G_TYPE_INT, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal(priv->proxy, - "status_changed", - G_CALLBACK(changed_status), - (void *)self, - NULL); - - /* Get the current status to update our cached - value of the status. */ - dbus_g_proxy_begin_call(priv->proxy, - "get_status", - status_cb, - self, - NULL, - G_TYPE_INVALID); - } - - return; -} - -static void -status_provider_emesene_dispose (GObject *object) -{ - StatusProviderEmesenePrivate * priv = STATUS_PROVIDER_EMESENE_GET_PRIVATE(object); - - if (priv->proxy != NULL) { - g_object_unref(priv->proxy); - priv->proxy = NULL; - } - - G_OBJECT_CLASS (status_provider_emesene_parent_class)->dispose (object); - return; -} - -static void -status_provider_emesene_finalize (GObject *object) -{ - - G_OBJECT_CLASS (status_provider_emesene_parent_class)->finalize (object); - return; -} - -/** - status_provider_emesene_new: - - Creates a new #StatusProviderEmesene object. No parameters or anything - like that. Just a convience function. - - Return value: A new instance of #StatusProviderEmesene -*/ -StatusProvider * -status_provider_emesene_new (void) -{ - return STATUS_PROVIDER(g_object_new(STATUS_PROVIDER_EMESENE_TYPE, NULL)); -} - -/* Takes the status provided generically for Status providers - and turns it into a Emesene status and sends it to Emesene. */ -static void -set_status (StatusProvider * sp, StatusProviderStatus status) -{ - g_return_if_fail(IS_STATUS_PROVIDER_EMESENE(sp)); - StatusProviderEmesenePrivate * priv = STATUS_PROVIDER_EMESENE_GET_PRIVATE(sp); - - g_debug("Emesene set status to %d", status); - if (priv->proxy == NULL) { - return; - } - - priv->em_status = sp_to_em_map[status]; - - gboolean ret = FALSE; - GError * error = NULL; - - ret = dbus_g_proxy_call(priv->proxy, - "set_status", &error, - G_TYPE_INT, priv->em_status, - G_TYPE_INVALID, - G_TYPE_INVALID); - - if (!ret) { - if (error != NULL) { - g_warning("Emesene unable to change to status: %s", error->message); - g_error_free(error); - } else { - g_warning("Emesene unable to change to status"); - } - error = NULL; - } - - g_signal_emit(G_OBJECT(sp), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, em_to_sp_map[priv->em_status], TRUE); - return; -} - -/* Takes the cached Emesene status and makes it into the generic - Status provider status. If there is no Emesene proxy then it - returns the disconnected state. */ -static StatusProviderStatus -get_status (StatusProvider * sp) -{ - g_return_val_if_fail(IS_STATUS_PROVIDER_EMESENE(sp), STATUS_PROVIDER_STATUS_DISCONNECTED); - StatusProviderEmesenePrivate * priv = STATUS_PROVIDER_EMESENE_GET_PRIVATE(sp); - - if (priv->proxy == NULL) { - return STATUS_PROVIDER_STATUS_DISCONNECTED; - } - - return em_to_sp_map[priv->em_status]; -} diff --git a/src/status-provider-emesene.h b/src/status-provider-emesene.h deleted file mode 100644 index 2309684..0000000 --- a/src/status-provider-emesene.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 20011 Canonical Ltd. - -Authors: - Stefano Candori <stefano.candori@gmail.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef __STATUS_PROVIDER_EMESENE_H__ -#define __STATUS_PROVIDER_EMESENE_H__ - -#include <glib.h> -#include <glib-object.h> - -#include "status-provider.h" - -G_BEGIN_DECLS - -#define STATUS_PROVIDER_EMESENE_TYPE (status_provider_emesene_get_type ()) -#define STATUS_PROVIDER_EMESENE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STATUS_PROVIDER_EMESENE_TYPE, StatusProviderEmesene)) -#define STATUS_PROVIDER_EMESENE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STATUS_PROVIDER_EMESENE_TYPE, StatusProviderEmeseneClass)) -#define IS_STATUS_PROVIDER_EMESENE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STATUS_PROVIDER_EMESENE_TYPE)) -#define IS_STATUS_PROVIDER_EMESENE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), STATUS_PROVIDER_EMESENE_TYPE)) -#define STATUS_PROVIDER_EMESENE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STATUS_PROVIDER_EMESENE_TYPE, StatusProviderEmeseneClass)) - - -typedef struct _StatusProviderEmeseneClass StatusProviderEmeseneClass; -struct _StatusProviderEmeseneClass { - StatusProviderClass parent_class; -}; - -typedef struct _StatusProviderEmesene StatusProviderEmesene; -struct _StatusProviderEmesene { - StatusProvider parent; -}; - -GType status_provider_emesene_get_type (void); -StatusProvider * status_provider_emesene_new (void); - -G_END_DECLS - -#endif diff --git a/src/status-provider-mc5-marshal.c b/src/status-provider-mc5-marshal.c deleted file mode 100644 index 6b1a020..0000000 --- a/src/status-provider-mc5-marshal.c +++ /dev/null @@ -1,88 +0,0 @@ - -#include <glib-object.h> - - -#ifdef G_ENABLE_DEBUG -#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) -#define g_marshal_value_peek_char(v) g_value_get_schar (v) -#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) -#define g_marshal_value_peek_int(v) g_value_get_int (v) -#define g_marshal_value_peek_uint(v) g_value_get_uint (v) -#define g_marshal_value_peek_long(v) g_value_get_long (v) -#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) -#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) -#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) -#define g_marshal_value_peek_enum(v) g_value_get_enum (v) -#define g_marshal_value_peek_flags(v) g_value_get_flags (v) -#define g_marshal_value_peek_float(v) g_value_get_float (v) -#define g_marshal_value_peek_double(v) g_value_get_double (v) -#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) -#define g_marshal_value_peek_param(v) g_value_get_param (v) -#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) -#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) -#define g_marshal_value_peek_object(v) g_value_get_object (v) -#define g_marshal_value_peek_variant(v) g_value_get_variant (v) -#else /* !G_ENABLE_DEBUG */ -/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. - * Do not access GValues directly in your code. Instead, use the - * g_value_get_*() functions - */ -#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int -#define g_marshal_value_peek_char(v) (v)->data[0].v_int -#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint -#define g_marshal_value_peek_int(v) (v)->data[0].v_int -#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint -#define g_marshal_value_peek_long(v) (v)->data[0].v_long -#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 -#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 -#define g_marshal_value_peek_enum(v) (v)->data[0].v_long -#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_float(v) (v)->data[0].v_float -#define g_marshal_value_peek_double(v) (v)->data[0].v_double -#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer -#endif /* !G_ENABLE_DEBUG */ - - -/* VOID:UINT,STRING (./status-provider-mc5.list:1) */ -void -_status_provider_mc5_marshal_VOID__UINT_STRING (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef void (*GMarshalFunc_VOID__UINT_STRING) (gpointer data1, - guint arg_1, - gpointer arg_2, - gpointer data2); - register GMarshalFunc_VOID__UINT_STRING callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - - g_return_if_fail (n_param_values == 3); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_VOID__UINT_STRING) (marshal_data ? marshal_data : cc->callback); - - callback (data1, - g_marshal_value_peek_uint (param_values + 1), - g_marshal_value_peek_string (param_values + 2), - data2); -} - diff --git a/src/status-provider-mc5-marshal.h b/src/status-provider-mc5-marshal.h deleted file mode 100644 index 35cc5ad..0000000 --- a/src/status-provider-mc5-marshal.h +++ /dev/null @@ -1,20 +0,0 @@ - -#ifndef ___status_provider_mc5_marshal_MARSHAL_H__ -#define ___status_provider_mc5_marshal_MARSHAL_H__ - -#include <glib-object.h> - -G_BEGIN_DECLS - -/* VOID:UINT,STRING (./status-provider-mc5.list:1) */ -extern void _status_provider_mc5_marshal_VOID__UINT_STRING (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -G_END_DECLS - -#endif /* ___status_provider_mc5_marshal_MARSHAL_H__ */ - diff --git a/src/status-provider-mc5.c b/src/status-provider-mc5.c deleted file mode 100644 index 3f23565..0000000 --- a/src/status-provider-mc5.c +++ /dev/null @@ -1,308 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <telepathy-glib/account-manager.h> - -#include "status-provider.h" -#include "status-provider-mc5.h" -#include "status-provider-mc5-marshal.h" - -#include <dbus/dbus-glib.h> -#include <dbus/dbus-glib-bindings.h> - -static gchar * sp_to_mc_map[STATUS_PROVIDER_STATUS_LAST] = { - /* STATUS_PROVIDER_STATUS_ONLINE, */ "available", - /* STATUS_PROVIDER_STATUS_AWAY, */ "away", - /* STATUS_PROVIDER_STATUS_DND */ "busy", - /* STATUS_PROVIDER_STATUS_INVISIBLE*/ "hidden", - /* STATUS_PROVIDER_STATUS_OFFLINE */ "offline", - /* STATUS_PROVIDER_STATUS_DISCONNECTED*/NULL -}; - -static TpConnectionPresenceType sp_to_tp_map[STATUS_PROVIDER_STATUS_LAST] = { - /* STATUS_PROVIDER_STATUS_ONLINE, */ TP_CONNECTION_PRESENCE_TYPE_AVAILABLE, - /* STATUS_PROVIDER_STATUS_AWAY, */ TP_CONNECTION_PRESENCE_TYPE_AWAY, - /* STATUS_PROVIDER_STATUS_DND */ TP_CONNECTION_PRESENCE_TYPE_BUSY, - /* STATUS_PROVIDER_STATUS_INVISIBLE*/ TP_CONNECTION_PRESENCE_TYPE_HIDDEN, - /* STATUS_PROVIDER_STATUS_OFFLINE */ TP_CONNECTION_PRESENCE_TYPE_OFFLINE, - /* STATUS_PROVIDER_STATUS_DISCONNECTED*/ TP_CONNECTION_PRESENCE_TYPE_UNSET -}; - -static StatusProviderStatus tp_to_sp_map[TP_CONNECTION_PRESENCE_TYPE_ERROR + 1] = { - /* TP_CONNECTION_PRESENCE_TYPE_UNSET */ STATUS_PROVIDER_STATUS_DISCONNECTED, - /* TP_CONNECTION_PRESENCE_TYPE_OFFLINE */ STATUS_PROVIDER_STATUS_OFFLINE, - /* TP_CONNECTION_PRESENCE_TYPE_AVAILABLE */ STATUS_PROVIDER_STATUS_ONLINE, - /* TP_CONNECTION_PRESENCE_TYPE_AWAY */ STATUS_PROVIDER_STATUS_AWAY, - /* TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY */ STATUS_PROVIDER_STATUS_AWAY, - /* TP_CONNECTION_PRESENCE_TYPE_HIDDEN */ STATUS_PROVIDER_STATUS_INVISIBLE, - /* TP_CONNECTION_PRESENCE_TYPE_BUSY */ STATUS_PROVIDER_STATUS_DND, - /* TP_CONNECTION_PRESENCE_TYPE_UNKNOWN */ STATUS_PROVIDER_STATUS_DISCONNECTED, - /* TP_CONNECTION_PRESENCE_TYPE_ERROR */ STATUS_PROVIDER_STATUS_DISCONNECTED -}; - -typedef struct _StatusProviderMC5Private StatusProviderMC5Private; -struct _StatusProviderMC5Private { - TpAccountManager * manager; - StatusProviderStatus status; - DBusGProxy * dbus_proxy; -}; - -#define STATUS_PROVIDER_MC5_GET_PRIVATE(o) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((o), STATUS_PROVIDER_MC5_TYPE, StatusProviderMC5Private)) -#define MC5_WELL_KNOWN_NAME "org.freedesktop.Telepathy.AccountManager" - -/* Prototypes */ -/* GObject stuff */ -static void status_provider_mc5_class_init (StatusProviderMC5Class *klass); -static void status_provider_mc5_init (StatusProviderMC5 *self); -static void status_provider_mc5_dispose (GObject *object); -static void status_provider_mc5_finalize (GObject *object); -/* Internal Funcs */ -static void set_status (StatusProvider * sp, StatusProviderStatus status); -static StatusProviderStatus get_status (StatusProvider * sp); -static void presence_changed (TpAccountManager * eam, guint type, const gchar * type_str, const gchar * message, StatusProviderMC5 * sp); -static void dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderMC5 * self); -static void mc5_exists_cb (DBusGProxy * proxy, gboolean exists, GError * error, gpointer userdata); - -G_DEFINE_TYPE (StatusProviderMC5, status_provider_mc5, STATUS_PROVIDER_TYPE); - -STATUS_PROVIDER_EXPORT_TYPE(STATUS_PROVIDER_MC5_TYPE) - -/* Create the class. We over ride a few functions but nothing - really shocking. Most interesting is the set and get status. */ -static void -status_provider_mc5_class_init (StatusProviderMC5Class *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (StatusProviderMC5Private)); - - object_class->dispose = status_provider_mc5_dispose; - object_class->finalize = status_provider_mc5_finalize; - - StatusProviderClass * spclass = STATUS_PROVIDER_CLASS(klass); - - spclass->set_status = set_status; - spclass->get_status = get_status; - - return; -} - -/* Build our telepathy account manager instance if we don't - have one. */ -static void -build_eam (StatusProviderMC5 * self) -{ - StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(self); - - if (priv->manager != NULL) { - return; - } - - priv->manager = tp_account_manager_dup(); - g_signal_connect(G_OBJECT(priv->manager), "most-available-presence-changed", G_CALLBACK(presence_changed), self); - - return; -} - -/* Creating an instance of the status provider. We set the variables - and create an TpAccountManager object. It does all the hard - work in this module of tracking MissionControl and enumerating the - accounts and all that jazz. */ -static void -status_provider_mc5_init (StatusProviderMC5 *self) -{ - StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(self); - - priv->status = STATUS_PROVIDER_STATUS_OFFLINE; - priv->manager = NULL; - - DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); - g_return_if_fail(bus != NULL); /* Can't do anymore DBus stuff without this, - all non-DBus stuff should be done */ - - GError * error = NULL; - - /* Set up the dbus Proxy */ - priv->dbus_proxy = dbus_g_proxy_new_for_name_owner (bus, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS, - &error); - if (error != NULL) { - g_warning("Unable to connect to DBus events: %s", error->message); - g_error_free(error); - return; - } - - /* Configure the name owner changing */ - dbus_g_proxy_add_signal(priv->dbus_proxy, "NameOwnerChanged", - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal(priv->dbus_proxy, "NameOwnerChanged", - G_CALLBACK(dbus_namechange), - self, NULL); - - org_freedesktop_DBus_name_has_owner_async(priv->dbus_proxy, MC5_WELL_KNOWN_NAME, mc5_exists_cb, self); - - return; -} - -/* Unref the account manager and move on. Sadly, we're - leaving the show. */ -static void -status_provider_mc5_dispose (GObject *object) -{ - StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(object); - - if (priv->manager != NULL) { - g_object_unref(priv->manager); - priv->manager = NULL; - } - - if (priv->dbus_proxy != NULL) { - g_object_unref(priv->dbus_proxy); - priv->dbus_proxy = NULL; - } - - G_OBJECT_CLASS (status_provider_mc5_parent_class)->dispose (object); - return; -} - -/* Pass to superclass */ -static void -status_provider_mc5_finalize (GObject *object) -{ - - G_OBJECT_CLASS (status_provider_mc5_parent_class)->finalize (object); - return; -} - -/* Watch for MC5 Coming on and off the bus. */ -static void -dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderMC5 * self) -{ - /* g_debug("DBUS NAMECHANGE: %s %s %s", name, prev, new); */ - - if (prev[0] == '\0' && g_strcmp0(name, MC5_WELL_KNOWN_NAME) == 0) { - g_debug("MC5 Coming online"); - build_eam(self); - } - if (new[0] == '\0' && g_strcmp0(name, MC5_WELL_KNOWN_NAME) == 0) { - g_debug("MC5 going offline"); - StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(self); - if (priv->manager != NULL) { - g_object_unref(priv->manager); - priv->manager = NULL; - } - - priv->status = STATUS_PROVIDER_STATUS_OFFLINE; - g_signal_emit(G_OBJECT(self), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, priv->status, TRUE); - } - - return; -} - -/* Callback for the Dbus command to do HasOwner on - the MC5 service. If it exists, we want to have an - account manager. */ -static void -mc5_exists_cb (DBusGProxy * proxy, gboolean exists, GError * error, gpointer userdata) -{ - if (error) { - g_warning("Unable to check if MC5 is running: %s", error->message); - return; - } - - if (exists) { - build_eam(STATUS_PROVIDER_MC5(userdata)); - } - - return; -} - -/** - status_provider_mc5_new: - - Creates a new #StatusProviderMC5 object. No parameters or anything - like that. Just a convience function. - - Return value: A new instance of #StatusProviderMC5 -*/ -StatusProvider * -status_provider_mc5_new (void) -{ - return STATUS_PROVIDER(g_object_new(STATUS_PROVIDER_MC5_TYPE, NULL)); -} - -/* Setting the status in the empathy account manager. We're - basically requesting a global status. This may or may not - get applied to all accounts. It's really the best we can - hope to do. */ -static void -set_status (StatusProvider * sp, StatusProviderStatus status) -{ - StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(sp); - - build_eam(STATUS_PROVIDER_MC5(sp)); - tp_account_manager_set_all_requested_presences(priv->manager, sp_to_tp_map[status], sp_to_mc_map[status], ""); - - return; -} - -/* Gets the status, uses the cached value that we have. Asking - would just be painful. */ -static StatusProviderStatus -get_status (StatusProvider * sp) -{ - g_return_val_if_fail(IS_STATUS_PROVIDER_MC5(sp), STATUS_PROVIDER_STATUS_DISCONNECTED); - StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(sp); - - if (priv->manager == NULL) { - return STATUS_PROVIDER_STATUS_OFFLINE; - } - - return priv->status; -} - -/* A signal handler for when the TpAccountManager believes - that the global status has changed. It roughly calculates this - by finding the most available of all accounts that are active. */ -static void -presence_changed (TpAccountManager * eam, guint type, const gchar * type_str, const gchar * message, StatusProviderMC5 * sp) -{ - StatusProviderMC5Private * priv = STATUS_PROVIDER_MC5_GET_PRIVATE(sp); - - g_debug("MC5 Status changed: %d %s %s", type, type_str, message); - - if (priv->status != tp_to_sp_map[type]) { - priv->status = tp_to_sp_map[type]; - g_signal_emit(G_OBJECT(sp), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, priv->status, TRUE); - } - - return; -} - diff --git a/src/status-provider-mc5.h b/src/status-provider-mc5.h deleted file mode 100644 index 4d5659d..0000000 --- a/src/status-provider-mc5.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef __STATUS_PROVIDER_MC5_H__ -#define __STATUS_PROVIDER_MC5_H__ - -#include <glib.h> -#include <glib-object.h> - -#include "status-provider.h" - -G_BEGIN_DECLS - -#define STATUS_PROVIDER_MC5_TYPE (status_provider_mc5_get_type ()) -#define STATUS_PROVIDER_MC5(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STATUS_PROVIDER_MC5_TYPE, StatusProviderMC5)) -#define STATUS_PROVIDER_MC5_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STATUS_PROVIDER_MC5_TYPE, StatusProviderMC5Class)) -#define IS_STATUS_PROVIDER_MC5(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STATUS_PROVIDER_MC5_TYPE)) -#define IS_STATUS_PROVIDER_MC5_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), STATUS_PROVIDER_MC5_TYPE)) -#define STATUS_PROVIDER_MC5_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STATUS_PROVIDER_MC5_TYPE, StatusProviderMC5Class)) - - -typedef struct _StatusProviderMC5Class StatusProviderMC5Class; -struct _StatusProviderMC5Class { - StatusProviderClass parent_class; -}; - -typedef struct _StatusProviderMC5 StatusProviderMC5; -struct _StatusProviderMC5 { - StatusProvider parent; -}; - -GType status_provider_mc5_get_type (void); -StatusProvider * status_provider_mc5_new (void); - -G_END_DECLS - -#endif diff --git a/src/status-provider-mc5.list b/src/status-provider-mc5.list deleted file mode 100644 index 5ab45bf..0000000 --- a/src/status-provider-mc5.list +++ /dev/null @@ -1 +0,0 @@ -VOID:UINT,STRING diff --git a/src/status-provider-pidgin-marshal.c b/src/status-provider-pidgin-marshal.c deleted file mode 100644 index 95b0bc3..0000000 --- a/src/status-provider-pidgin-marshal.c +++ /dev/null @@ -1,88 +0,0 @@ - -#include <glib-object.h> - - -#ifdef G_ENABLE_DEBUG -#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) -#define g_marshal_value_peek_char(v) g_value_get_schar (v) -#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) -#define g_marshal_value_peek_int(v) g_value_get_int (v) -#define g_marshal_value_peek_uint(v) g_value_get_uint (v) -#define g_marshal_value_peek_long(v) g_value_get_long (v) -#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) -#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) -#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) -#define g_marshal_value_peek_enum(v) g_value_get_enum (v) -#define g_marshal_value_peek_flags(v) g_value_get_flags (v) -#define g_marshal_value_peek_float(v) g_value_get_float (v) -#define g_marshal_value_peek_double(v) g_value_get_double (v) -#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) -#define g_marshal_value_peek_param(v) g_value_get_param (v) -#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) -#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) -#define g_marshal_value_peek_object(v) g_value_get_object (v) -#define g_marshal_value_peek_variant(v) g_value_get_variant (v) -#else /* !G_ENABLE_DEBUG */ -/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. - * Do not access GValues directly in your code. Instead, use the - * g_value_get_*() functions - */ -#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int -#define g_marshal_value_peek_char(v) (v)->data[0].v_int -#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint -#define g_marshal_value_peek_int(v) (v)->data[0].v_int -#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint -#define g_marshal_value_peek_long(v) (v)->data[0].v_long -#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 -#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 -#define g_marshal_value_peek_enum(v) (v)->data[0].v_long -#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_float(v) (v)->data[0].v_float -#define g_marshal_value_peek_double(v) (v)->data[0].v_double -#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer -#endif /* !G_ENABLE_DEBUG */ - - -/* VOID:INT,INT (./status-provider-pidgin.list:1) */ -void -_status_provider_pidgin_marshal_VOID__INT_INT (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef void (*GMarshalFunc_VOID__INT_INT) (gpointer data1, - gint arg_1, - gint arg_2, - gpointer data2); - register GMarshalFunc_VOID__INT_INT callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - - g_return_if_fail (n_param_values == 3); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_VOID__INT_INT) (marshal_data ? marshal_data : cc->callback); - - callback (data1, - g_marshal_value_peek_int (param_values + 1), - g_marshal_value_peek_int (param_values + 2), - data2); -} - diff --git a/src/status-provider-pidgin-marshal.h b/src/status-provider-pidgin-marshal.h deleted file mode 100644 index e4fe662..0000000 --- a/src/status-provider-pidgin-marshal.h +++ /dev/null @@ -1,20 +0,0 @@ - -#ifndef ___status_provider_pidgin_marshal_MARSHAL_H__ -#define ___status_provider_pidgin_marshal_MARSHAL_H__ - -#include <glib-object.h> - -G_BEGIN_DECLS - -/* VOID:INT,INT (./status-provider-pidgin.list:1) */ -extern void _status_provider_pidgin_marshal_VOID__INT_INT (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -G_END_DECLS - -#endif /* ___status_provider_pidgin_marshal_MARSHAL_H__ */ - diff --git a/src/status-provider-pidgin.c b/src/status-provider-pidgin.c deleted file mode 100644 index 6c73d56..0000000 --- a/src/status-provider-pidgin.c +++ /dev/null @@ -1,433 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "status-provider.h" -#include "status-provider-pidgin.h" -#include "status-provider-pidgin-marshal.h" - -#include <dbus/dbus-glib.h> - -typedef enum { - PG_STATUS_UNKNOWN, - PG_STATUS_OFFLINE, - PG_STATUS_AVAILABLE, - PG_STATUS_UNAVAILABLE, - PG_STATUS_INVISIBLE, - PG_STATUS_AWAY, - PG_STATUS_EXTENDEND_AWAY, - PG_STATUS_MOBILE, - PG_STATUS_TUNE -} pg_status_t; - -static const StatusProviderStatus pg_to_sp_map[] = { - /* PG_STATUS_UNKNOWN, */ STATUS_PROVIDER_STATUS_OFFLINE, - /* PG_STATUS_OFFLINE, */ STATUS_PROVIDER_STATUS_OFFLINE, - /* PG_STATUS_AVAILABLE, */ STATUS_PROVIDER_STATUS_ONLINE, - /* PG_STATUS_UNAVAILABLE, */ STATUS_PROVIDER_STATUS_DND, - /* PG_STATUS_INVISIBLE, */ STATUS_PROVIDER_STATUS_INVISIBLE, - /* PG_STATUS_AWAY, */ STATUS_PROVIDER_STATUS_AWAY, - /* PG_STATUS_EXTENDEND_AWAY, */ STATUS_PROVIDER_STATUS_AWAY, - /* PG_STATUS_MOBILE, */ STATUS_PROVIDER_STATUS_OFFLINE, - /* PG_STATUS_TUNE */ STATUS_PROVIDER_STATUS_OFFLINE -}; - -static const pg_status_t sp_to_pg_map[STATUS_PROVIDER_STATUS_LAST] = { - /* STATUS_PROVIDER_STATUS_ONLINE, */ PG_STATUS_AVAILABLE, - /* STATUS_PROVIDER_STATUS_AWAY, */ PG_STATUS_AWAY, - /* STATUS_PROVIDER_STATUS_DND */ PG_STATUS_UNAVAILABLE, - /* STATUS_PROVIDER_STATUS_INVISIBLE*/ PG_STATUS_INVISIBLE, - /* STATUS_PROVIDER_STATUS_OFFLINE */ PG_STATUS_OFFLINE, - /* STATUS_PROVIDER_STATUS_DISCONNECTED*/ PG_STATUS_OFFLINE -}; - -typedef struct _StatusProviderPidginPrivate StatusProviderPidginPrivate; -struct _StatusProviderPidginPrivate { - DBusGProxy * proxy; - DBusGProxy * dbus_proxy; - pg_status_t pg_status; -}; - -#define STATUS_PROVIDER_PIDGIN_GET_PRIVATE(o) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((o), STATUS_PROVIDER_PIDGIN_TYPE, StatusProviderPidginPrivate)) - -/* Prototypes */ -/* GObject stuff */ -static void status_provider_pidgin_class_init (StatusProviderPidginClass *klass); -static void status_provider_pidgin_init (StatusProviderPidgin *self); -static void status_provider_pidgin_dispose (GObject *object); -static void status_provider_pidgin_finalize (GObject *object); -/* Internal Funcs */ -static void set_status (StatusProvider * sp, StatusProviderStatus status); -static StatusProviderStatus get_status (StatusProvider * sp); -static void setup_pidgin_proxy (StatusProviderPidgin * self); -static void dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderPidgin * self); - -G_DEFINE_TYPE (StatusProviderPidgin, status_provider_pidgin, STATUS_PROVIDER_TYPE); - -STATUS_PROVIDER_EXPORT_TYPE(STATUS_PROVIDER_PIDGIN_TYPE) - -static void -status_provider_pidgin_class_init (StatusProviderPidginClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (StatusProviderPidginPrivate)); - - object_class->dispose = status_provider_pidgin_dispose; - object_class->finalize = status_provider_pidgin_finalize; - - StatusProviderClass * spclass = STATUS_PROVIDER_CLASS(klass); - - spclass->set_status = set_status; - spclass->get_status = get_status; - - return; -} - -static void -type_cb (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata) -{ - GError * error = NULL; - gint status = 0; - if (!dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_INT, &status, G_TYPE_INVALID)) { - g_warning("Unable to get type from Pidgin: %s", error->message); - g_error_free(error); - return; - } - - StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(userdata); - if (status != priv->pg_status) { - priv->pg_status = status; - - g_signal_emit(G_OBJECT(userdata), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, pg_to_sp_map[priv->pg_status], TRUE); - } - - return; -} - -static void -saved_status_to_type (StatusProviderPidgin * spp, gint savedstatus) -{ - StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(spp); - - g_debug("Pidgin figuring out type for %d", savedstatus); - dbus_g_proxy_begin_call(priv->proxy, - "PurpleSavedstatusGetType", type_cb, spp, NULL, - G_TYPE_INT, savedstatus, G_TYPE_INVALID); - - return; -} - -static void -savedstatus_cb (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata) -{ - GError * error = NULL; - gint status = 0; - if (!dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_INT, &status, G_TYPE_INVALID)) { - g_warning("Unable to get saved status from Pidgin: %s", error->message); - g_error_free(error); - return; - } - - saved_status_to_type(STATUS_PROVIDER_PIDGIN(userdata), status); - return; -} - - -static void -changed_status (DBusGProxy * proxy, gint savedstatus, GError ** error, StatusProviderPidgin * spp) -{ - saved_status_to_type(spp, savedstatus); - return; -} - -static void -proxy_destroy (DBusGProxy * proxy, StatusProviderPidgin * spp) -{ - StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(spp); - - priv->proxy = NULL; - priv->pg_status = PG_STATUS_OFFLINE; - - g_signal_emit(G_OBJECT(spp), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, pg_to_sp_map[priv->pg_status], TRUE); - return; -} - -static void -status_provider_pidgin_init (StatusProviderPidgin *self) -{ - StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(self); - - priv->proxy = NULL; - priv->pg_status = PG_STATUS_OFFLINE; - - DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); - g_return_if_fail(bus != NULL); /* Can't do anymore DBus stuff without this, - all non-DBus stuff should be done */ - - GError * error = NULL; - - /* Set up the dbus Proxy */ - priv->dbus_proxy = dbus_g_proxy_new_for_name_owner (bus, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS, - &error); - if (error != NULL) { - g_warning("Unable to connect to DBus events: %s", error->message); - g_error_free(error); - return; - } - - /* Configure the name owner changing */ - dbus_g_proxy_add_signal(priv->dbus_proxy, "NameOwnerChanged", - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal(priv->dbus_proxy, "NameOwnerChanged", - G_CALLBACK(dbus_namechange), - self, NULL); - - setup_pidgin_proxy(self); - - return; -} - -/* Watch to see if the Pidgin comes up on Dbus */ -static void -dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderPidgin * self) -{ - g_return_if_fail(name != NULL); - g_return_if_fail(new != NULL); - - if (g_strcmp0(name, "im.pidgin.purple.PurpleService") == 0) { - setup_pidgin_proxy(self); - } - return; -} - -/* Setup the Pidgin proxy so that we can talk to it - and get signals from it. */ -static void -setup_pidgin_proxy (StatusProviderPidgin * self) -{ - StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(self); - - if (priv->proxy != NULL) { - g_debug("Odd, we were asked to set up a Pidgin proxy when we already had one."); - return; - } - - DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); - g_return_if_fail(bus != NULL); /* Can't do anymore DBus stuff without this, - all non-DBus stuff should be done */ - - GError * error = NULL; - - /* Set up the Pidgin Proxy */ - priv->proxy = dbus_g_proxy_new_for_name_owner (bus, - "im.pidgin.purple.PurpleService", - "/im/pidgin/purple/PurpleObject", - "im.pidgin.purple.PurpleInterface", - &error); - /* Report any errors */ - if (error != NULL) { - g_debug("Unable to get Pidgin proxy: %s", error->message); - g_error_free(error); - } - - /* If we have a proxy, let's start using it */ - if (priv->proxy != NULL) { - /* Set the proxy to NULL if it's destroyed */ - g_object_add_weak_pointer (G_OBJECT(priv->proxy), (gpointer *)&priv->proxy); - /* If it's destroyed, let's clean up as well */ - g_signal_connect(G_OBJECT(priv->proxy), "destroy", - G_CALLBACK(proxy_destroy), self); - - /* Watching for the status change coming from the - Pidgin side of things. */ - g_debug("Adding Pidgin Signals"); - dbus_g_object_register_marshaller(_status_provider_pidgin_marshal_VOID__INT_INT, - G_TYPE_NONE, - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INVALID); - dbus_g_proxy_add_signal (priv->proxy, - "SavedstatusChanged", - G_TYPE_INT, - G_TYPE_INT, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal(priv->proxy, - "SavedstatusChanged", - G_CALLBACK(changed_status), - (void *)self, - NULL); - - /* Get the current status to update our cached - value of the status. */ - dbus_g_proxy_begin_call(priv->proxy, - "PurpleSavedstatusGetCurrent", - savedstatus_cb, - self, - NULL, - G_TYPE_INVALID); - } - - return; -} - -static void -status_provider_pidgin_dispose (GObject *object) -{ - StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(object); - - if (priv->proxy != NULL) { - g_object_unref(priv->proxy); - priv->proxy = NULL; - } - - G_OBJECT_CLASS (status_provider_pidgin_parent_class)->dispose (object); - return; -} - -static void -status_provider_pidgin_finalize (GObject *object) -{ - - G_OBJECT_CLASS (status_provider_pidgin_parent_class)->finalize (object); - return; -} - -/** - status_provider_pidgin_new: - - Creates a new #StatusProviderPidgin object. No parameters or anything - like that. Just a convience function. - - Return value: A new instance of #StatusProviderPidgin -*/ -StatusProvider * -status_provider_pidgin_new (void) -{ - return STATUS_PROVIDER(g_object_new(STATUS_PROVIDER_PIDGIN_TYPE, NULL)); -} - -/* Takes the status provided generically for Status providers - and turns it into a Pidgin status and sends it to Pidgin. */ -static void -set_status (StatusProvider * sp, StatusProviderStatus status) -{ - gchar * message = ""; - - g_return_if_fail(IS_STATUS_PROVIDER_PIDGIN(sp)); - StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(sp); - - g_debug("\tPidgin set status to %d", status); - if (priv->proxy == NULL) { - return; - } - - priv->pg_status = sp_to_pg_map[status]; - gint status_val = 0; - gboolean ret = FALSE; - GError * error = NULL; - - ret = dbus_g_proxy_call(priv->proxy, - "PurpleSavedstatusFindTransientByTypeAndMessage", &error, - G_TYPE_INT, priv->pg_status, - G_TYPE_STRING, message, - G_TYPE_INVALID, - G_TYPE_INT, &status_val, - G_TYPE_INVALID); - - if (!ret) { - if (error != NULL) { - g_error_free(error); - } - error = NULL; - status_val = 0; - g_debug("No Pidgin saved status to apply"); - } - - if (status_val == 0) { - ret = dbus_g_proxy_call(priv->proxy, - "PurpleSavedstatusNew", &error, - G_TYPE_STRING, message, - G_TYPE_INT, priv->pg_status, - G_TYPE_INVALID, - G_TYPE_INT, &status_val, - G_TYPE_INVALID); - - if (!ret) { - status_val = 0; - if (error != NULL) { - g_warning("Unable to create Pidgin status for %d: %s", status, error->message); - g_error_free(error); - } else { - g_warning("Unable to create Pidgin status for %d", status); - } - error = NULL; - } - } - - if (status_val == 0) { - return; - } - - ret = dbus_g_proxy_call(priv->proxy, - "PurpleSavedstatusActivate", &error, - G_TYPE_INT, status_val, - G_TYPE_INVALID, - G_TYPE_INVALID); - - if (!ret) { - if (error != NULL) { - g_warning("Pidgin unable to change to status: %s", error->message); - g_error_free(error); - } else { - g_warning("Pidgin unable to change to status"); - } - error = NULL; - } - - g_signal_emit(G_OBJECT(sp), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, pg_to_sp_map[priv->pg_status], TRUE); - return; -} - -/* Takes the cached Pidgin status and makes it into the generic - Status provider status. If there is no Pidgin proxy then it - returns the disconnected state. */ -static StatusProviderStatus -get_status (StatusProvider * sp) -{ - g_return_val_if_fail(IS_STATUS_PROVIDER_PIDGIN(sp), STATUS_PROVIDER_STATUS_DISCONNECTED); - StatusProviderPidginPrivate * priv = STATUS_PROVIDER_PIDGIN_GET_PRIVATE(sp); - - if (priv->proxy == NULL) { - return STATUS_PROVIDER_STATUS_DISCONNECTED; - } - - return pg_to_sp_map[priv->pg_status]; -} diff --git a/src/status-provider-pidgin.h b/src/status-provider-pidgin.h deleted file mode 100644 index 54b1718..0000000 --- a/src/status-provider-pidgin.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef __STATUS_PROVIDER_PIDGIN_H__ -#define __STATUS_PROVIDER_PIDGIN_H__ - -#include <glib.h> -#include <glib-object.h> - -#include "status-provider.h" - -G_BEGIN_DECLS - -#define STATUS_PROVIDER_PIDGIN_TYPE (status_provider_pidgin_get_type ()) -#define STATUS_PROVIDER_PIDGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STATUS_PROVIDER_PIDGIN_TYPE, StatusProviderPidgin)) -#define STATUS_PROVIDER_PIDGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STATUS_PROVIDER_PIDGIN_TYPE, StatusProviderPidginClass)) -#define IS_STATUS_PROVIDER_PIDGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STATUS_PROVIDER_PIDGIN_TYPE)) -#define IS_STATUS_PROVIDER_PIDGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), STATUS_PROVIDER_PIDGIN_TYPE)) -#define STATUS_PROVIDER_PIDGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STATUS_PROVIDER_PIDGIN_TYPE, StatusProviderPidginClass)) - - -typedef struct _StatusProviderPidginClass StatusProviderPidginClass; -struct _StatusProviderPidginClass { - StatusProviderClass parent_class; -}; - -typedef struct _StatusProviderPidgin StatusProviderPidgin; -struct _StatusProviderPidgin { - StatusProvider parent; -}; - -GType status_provider_pidgin_get_type (void); -StatusProvider * status_provider_pidgin_new (void); - -G_END_DECLS - -#endif diff --git a/src/status-provider-pidgin.list b/src/status-provider-pidgin.list deleted file mode 100644 index 1f953dd..0000000 --- a/src/status-provider-pidgin.list +++ /dev/null @@ -1 +0,0 @@ -VOID:INT,INT diff --git a/src/status-provider-telepathy-marshal.c b/src/status-provider-telepathy-marshal.c deleted file mode 100644 index ce5509c..0000000 --- a/src/status-provider-telepathy-marshal.c +++ /dev/null @@ -1,88 +0,0 @@ - -#include <glib-object.h> - - -#ifdef G_ENABLE_DEBUG -#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) -#define g_marshal_value_peek_char(v) g_value_get_schar (v) -#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) -#define g_marshal_value_peek_int(v) g_value_get_int (v) -#define g_marshal_value_peek_uint(v) g_value_get_uint (v) -#define g_marshal_value_peek_long(v) g_value_get_long (v) -#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) -#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) -#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) -#define g_marshal_value_peek_enum(v) g_value_get_enum (v) -#define g_marshal_value_peek_flags(v) g_value_get_flags (v) -#define g_marshal_value_peek_float(v) g_value_get_float (v) -#define g_marshal_value_peek_double(v) g_value_get_double (v) -#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) -#define g_marshal_value_peek_param(v) g_value_get_param (v) -#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) -#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) -#define g_marshal_value_peek_object(v) g_value_get_object (v) -#define g_marshal_value_peek_variant(v) g_value_get_variant (v) -#else /* !G_ENABLE_DEBUG */ -/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. - * Do not access GValues directly in your code. Instead, use the - * g_value_get_*() functions - */ -#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int -#define g_marshal_value_peek_char(v) (v)->data[0].v_int -#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint -#define g_marshal_value_peek_int(v) (v)->data[0].v_int -#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint -#define g_marshal_value_peek_long(v) (v)->data[0].v_long -#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 -#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 -#define g_marshal_value_peek_enum(v) (v)->data[0].v_long -#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_float(v) (v)->data[0].v_float -#define g_marshal_value_peek_double(v) (v)->data[0].v_double -#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer -#endif /* !G_ENABLE_DEBUG */ - - -/* VOID:UINT,STRING (./status-provider-telepathy.list:1) */ -void -_status_provider_telepathy_marshal_VOID__UINT_STRING (GClosure *closure, - GValue *return_value G_GNUC_UNUSED, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint G_GNUC_UNUSED, - gpointer marshal_data) -{ - typedef void (*GMarshalFunc_VOID__UINT_STRING) (gpointer data1, - guint arg_1, - gpointer arg_2, - gpointer data2); - register GMarshalFunc_VOID__UINT_STRING callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - - g_return_if_fail (n_param_values == 3); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_VOID__UINT_STRING) (marshal_data ? marshal_data : cc->callback); - - callback (data1, - g_marshal_value_peek_uint (param_values + 1), - g_marshal_value_peek_string (param_values + 2), - data2); -} - diff --git a/src/status-provider-telepathy-marshal.h b/src/status-provider-telepathy-marshal.h deleted file mode 100644 index c8595fe..0000000 --- a/src/status-provider-telepathy-marshal.h +++ /dev/null @@ -1,20 +0,0 @@ - -#ifndef ___status_provider_telepathy_marshal_MARSHAL_H__ -#define ___status_provider_telepathy_marshal_MARSHAL_H__ - -#include <glib-object.h> - -G_BEGIN_DECLS - -/* VOID:UINT,STRING (./status-provider-telepathy.list:1) */ -extern void _status_provider_telepathy_marshal_VOID__UINT_STRING (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); - -G_END_DECLS - -#endif /* ___status_provider_telepathy_marshal_MARSHAL_H__ */ - diff --git a/src/status-provider-telepathy.c b/src/status-provider-telepathy.c deleted file mode 100644 index 948e965..0000000 --- a/src/status-provider-telepathy.c +++ /dev/null @@ -1,385 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "status-provider.h" -#include "status-provider-telepathy.h" -#include "status-provider-telepathy-marshal.h" - -#include <dbus/dbus-glib.h> - -typedef enum { - MC_STATUS_UNSET, - MC_STATUS_OFFLINE, - MC_STATUS_AVAILABLE, - MC_STATUS_AWAY, - MC_STATUS_EXTENDED_AWAY, - MC_STATUS_HIDDEN, - MC_STATUS_DND -} mc_status_t; - -static StatusProviderStatus mc_to_sp_map[] = { - /* MC_STATUS_UNSET, */ STATUS_PROVIDER_STATUS_OFFLINE, - /* MC_STATUS_OFFLINE, */ STATUS_PROVIDER_STATUS_OFFLINE, - /* MC_STATUS_AVAILABLE, */ STATUS_PROVIDER_STATUS_ONLINE, - /* MC_STATUS_AWAY, */ STATUS_PROVIDER_STATUS_AWAY, - /* MC_STATUS_EXTENDED_AWAY, */ STATUS_PROVIDER_STATUS_AWAY, - /* MC_STATUS_HIDDEN, */ STATUS_PROVIDER_STATUS_INVISIBLE, - /* MC_STATUS_DND */ STATUS_PROVIDER_STATUS_DND -}; - -static mc_status_t sp_to_mc_map[] = { - /* STATUS_PROVIDER_STATUS_ONLINE, */ MC_STATUS_AVAILABLE, - /* STATUS_PROVIDER_STATUS_AWAY, */ MC_STATUS_AWAY, - /* STATUS_PROVIDER_STATUS_DND */ MC_STATUS_DND, - /* STATUS_PROVIDER_STATUS_INVISIBLE*/ MC_STATUS_HIDDEN, - /* STATUS_PROVIDER_STATUS_OFFLINE */ MC_STATUS_OFFLINE, - /* STATUS_PROVIDER_STATUS_DISCONNECTED*/MC_STATUS_OFFLINE -}; - -typedef struct _StatusProviderTelepathyPrivate StatusProviderTelepathyPrivate; -struct _StatusProviderTelepathyPrivate { - DBusGProxy * proxy; - DBusGProxy * dbus_proxy; - mc_status_t mc_status; -}; - -#define STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(o) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((o), STATUS_PROVIDER_TELEPATHY_TYPE, StatusProviderTelepathyPrivate)) - -/* Prototypes */ -/* GObject stuff */ -static void status_provider_telepathy_class_init (StatusProviderTelepathyClass *klass); -static void status_provider_telepathy_init (StatusProviderTelepathy *self); -static void status_provider_telepathy_dispose (GObject *object); -static void status_provider_telepathy_finalize (GObject *object); -/* Internal Funcs */ -static void build_telepathy_proxy (StatusProviderTelepathy * self); -static void dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderTelepathy * self); -static void set_status (StatusProvider * sp, StatusProviderStatus status); -static StatusProviderStatus get_status (StatusProvider * sp); -static void changed_status (DBusGProxy * proxy, guint status, gchar * message, StatusProvider * sp); -static void proxy_destroy (DBusGProxy * proxy, StatusProvider * sp); -static void get_status_async (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata); - -G_DEFINE_TYPE (StatusProviderTelepathy, status_provider_telepathy, STATUS_PROVIDER_TYPE); - -STATUS_PROVIDER_EXPORT_TYPE(STATUS_PROVIDER_TELEPATHY_TYPE) - -static void -status_provider_telepathy_class_init (StatusProviderTelepathyClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (StatusProviderTelepathyPrivate)); - - object_class->dispose = status_provider_telepathy_dispose; - object_class->finalize = status_provider_telepathy_finalize; - - StatusProviderClass * spclass = STATUS_PROVIDER_CLASS(klass); - - spclass->set_status = set_status; - spclass->get_status = get_status; - - return; -} - - -static void -status_provider_telepathy_init (StatusProviderTelepathy *self) -{ - StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(self); - - priv->proxy = NULL; - priv->dbus_proxy = NULL; - priv->mc_status = MC_STATUS_OFFLINE; - - GError * error = NULL; - - /* Grabbing the session bus */ - DBusGConnection * bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); - if (bus == NULL) { - g_warning("Unable to connect to Session Bus: %s", error == NULL ? "No message" : error->message); - g_error_free(error); - return; - } - - /* Set up the dbus Proxy */ - priv->dbus_proxy = dbus_g_proxy_new_for_name_owner (bus, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS, - &error); - if (error != NULL) { - g_warning("Unable to connect to DBus events: %s", error->message); - g_error_free(error); - return; - } - - /* Configure the name owner changing */ - dbus_g_proxy_add_signal(priv->dbus_proxy, "NameOwnerChanged", - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal(priv->dbus_proxy, "NameOwnerChanged", - G_CALLBACK(dbus_namechange), - self, NULL); - - build_telepathy_proxy(self); - - return; -} - -/* Builds up the proxy to Mission Control and configures all of the - signals for getting info from the proxy. Also does a call to get - the inital value of the status. */ -static void -build_telepathy_proxy (StatusProviderTelepathy * self) -{ - g_debug("Building Telepathy Proxy"); - StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(self); - - if (priv->proxy != NULL) { - g_debug("Hmm, being asked to build a proxy we alredy have."); - return; - } - - GError * error = NULL; - - /* Grabbing the session bus */ - DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); - if (session_bus == NULL) { - g_warning("Unable to connect to Session Bus: %s", error == NULL ? "No message" : error->message); - g_error_free(error); - return; - } - - /* Get the proxy to Mission Control */ - priv->proxy = dbus_g_proxy_new_for_name_owner(session_bus, - "org.freedesktop.Telepathy.MissionControl", - "/org/freedesktop/Telepathy/MissionControl", - "org.freedesktop.Telepathy.MissionControl", - &error); - - if (priv->proxy != NULL) { - /* If it goes, we set the proxy to NULL */ - g_object_add_weak_pointer (G_OBJECT(priv->proxy), (gpointer *)&priv->proxy); - /* And we clean up other variables associated */ - g_signal_connect(G_OBJECT(priv->proxy), "destroy", - G_CALLBACK(proxy_destroy), self); - - /* Set up the signal handler for watching when status changes. */ - dbus_g_object_register_marshaller(_status_provider_telepathy_marshal_VOID__UINT_STRING, - G_TYPE_NONE, - G_TYPE_UINT, - G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_add_signal (priv->proxy, - "PresenceChanged", - G_TYPE_UINT, - G_TYPE_STRING, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal(priv->proxy, - "PresenceChanged", - G_CALLBACK(changed_status), - (void *)self, - NULL); - - /* Do a get here, to init the status */ - dbus_g_proxy_begin_call(priv->proxy, - "GetStatus", - get_status_async, - self, - NULL, - G_TYPE_INVALID); - } else { - g_warning("Unable to connect to Mission Control"); - if (error != NULL) { - g_error_free(error); - } - } - - return; -} - -/* Watch to see if the Mission Control comes up on Dbus */ -static void -dbus_namechange (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, StatusProviderTelepathy * self) -{ - g_return_if_fail(name != NULL); - g_return_if_fail(new != NULL); - - if (g_strcmp0(name, "org.freedesktop.Telepathy.MissionControl") == 0) { - build_telepathy_proxy(self); - } - return; -} - -static void -status_provider_telepathy_dispose (GObject *object) -{ - StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(object); - - if (priv->proxy != NULL) { - g_object_unref(priv->proxy); - priv->proxy = NULL; - } - - G_OBJECT_CLASS (status_provider_telepathy_parent_class)->dispose (object); - return; -} - -static void -status_provider_telepathy_finalize (GObject *object) -{ - - G_OBJECT_CLASS (status_provider_telepathy_parent_class)->finalize (object); - return; -} - -/** - status_provider_telepathy_new: - - Creates a new #StatusProviderTelepathy object. No parameters or anything - like that. Just a convience function. - - Return value: A new instance of #StatusProviderTelepathy -*/ -StatusProvider * -status_provider_telepathy_new (void) -{ - return STATUS_PROVIDER(g_object_new(STATUS_PROVIDER_TELEPATHY_TYPE, NULL)); -} - -static void -set_status (StatusProvider * sp, StatusProviderStatus status) -{ - StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(sp); - if (priv->proxy == NULL) { - priv->mc_status = MC_STATUS_OFFLINE; - return; - } - - priv->mc_status = sp_to_mc_map[status]; - - guint mcstatus = MC_STATUS_UNSET; - gboolean ret = FALSE; - GError * error = NULL; - - ret = dbus_g_proxy_call(priv->proxy, - "GetPresence", &error, - G_TYPE_INVALID, - G_TYPE_UINT, &mcstatus, - G_TYPE_INVALID); - - /* If we can't get the get call to work, let's not set */ - if (!ret) { - if (error != NULL) { - g_error_free(error); - } - return; - } - - /* If the get call doesn't return a status, that means that there - are no clients connected. We don't want to connect them by telling - MC that we're going online -- we'd like to be more passive than that. */ - if (mcstatus == MC_STATUS_UNSET) { - return; - } - - ret = dbus_g_proxy_call(priv->proxy, - "SetPresence", &error, - G_TYPE_UINT, priv->mc_status, - G_TYPE_STRING, "", - G_TYPE_INVALID, - G_TYPE_INVALID); - - if (!ret) { - if (error != NULL) { - g_warning("Unable to set Mission Control Presence: %s", error->message); - g_error_free(error); - } else { - g_warning("Unable to set Mission Control Presence"); - } - return; - } - - return; -} - -static StatusProviderStatus -get_status (StatusProvider * sp) -{ - g_return_val_if_fail(IS_STATUS_PROVIDER_TELEPATHY(sp), STATUS_PROVIDER_STATUS_DISCONNECTED); - StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(sp); - - if (priv->proxy == NULL) { - return STATUS_PROVIDER_STATUS_DISCONNECTED; - } - - return mc_to_sp_map[priv->mc_status]; -} - -static void -changed_status (DBusGProxy * proxy, guint status, gchar * message, StatusProvider * sp) -{ - StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(sp); - priv->mc_status = status; - g_signal_emit(G_OBJECT(sp), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, mc_to_sp_map[priv->mc_status], TRUE); -} - -static void -proxy_destroy (DBusGProxy * proxy, StatusProvider * sp) -{ - g_debug("Signal: Mission Control proxy destroyed"); - g_signal_emit(G_OBJECT(sp), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, STATUS_PROVIDER_STATUS_OFFLINE, TRUE); - return; -} - -static void -get_status_async (DBusGProxy * proxy, DBusGProxyCall * call, gpointer userdata) -{ - GError * error = NULL; - guint status = 0; - if (!dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_UINT, &status, G_TYPE_INVALID)) { - g_warning("Unable to get type from Mission Control: %s", error->message); - g_error_free(error); - return; - } - - StatusProviderTelepathyPrivate * priv = STATUS_PROVIDER_TELEPATHY_GET_PRIVATE(userdata); - - gboolean changed = FALSE; - if (status != priv->mc_status) { - changed = TRUE; - } - - priv->mc_status = status; - - if (changed) { - g_signal_emit(G_OBJECT(userdata), STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID, 0, mc_to_sp_map[priv->mc_status], TRUE); - } - - return; -} diff --git a/src/status-provider-telepathy.h b/src/status-provider-telepathy.h deleted file mode 100644 index a67ee40..0000000 --- a/src/status-provider-telepathy.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef __STATUS_PROVIDER_TELEPATHY_H__ -#define __STATUS_PROVIDER_TELEPATHY_H__ - -#include <glib.h> -#include <glib-object.h> - -#include "status-provider.h" - -G_BEGIN_DECLS - -#define STATUS_PROVIDER_TELEPATHY_TYPE (status_provider_telepathy_get_type ()) -#define STATUS_PROVIDER_TELEPATHY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STATUS_PROVIDER_TELEPATHY_TYPE, StatusProviderTelepathy)) -#define STATUS_PROVIDER_TELEPATHY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STATUS_PROVIDER_TELEPATHY_TYPE, StatusProviderTelepathyClass)) -#define IS_STATUS_PROVIDER_TELEPATHY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STATUS_PROVIDER_TELEPATHY_TYPE)) -#define IS_STATUS_PROVIDER_TELEPATHY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), STATUS_PROVIDER_TELEPATHY_TYPE)) -#define STATUS_PROVIDER_TELEPATHY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STATUS_PROVIDER_TELEPATHY_TYPE, StatusProviderTelepathyClass)) - - -typedef struct _StatusProviderTelepathyClass StatusProviderTelepathyClass; -struct _StatusProviderTelepathyClass { - StatusProviderClass parent_class; -}; - -typedef struct _StatusProviderTelepathy StatusProviderTelepathy; -struct _StatusProviderTelepathy { - StatusProvider parent; -}; - -GType status_provider_telepathy_get_type (void); -StatusProvider * status_provider_telepathy_new (void); - -G_END_DECLS - -#endif diff --git a/src/status-provider-telepathy.list b/src/status-provider-telepathy.list deleted file mode 100644 index 5ab45bf..0000000 --- a/src/status-provider-telepathy.list +++ /dev/null @@ -1 +0,0 @@ -VOID:UINT,STRING diff --git a/src/status-provider.c b/src/status-provider.c deleted file mode 100644 index 1139e54..0000000 --- a/src/status-provider.c +++ /dev/null @@ -1,101 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "status-provider.h" - -/* Signals */ -enum { - STATUS_CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -/* GObject Boilerplate */ -static void status_provider_class_init (StatusProviderClass *klass); -static void status_provider_init (StatusProvider *self); - -G_DEFINE_TYPE (StatusProvider, status_provider, G_TYPE_OBJECT); - -static void -status_provider_class_init (StatusProviderClass *klass) -{ - // GObjectClass *object_class = G_OBJECT_CLASS (klass); - - klass->status_changed = NULL; - - klass->set_status = NULL; - klass->get_status = NULL; - - /** - StatusProvider::status-changed: - @arg0: The #StatusProvider object. - @arg1: The new status #StatusProviderStatus - - Should be emitted by subclasses everytime that the status - changes externally to us. - */ - signals[STATUS_CHANGED] = g_signal_new(STATUS_PROVIDER_SIGNAL_STATUS_CHANGED, - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(StatusProviderClass, status_changed), - NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, G_TYPE_UINT); - - return; -} - -static void -status_provider_init (StatusProvider *self) -{ - - return; -} - -void -status_provider_set_status (StatusProvider * sp, StatusProviderStatus status) -{ - g_return_if_fail(IS_STATUS_PROVIDER(sp)); - - StatusProviderClass * class = STATUS_PROVIDER_GET_CLASS(sp); - g_return_if_fail(class != NULL); - g_return_if_fail(class->set_status != NULL); - - return class->set_status(sp, status); -} - -StatusProviderStatus -status_provider_get_status (StatusProvider * sp) -{ - g_return_val_if_fail(IS_STATUS_PROVIDER(sp), STATUS_PROVIDER_STATUS_OFFLINE); - - StatusProviderClass * class = STATUS_PROVIDER_GET_CLASS(sp); - g_return_val_if_fail(class->get_status != NULL, STATUS_PROVIDER_STATUS_OFFLINE); - - return class->get_status(sp); -} - diff --git a/src/status-provider.h b/src/status-provider.h deleted file mode 100644 index 45433fc..0000000 --- a/src/status-provider.h +++ /dev/null @@ -1,81 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould <ted@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef __STATUS_PROVIDER_H__ -#define __STATUS_PROVIDER_H__ - -#include <glib.h> -#include <glib-object.h> - -G_BEGIN_DECLS - -#define STATUS_PROVIDER_EXPORT_TYPE(x) GType status_provider_export_type (void) { return (x); } -#define STATUS_PROVIDER_EXPORT_S "status_provider_export_type" - -#define STATUS_PROVIDER_TYPE (status_provider_get_type ()) -#define STATUS_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STATUS_PROVIDER_TYPE, StatusProvider)) -#define STATUS_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STATUS_PROVIDER_TYPE, StatusProviderClass)) -#define IS_STATUS_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STATUS_PROVIDER_TYPE)) -#define IS_STATUS_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), STATUS_PROVIDER_TYPE)) -#define STATUS_PROVIDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STATUS_PROVIDER_TYPE, StatusProviderClass)) - -typedef enum -{ - STATUS_PROVIDER_STATUS_ONLINE, - STATUS_PROVIDER_STATUS_AWAY, - STATUS_PROVIDER_STATUS_DND, - STATUS_PROVIDER_STATUS_INVISIBLE, - STATUS_PROVIDER_STATUS_OFFLINE, - STATUS_PROVIDER_STATUS_DISCONNECTED, - /* Leave as last */ - STATUS_PROVIDER_STATUS_LAST -} -StatusProviderStatus; - -#define STATUS_PROVIDER_SIGNAL_STATUS_CHANGED "status-changed" -#define STATUS_PROVIDER_SIGNAL_STATUS_CHANGED_ID (g_signal_lookup(STATUS_PROVIDER_SIGNAL_STATUS_CHANGED, STATUS_PROVIDER_TYPE)) - -typedef struct _StatusProvider StatusProvider; -struct _StatusProvider { - GObject parent; -}; - -typedef struct _StatusProviderClass StatusProviderClass; -struct _StatusProviderClass { - GObjectClass parent_class; - - /* Signals */ - void (*status_changed) (StatusProviderStatus newstatus); - - /* Virtual Functions */ - void (*set_status) (StatusProvider * sp, StatusProviderStatus newstatus); - StatusProviderStatus (*get_status) (StatusProvider * sp); -}; - -GType status_provider_get_type (void); - -void status_provider_set_status (StatusProvider * sp, StatusProviderStatus status); -StatusProviderStatus status_provider_get_status (StatusProvider * sp); - -G_END_DECLS - -#endif |