aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.build.yml103
-rw-r--r--CMakeLists.txt71
-rw-r--r--Makefile.am25
-rw-r--r--Makefile.am.coverage47
-rwxr-xr-xautogen.sh9
-rw-r--r--cmake/GdbusCodegen.cmake36
-rw-r--r--configure.ac98
-rw-r--r--data/CMakeLists.txt15
-rw-r--r--data/Makefile.am34
-rw-r--r--data/ayatana-indicator-printers.desktop.in2
-rw-r--r--data/ayatana-indicator-printers.service.in2
-rw-r--r--data/org.ayatana.indicator.printers11
-rw-r--r--debian/control11
-rwxr-xr-xdebian/rules24
-rw-r--r--m4/gcov.m486
-rw-r--r--po/CMakeLists.txt2
-rw-r--r--src/CMakeLists.txt22
-rw-r--r--src/Makefile.am53
-rw-r--r--src/indicator-menu-item.c395
-rw-r--r--src/indicator-menu-item.h81
-rw-r--r--src/indicator-printer-state-notifier.c36
-rw-r--r--src/indicator-printers-menu.c334
-rw-r--r--src/indicator-printers-menu.h76
-rw-r--r--src/indicator-printers-service.c567
-rw-r--r--src/indicator-printers-service.h52
-rw-r--r--src/indicator-printers.c303
-rw-r--r--src/indicator-printers.h70
-rw-r--r--src/main.c47
-rw-r--r--test/CMakeLists.txt12
-rw-r--r--test/Makefile.am30
-rwxr-xr-xupdate-po.sh2
-rwxr-xr-xupdate-pot.sh2
32 files changed, 772 insertions, 1886 deletions
diff --git a/.build.yml b/.build.yml
index 69b5920..1ef8055 100644
--- a/.build.yml
+++ b/.build.yml
@@ -3,58 +3,50 @@
##########################################################
requires:
archlinux:
- # Useful URL: https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=ayatana-indicator-session
+ # Useful URL: https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=ayatana-indicator-printers
- clang
- gcc
- git
- make
- startup-notification
- which
-# - cmake
-# - cmake-extras
- - mate-common
+ - cmake
+ - cmake-extras
- intltool
- - ayatana-indicator3
- - gobject-introspection
- glib2
+ - libayatana-common
+ - libcups
- systemd
+ - cups
debian:
- # Useful URL: https://salsa.debian.org/debian-ayatana-team/ayatana-session
- - autopoint
+ # Useful URL: https://salsa.debian.org/debian-ayatana-team/ayatana-printers
- clang
- clang-tools
- g++
- cppcheck
- git
-# - cmake
-# - cmake-extras
- - mate-common
+ - cmake
+ - cmake-extras
- intltool
- libglib2.0-dev
- - libgtk-3-dev
- - libdbusmenu-glib-dev
- - libdbusmenu-gtk3-dev
- - libayatana-indicator3-dev
- libcups2-dev
+# - libayatana-common-dev
+ - liblomiri-url-dispatcher-dev
- dbus
ubuntu:
- - autopoint
- clang
- clang-tools
- g++
- git
-# - cmake
-# - cmake-extras
- - mate-common
+ - cmake
+ - cmake-extras
- intltool
- libglib2.0-dev
- - libgtk-3-dev
- - libdbusmenu-glib-dev
- - libdbusmenu-gtk3-dev
- - libayatana-indicator3-dev
- libcups2-dev
+# - libayatana-common-dev
+# - liblomiri-url-dispatcher-dev
variables:
- 'CHECKERS="
@@ -74,45 +66,32 @@ variables:
-enable-checker alpha.core.FixedAddr
-enable-checker security.insecureAPI.strcpy"'
-### the printers indicator requires a very old version of libayatana-indicator, so no need to
-### build it from source here. Leaving the ruleset here, nonetheless.
+before_scripts:
+ - cd ${START_DIR}
+ - if [ ! -d libayatana-common-build ]; then
+ - git clone --depth 1 https://github.com/AyatanaIndicators/libayatana-common.git libayatana-common-build
+ - fi
+ - cd libayatana-common-build
+ - if [ ${DISTRO_NAME} == "debian" ]; then
+ - cmake . -DCMAKE_INSTALL_PREFIX=/usr -DENABLE_LOMIRI_FEATURES=ON
+ - else
+ - cmake . -DCMAKE_INSTALL_PREFIX=/usr
+ - fi
+ - make
+ - make install
+ - cd -
+ - rm -Rf libayatana-common-build/
-#before_scripts:
-# - cd ${START_DIR}
-# - if [ ! -d ayatana-ido-build ]; then
-# - git clone --depth 1 https://github.com/AyatanaIndicators/ayatana-ido.git ayatana-ido-build
-# - fi
-# - cd ayatana-ido-build
-# - cmake . -DCMAKE_INSTALL_PREFIX=/usr
-# - make
-# - make install
-# - cd -
-# - rm -Rf ayatana-ido-build/
-# -
-# - cd ${START_DIR}
-# - if [ ! -d libayatana-indicator-build ]; then
-# - git clone --depth 1 https://github.com/AyatanaIndicators/libayatana-indicator.git libayatana-indicator-build
-# - fi
-# - cd libayatana-indicator-build
-# - cmake . -DCMAKE_INSTALL_PREFIX=/usr
-# - make
-# - make install
-# - cd -
-# - rm -Rf libayatana-indicator-build/
-#
build_scripts:
- if [ ${DISTRO_NAME} == "debian" ];then
- cppcheck --enable=warning,style,performance,portability,information,missingInclude .
- fi
-
- - if [ -e ./autogen.sh ]; then
- - NOCONFIGURE=1 ./autogen.sh
- - scan-build $CHECKERS ./configure --prefix=/usr --enable-gtk-doc --enable-compile-warnings=maximum
- - elif [ -e ./CMakeLists.txt ]; then
+ - if [ -e ./CMakeLists.txt ]; then
- if [ ${DISTRO_NAME} == "debian" ] || [ ${DISTRO_NAME} == "ubuntu" ]; then
- - scan-build $CHECKERS cmake . -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_TESTS=ON
+ - scan-build $CHECKERS cmake . -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_WERROR=ON -DENABLE_TESTS=ON
- else
- - scan-build $CHECKERS cmake . -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_VERBOSE_MAKEFILE=ON
+ - scan-build $CHECKERS cmake . -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_WERROR=ON
- fi
- else
- exit 1
@@ -131,12 +110,10 @@ build_scripts:
- fi
- scan-build $CHECKERS --keep-cc -o html-report make
- fi
-# -
-# - XVFB_RUN="$(which xvfb-run || true)"
-# - if [ ${DISTRO_NAME} == "debian" ] || [ ${DISTRO_NAME} == "ubuntu" ];then
-# - if [ -e ./autogen.sh ]; then
-# - ${XVFB_RUN} make check
-# - elif [ -e ./CMakeLists.txt ]; then
-# - ${XVFB_RUN} env CTEST_OUTPUT_ON_FAILURE=1 make test
-# - fi
-# - fi
+ -
+ - XVFB_RUN="$(which xvfb-run || true)"
+ - if [ ${DISTRO_NAME} == "debian" ] || [ ${DISTRO_NAME} == "ubuntu" ];then
+ - if [ -e ./CMakeLists.txt ]; then
+ - ${XVFB_RUN} env CTEST_OUTPUT_ON_FAILURE=1 make test
+ - fi
+ - fi
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..892b0e9
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,71 @@
+project (ayatana-indicator-printers C)
+cmake_minimum_required (VERSION 3.13)
+
+if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+ SET (CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "..." FORCE)
+endif (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+
+list (APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
+
+set (PROJECT_VERSION "22.2.0")
+set (PACKAGE ${CMAKE_PROJECT_NAME})
+set (GETTEXT_PACKAGE "ayatana-indicator-printers")
+
+# Options
+option (ENABLE_TESTS "Enable all tests and checks" OFF)
+option (ENABLE_COVERAGE "Enable coverage reports (includes enabling all tests and checks)" OFF)
+option (ENABLE_WERROR "Treat all build warnings as errors" OFF)
+
+if (ENABLE_COVERAGE)
+ set (ENABLE_TESTS ON)
+ set (CMAKE_BUILD_TYPE "Coverage")
+else ()
+ set (CMAKE_BUILD_TYPE "Release")
+endif ()
+
+if (ENABLE_WERROR)
+ add_definitions ("-Werror")
+endif ()
+
+if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+ add_definitions ("-Weverything")
+else ()
+ add_definitions ("-Wall")
+endif ()
+
+# Check for prerequisites
+include (GNUInstallDirs)
+find_package (PkgConfig REQUIRED)
+include (FindPkgConfig)
+pkg_check_modules (SERVICE REQUIRED glib-2.0>=2.36 gio-2.0>=2.36 gio-unix-2.0>=2.36 libayatana-common)
+find_program (CUPS_CONFIG cups-config REQUIRED)
+execute_process (COMMAND ${CUPS_CONFIG} --cflags OUTPUT_VARIABLE CUPS_CFLAGS)
+execute_process (COMMAND ${CUPS_CONFIG} --libs OUTPUT_VARIABLE CUPS_LIBS)
+list (APPEND SERVICE_CFLAGS ${CUPS_CFLAGS})
+list (APPEND SERVICE_LDFLAGS ${CUPS_LIBS})
+list (APPEND SERVICE_LIBRARIES "cups")
+
+# Custom targets
+set (ARCHIVE_NAME ${CMAKE_PROJECT_NAME}-${PROJECT_VERSION})
+add_custom_target (dist COMMAND bzr export --root=${ARCHIVE_NAME} ${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}.tar.gz WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+add_custom_target (cppcheck COMMAND cppcheck --enable=all -q --error-exitcode=2 --inline-suppr ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/test)
+
+# Build
+add_subdirectory (src)
+add_subdirectory (data)
+add_subdirectory (po)
+
+if (ENABLE_TESTS)
+ include (CTest)
+ enable_testing ()
+ add_subdirectory (test)
+ if (ENABLE_COVERAGE)
+ find_package (CoverageReport)
+ ENABLE_COVERAGE_REPORT (TARGETS "ayatanaindicatorprintersservice" "ayatana-indicator-printers-service" TESTS "mock-cups-notifier" FILTER /usr/include ${CMAKE_BINARY_DIR}/*)
+ endif ()
+endif ()
+
+# Display config info
+message (STATUS "Install prefix: ${CMAKE_INSTALL_PREFIX}")
+message (STATUS "Unit tests: ${ENABLE_TESTS}")
+message (STATUS "Build with -Werror: ${ENABLE_WERROR}")
diff --git a/Makefile.am b/Makefile.am
deleted file mode 100644
index 26e7118..0000000
--- a/Makefile.am
+++ /dev/null
@@ -1,25 +0,0 @@
-SUBDIRS = src data test po
-
-include $(top_srcdir)/Makefile.am.coverage
-
-DISTCLEANFILES = \
- INSTALL \
- Makefile.in \
- aclocal.m4 \
- compile \
- configure \
- config.h.in \
- config.h \
- config.sub \
- config.guess \
- depcomp \
- install-sh \
- ltmain.sh \
- missing \
- m4/intltool.m4 \
- m4/libtool.m4 \
- m4/ltoptions.m4 \
- m4/ltsugar.m4 \
- m4/ltversion.m4 \
- m4/lt~obsolete.m4 \
- po/Makefile.in.in
diff --git a/Makefile.am.coverage b/Makefile.am.coverage
deleted file mode 100644
index 7d2d43f..0000000
--- a/Makefile.am.coverage
+++ /dev/null
@@ -1,47 +0,0 @@
-# Coverage targets
-
-.PHONY: clean-gcno clean-gcda \
- coverage-html generate-coverage-html clean-coverage-html \
- coverage-gcovr generate-coverage-gcovr clean-coverage-gcovr
-
-clean-local: clean-gcno clean-coverage-html clean-coverage-gcovr
-
-if HAVE_GCOV
-
-clean-gcno:
- @echo Removing old coverage instrumentation
- -find -name '*.gcno' -print | xargs -r rm
-
-clean-gcda:
- @echo Removing old coverage results
- -find -name '*.gcda' -print | xargs -r rm
-
-coverage-html: clean-gcda
- -$(MAKE) $(AM_MAKEFLAGS) -k check
- $(MAKE) $(AM_MAKEFLAGS) generate-coverage-html
-
-generate-coverage-html:
- @echo Collecting coverage data
- $(LCOV) --directory $(top_builddir) --capture --output-file coverage.info --no-checksum --compat-libtool
- LANG=C $(GENHTML) --prefix $(top_builddir) --output-directory coveragereport --title "Code Coverage" --legend --show-details coverage.info
-
-clean-coverage-html: clean-gcda
- -$(LCOV) --directory $(top_builddir) -z
- -rm -rf coverage.info coveragereport
-
-if HAVE_GCOVR
-
-coverage-gcovr: clean-gcda
- -$(MAKE) $(AM_MAKEFLAGS) -k check
- $(MAKE) $(AM_MAKEFLAGS) generate-coverage-gcovr
-
-generate-coverage-gcovr:
- @echo Generating coverage GCOVR report
- $(GCOVR) -x -r $(top_builddir) -o $(top_builddir)/coverage.xml
-
-clean-coverage-gcovr: clean-gcda
- -rm -rf $(top_builddir)/coverage.xml
-
-endif # HAVE_GCOVR
-
-endif # HAVE_GCOV
diff --git a/autogen.sh b/autogen.sh
deleted file mode 100755
index 0478484..0000000
--- a/autogen.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/sh
-
-which mate-autogen || {
- echo "Could not find 'mate-autgen'. Is mate-common installed?"
- exit 1
-}
-
-. mate-autogen
-
diff --git a/cmake/GdbusCodegen.cmake b/cmake/GdbusCodegen.cmake
new file mode 100644
index 0000000..5261ba8
--- /dev/null
+++ b/cmake/GdbusCodegen.cmake
@@ -0,0 +1,36 @@
+cmake_minimum_required(VERSION 3.13)
+if(POLICY CMP0011)
+ cmake_policy(SET CMP0011 NEW)
+endif(POLICY CMP0011)
+
+find_program(GDBUS_CODEGEN NAMES gdbus-codegen DOC "gdbus-codegen executable")
+if(NOT GDBUS_CODEGEN)
+ message(FATAL_ERROR "Excutable gdbus-codegen not found")
+endif()
+
+macro(add_gdbus_codegen outfiles name prefix service_xml)
+ add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${name}.h" "${CMAKE_CURRENT_BINARY_DIR}/${name}.c"
+ COMMAND "${GDBUS_CODEGEN}"
+ --interface-prefix "${prefix}"
+ --generate-c-code "${name}"
+ "${service_xml}"
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS ${ARGN} "${service_xml}"
+ )
+ list(APPEND ${outfiles} "${CMAKE_CURRENT_BINARY_DIR}/${name}.c")
+endmacro(add_gdbus_codegen)
+
+macro(add_gdbus_codegen_with_namespace outfiles name prefix namespace service_xml)
+ add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${name}.h" "${CMAKE_CURRENT_BINARY_DIR}/${name}.c"
+ COMMAND "${GDBUS_CODEGEN}"
+ --interface-prefix "${prefix}"
+ --generate-c-code "${name}"
+ --c-namespace "${namespace}"
+ "${service_xml}"
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS ${ARGN} "${service_xml}"
+ )
+ list(APPEND ${outfiles} "${CMAKE_CURRENT_BINARY_DIR}/${name}.c")
+endmacro(add_gdbus_codegen_with_namespace)
diff --git a/configure.ac b/configure.ac
deleted file mode 100644
index b47ddb6..0000000
--- a/configure.ac
+++ /dev/null
@@ -1,98 +0,0 @@
-AC_INIT(ayatana-indicator-printers, 22.2.0)
-
-AC_PREREQ(2.53)
-AM_INIT_AUTOMAKE([])
-
-AC_PROG_CC
-AC_PROG_INSTALL
-AC_PROG_LIBTOOL
-AM_PROG_CC_C_O
-AM_SILENT_RULES([yes])
-AC_CONFIG_MACRO_DIR([m4])
-
-AC_DEFUN([AC_DEFINE_PATH], [
- test "x$prefix" = xNONE && prefix="$ac_default_prefix"
- test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
- ac_define_path=`eval echo [$]$2`
- ac_define_path=`eval echo [$]ac_define_path`
- $1="$ac_define_path"
- AC_SUBST($1)
- ifelse($3, ,
- AC_DEFINE_UNQUOTED($1, "$ac_define_path"),
- AC_DEFINE_UNQUOTED($1, "$ac_define_path", $3))
-])
-
-IT_PROG_INTLTOOL([0.35.0])
-GETTEXT_PACKAGE=ayatana-indicator-printers
-AC_SUBST(GETTEXT_PACKAGE)
-AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [gettext package])
-AC_DEFINE_PATH(LOCALEDIR, "${datadir}/locale", [locale directory])
-AM_GLIB_GNU_GETTEXT
-
-AC_CONFIG_HEADER(config.h)
-AC_CONFIG_FILES([
- Makefile
- src/Makefile
- data/Makefile
- test/Makefile
- po/Makefile.in
-])
-
-PKG_CHECK_MODULES(APPLET, gtk+-3.0 >= 3.0
- ayatana-indicator3-0.4 >= 0.2
- dbusmenu-gtk3-0.4 >= 0.2)
-PKG_CHECK_MODULES(SERVICE, gtk+-3.0 >= 3.0
- ayatana-indicator3-0.4 >= 0.2
- dbusmenu-glib-0.4 >= 0.2)
-
-AC_PATH_PROG(CUPS_CONFIG, cups-config, no)
-if test "x$CUPS_CONFIG" = "xno"; then
- AC_MSG_ERROR([could not find cups-config])
-fi
-AC_CHECK_HEADER(cups/cups.h,,AC_MSG_ERROR([could not find cups.h]))
-CUPS_CFLAGS=`$CUPS_CONFIG --cflags`
-CUPS_LIBS=`$CUPS_CONFIG --libs`
-SERVICE_CFLAGS="$SERVICE_CFLAGS $CUPS_CFLAGS"
-SERVICE_LIBS="$SERVICE_LIBS $CUPS_LIBS"
-
-#########################
-# Check for systemd
-#########################
-PKG_CHECK_MODULES(SYSTEMD, systemd,
- [has_systemd=yes],
- []
-)
-if test "x$has_systemd" = "xyes"; then
- SYSTEMD_USERDIR=`$PKG_CONFIG --variable=systemduserunitdir systemd`
- AC_SUBST(SYSTEMD_USERDIR)
- AC_DEFINE(HAVE_SYSTEMD, 1, [create ayatana-indicator-printers.service for systemd])
-fi
-
-INDICATORDIR=`$PKG_CONFIG --variable=indicatordir ayatana-indicator3-0.4`
-INDICATORICONSDIR=`$PKG_CONFIG --variable=iconsdir ayatana-indicator3-0.4`
-
-AC_SUBST(INDICATORDIR)
-AC_SUBST(INDICATORICONSDIR)
-
-###########################
-# DBus Service Info
-###########################
-
-DBUSSERVICEDIR=`$PKG_CONFIG --variable=session_bus_services_dir dbus-1`
-AC_SUBST(DBUSSERVICEDIR)
-
-###########################
-# gcov coverage reporting
-###########################
-
-m4_include([m4/gcov.m4])
-AC_TDD_GCOV
-AM_CONDITIONAL([HAVE_GCOV], [test "x$ac_cv_check_gcov" = xyes])
-AM_CONDITIONAL([HAVE_LCOV], [test "x$ac_cv_check_lcov" = xyes])
-AM_CONDITIONAL([HAVE_GCOVR], [test "x$ac_cv_check_gcovr" = xyes])
-AC_SUBST(COVERAGE_CFLAGS)
-AC_SUBST(COVERAGE_LDFLAGS)
-
-AC_SUBST(AM_CFLAGS, "-Wall")
-
-AC_OUTPUT
diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt
new file mode 100644
index 0000000..ac6a6c6
--- /dev/null
+++ b/data/CMakeLists.txt
@@ -0,0 +1,15 @@
+# ayatana-indicator-printers.service
+pkg_check_modules (SYSTEMD systemd)
+
+if (${SYSTEMD_FOUND})
+ pkg_get_variable (SYSTEMD_USER_DIR systemd systemduserunitdir)
+ configure_file ("${CMAKE_CURRENT_SOURCE_DIR}/ayatana-indicator-printers.service.in" "${CMAKE_CURRENT_BINARY_DIR}/ayatana-indicator-printers.service" @ONLY)
+ install (FILES "${CMAKE_CURRENT_BINARY_DIR}/ayatana-indicator-printers.service" DESTINATION "${SYSTEMD_USER_DIR}")
+endif ()
+
+# ayatana-indicator-printers.desktop
+configure_file ("${CMAKE_CURRENT_SOURCE_DIR}/ayatana-indicator-printers.desktop.in" "${CMAKE_CURRENT_BINARY_DIR}/ayatana-indicator-printers.desktop" @ONLY)
+install (FILES "${CMAKE_CURRENT_BINARY_DIR}/ayatana-indicator-printers.desktop" DESTINATION "/etc/xdg/autostart")
+
+# org.ayatana.indicator.printers
+install (FILES "${CMAKE_CURRENT_SOURCE_DIR}/org.ayatana.indicator.printers" DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/ayatana/indicators")
diff --git a/data/Makefile.am b/data/Makefile.am
deleted file mode 100644
index 8bf680d..0000000
--- a/data/Makefile.am
+++ /dev/null
@@ -1,34 +0,0 @@
-BUILT_SOURCES=
-CLEANFILES=
-EXTRA_DIST=
-
-#
-# the systemd unit file
-#
-
-#if defined(HAVE_SYSTEMD)
-systemddir = $(SYSTEMD_USERDIR)
-systemd_DATA = ayatana-indicator-printers.service
-systemd_in = $(systemd_DATA:.service=.service.in)
-$(systemd_DATA): $(systemd_in)
- $(AM_V_GEN) $(SED) -e "s|\@pkglibexecdir\@|$(pkglibexecdir)|" $< > $@
-BUILT_SOURCES += $(systemd_DATA)
-EXTRA_DIST += $(systemd_in)
-CLEANFILES += $(systemd_DATA)
-#endif
-
-#
-# the xdg autostart job file
-#
-
-xdg_autostartdir = /etc/xdg/autostart
-xdg_autostart_DATA = ayatana-indicator-printers.desktop
-xdg_autostart_in = $(xdg_autostart_DATA:.desktop=.desktop.in)
-$(xdg_autostart_DATA): $(xdg_autostart_in)
- $(AM_V_GEN) $(SED) -e "s|\@pkglibexecdir\@|$(pkglibexecdir)|" $< > $@
-BUILT_SOURCES += $(xdg_autostart_DATA)
-CLEANFILES += $(xdg_autostart_DATA)
-EXTRA_DIST += $(xdg_autostart_in)
-
-DISTCLEANFILES = \
- Makefile.in
diff --git a/data/ayatana-indicator-printers.desktop.in b/data/ayatana-indicator-printers.desktop.in
index e0f74b0..1027096 100644
--- a/data/ayatana-indicator-printers.desktop.in
+++ b/data/ayatana-indicator-printers.desktop.in
@@ -1,7 +1,7 @@
[Desktop Entry]
Type=Application
Name=Ayatana Indicator Printers
-Exec=@pkglibexecdir@/ayatana-indicator-printers-service
+Exec=@CMAKE_INSTALL_FULL_LIBEXECDIR@/ayatana-indicator-printers/ayatana-indicator-printers-service
OnlyShowIn=MATE;XFCE;Budgie
NoDisplay=true
StartupNotify=false
diff --git a/data/ayatana-indicator-printers.service.in b/data/ayatana-indicator-printers.service.in
index 781f3e6..e482f96 100644
--- a/data/ayatana-indicator-printers.service.in
+++ b/data/ayatana-indicator-printers.service.in
@@ -4,7 +4,7 @@ PartOf=graphical-session.target
PartOf=ayatana-indicators.target
[Service]
-ExecStart=@pkglibexecdir@/ayatana-indicator-printers-service
+ExecStart=@CMAKE_INSTALL_FULL_LIBEXECDIR@/ayatana-indicator-printers/ayatana-indicator-printers-service
Restart=on-failure
[Install]
diff --git a/data/org.ayatana.indicator.printers b/data/org.ayatana.indicator.printers
new file mode 100644
index 0000000..d9fe355
--- /dev/null
+++ b/data/org.ayatana.indicator.printers
@@ -0,0 +1,11 @@
+[Indicator Service]
+Name=ayatana-indicator-printers
+ObjectPath=/org/ayatana/indicator/printers
+Position=100
+
+[phone]
+ObjectPath=/org/ayatana/indicator/printers/phone
+Position=25
+
+[desktop]
+ObjectPath=/org/ayatana/indicator/printers/desktop
diff --git a/debian/control b/debian/control
index 3e98b9c..040ff2b 100644
--- a/debian/control
+++ b/debian/control
@@ -3,17 +3,14 @@ Section: x11
Priority: extra
Maintainer: Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
Build-Depends: debhelper (>= 10),
- autotools-dev,
- dh-autoreconf | debhelper (>= 9.20160403~),
+ cmake,
+ cmake-extras,
dh-systemd | debhelper (>= 10.2~),
dpkg-dev (>= 1.16.1.1),
- mate-common,
+ intltool,
libglib2.0-dev (>= 2.43.2),
- libgtk-3-dev,
- libdbusmenu-glib-dev (>= 0.5.90),
- libdbusmenu-gtk3-dev (>= 0.5.90),
- libayatana-indicator3-dev (>= 0.3.91),
libcups2-dev,
+ libayatana-common-dev,
systemd [linux-any],
Standards-Version: 4.1.1
Homepage: https://github.com/AyatanaIndicators/ayatana-indicator-printers
diff --git a/debian/rules b/debian/rules
index ba2e36f..fac96d4 100755
--- a/debian/rules
+++ b/debian/rules
@@ -1,28 +1,32 @@
#!/usr/bin/make -f
+export DPKG_GENSYMBOLS_CHECK_LEVEL=4
+
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
DPKG_EXPORT_BUILDFLAGS = 1
include /usr/share/dpkg/buildflags.mk
-CFLAGS += -Wno-error=deprecated-declarations
-LDFLAGS += -Wl,-z,defs -Wl,--as-needed
+DEB_CMAKE_EXTRA_FLAGS = \
+ -DENABLE_TESTS=ON \
+ -DENABLE_COVERAGE=OFF \
+ $(NULL)
export DPKG_GENSYMBOLS_CHECK_LEVEL = 4
%:
- dh $@ --without autoreconf,systemd
+ dh $@ --with systemd
override_dh_auto_configure:
- NOCONFIGURE=1 ./autogen.sh
- dh_auto_configure -- \
- --disable-static
+ dh_auto_configure -- $(DEB_CMAKE_EXTRA_FLAGS)
override_dh_install:
find debian/ayatana-indicator-printers -name \*.la -delete
find debian/ayatana-indicator-printers -name \*.a -delete
dh_install --fail-missing
-override_dh_auto_clean:
- dh_auto_clean
- # no clue, why they don't disappear during make distclean...
- rm -f config.sub config.guess
+# Hack as it seems it's not possible to easy run that under dbus-test-runner
+override_dh_auto_test:
+ env -u LD_PRELOAD dh_auto_test
+
+get-orig-source:
+ uscan --noconf --force-download --rename --download-current-version --destdir=..
diff --git a/m4/gcov.m4 b/m4/gcov.m4
deleted file mode 100644
index 3163584..0000000
--- a/m4/gcov.m4
+++ /dev/null
@@ -1,86 +0,0 @@
-# Checks for existence of coverage tools:
-# * gcov
-# * lcov
-# * genhtml
-# * gcovr
-#
-# Sets ac_cv_check_gcov to yes if tooling is present
-# and reports the executables to the variables LCOV, GCOVR and GENHTML.
-AC_DEFUN([AC_TDD_GCOV],
-[
- AC_ARG_ENABLE(gcov,
- AS_HELP_STRING([--enable-gcov],
- [enable coverage testing with gcov]),
- [use_gcov=$enableval], [use_gcov=no])
-
- if test "x$use_gcov" = "xyes"; then
- # we need gcc:
- if test "$GCC" != "yes"; then
- AC_MSG_ERROR([GCC is required for --enable-gcov])
- fi
-
- # Check if ccache is being used
- AC_CHECK_PROG(SHTOOL, shtool, shtool)
- case `$SHTOOL path $CC` in
- *ccache*[)] gcc_ccache=yes;;
- *[)] gcc_ccache=no;;
- esac
-
- if test "$gcc_ccache" = "yes" && (test -z "$CCACHE_DISABLE" || test "$CCACHE_DISABLE" != "1"); then
- AC_MSG_ERROR([ccache must be disabled when --enable-gcov option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.])
- fi
-
- lcov_version_list="1.6 1.7 1.8 1.9"
- AC_CHECK_PROG(LCOV, lcov, lcov)
- AC_CHECK_PROG(GENHTML, genhtml, genhtml)
-
- if test "$LCOV"; then
- AC_CACHE_CHECK([for lcov version], glib_cv_lcov_version, [
- glib_cv_lcov_version=invalid
- lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'`
- for lcov_check_version in $lcov_version_list; do
- if test "$lcov_version" = "$lcov_check_version"; then
- glib_cv_lcov_version="$lcov_check_version (ok)"
- fi
- done
- ])
- else
- lcov_msg="To enable code coverage reporting you must have one of the following lcov versions installed: $lcov_version_list"
- AC_MSG_ERROR([$lcov_msg])
- fi
-
- case $glib_cv_lcov_version in
- ""|invalid[)]
- lcov_msg="You must have one of the following versions of lcov: $lcov_version_list (found: $lcov_version)."
- AC_MSG_ERROR([$lcov_msg])
- LCOV="exit 0;"
- ;;
- esac
-
- if test -z "$GENHTML"; then
- AC_MSG_ERROR([Could not find genhtml from the lcov package])
- fi
-
- ac_cv_check_gcov=yes
- ac_cv_check_lcov=yes
-
- # Remove all optimization flags from CFLAGS
- changequote({,})
- CFLAGS=`echo "$CFLAGS" | $SED -e 's/-O[0-9]*//g'`
- changequote([,])
-
- # Add the special gcc flags
- COVERAGE_CFLAGS="-O0 -fprofile-arcs -ftest-coverage"
- COVERAGE_CXXFLAGS="-O0 -fprofile-arcs -ftest-coverage"
- COVERAGE_LDFLAGS="-lgcov"
-
- # Check availability of gcovr
- AC_CHECK_PROG(GCOVR, gcovr, gcovr)
- if test -z "$GCOVR"; then
- ac_cv_check_gcovr=no
- else
- ac_cv_check_gcovr=yes
- fi
-
-fi
-]) # AC_TDD_GCOV
diff --git a/po/CMakeLists.txt b/po/CMakeLists.txt
new file mode 100644
index 0000000..fce8216
--- /dev/null
+++ b/po/CMakeLists.txt
@@ -0,0 +1,2 @@
+find_package (Intltool REQUIRED)
+intltool_install_translations (ALL GETTEXT_PACKAGE ${GETTEXT_PACKAGE})
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..d0fdbd1
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,22 @@
+# cups-notifier.h
+# cups-notifier.c
+include (GdbusCodegen)
+add_gdbus_codegen_with_namespace (CUPS_NOTIFIER cups-notifier org.cups.cupsd Cups "${CMAKE_CURRENT_SOURCE_DIR}/org.cups.cupsd.Notifier.xml")
+
+# libayatanaindicatorprintersservice.a
+add_library (ayatanaindicatorprintersservice STATIC
+ indicator-printers-service.h
+ indicator-printers-service.c
+ indicator-printer-state-notifier.c
+ indicator-printer-state-notifier.h
+ spawn-printer-settings.c
+ spawn-printer-settings.h
+ dbus-names.h
+ ${CUPS_NOTIFIER})
+target_include_directories (ayatanaindicatorprintersservice PUBLIC ${SERVICE_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})
+target_compile_definitions (ayatanaindicatorprintersservice PUBLIC GETTEXT_PACKAGE="${GETTEXT_PACKAGE}" LOCALEDIR="${CMAKE_INSTALL_FULL_LOCALEDIR}")
+
+# ayatana-indicator-printers-service
+add_executable (ayatana-indicator-printers-service main.c)
+target_link_libraries (ayatana-indicator-printers-service ayatanaindicatorprintersservice ${SERVICE_LIBRARIES})
+install (TARGETS ayatana-indicator-printers-service RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_LIBEXECDIR}/${CMAKE_PROJECT_NAME})
diff --git a/src/Makefile.am b/src/Makefile.am
deleted file mode 100644
index 48e81f0..0000000
--- a/src/Makefile.am
+++ /dev/null
@@ -1,53 +0,0 @@
-printersmenulibdir = $(INDICATORDIR)
-printersmenulib_LTLIBRARIES = libayatana-printersmenu.la
-libayatana_printersmenu_la_SOURCES = \
- indicator-printers.c \
- indicator-printers.h \
- indicator-menu-item.c \
- indicator-menu-item.h \
- dbus-names.h
-
-libayatana_printersmenu_la_CPPFLAGS = $(APPLET_CFLAGS)
-libayatana_printersmenu_la_CFLAGS = $(COVERAGE_CFLAGS)
-libayatana_printersmenu_la_LIBADD = $(APPLET_LIBS) -lm
-libayatana_printersmenu_la_LDFLAGS = \
- $(COVERAGE_LDFLAGS) \
- -module -avoid-version
-
-
-cups_notifier_sources = \
- cups-notifier.c \
- cups-notifier.h
-
-$(cups_notifier_sources): org.cups.cupsd.Notifier.xml
- gdbus-codegen \
- --interface-prefix org.cups.cupsd \
- --c-namespace Cups \
- --generate-c-code cups-notifier \
- $^
-
-
-pkglibexec_PROGRAMS = ayatana-indicator-printers-service
-ayatana_indicator_printers_service_SOURCES = \
- indicator-printers-service.c \
- indicator-printers-menu.c \
- indicator-printers-menu.h \
- indicator-printer-state-notifier.c \
- indicator-printer-state-notifier.h \
- spawn-printer-settings.c \
- spawn-printer-settings.h \
- dbus-names.h
-
-nodist_ayatana_indicator_printers_service_SOURCES = $(cups_notifier_sources)
-
-ayatana_indicator_printers_service_CPPFLAGS = $(SERVICE_CFLAGS)
-ayatana_indicator_printers_service_CFLAGS = $(COVERAGE_CFLAGS)
-ayatana_indicator_printers_service_LDADD = $(SERVICE_LIBS)
-ayatana_indicator_printers_service_LDFLAGS = $(COVERAGE_LDFLAGS)
-
-BUILT_SOURCES = $(cups_notifier_sources)
-CLEANFILES= $(BUILT_SOURCES)
-EXTRA_DIST = org.cups.cupsd.Notifier.xml
-
-DISTCLEANFILES = \
- Makefile.in \ No newline at end of file
diff --git a/src/indicator-menu-item.c b/src/indicator-menu-item.c
deleted file mode 100644
index ed89a0f..0000000
--- a/src/indicator-menu-item.c
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * Copyright 2012 Canonical Ltd.
- *
- * Authors: 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
- * 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 "indicator-menu-item.h"
-
-#include <math.h>
-
-struct _IndicatorMenuItemPrivate
-{
- GtkImage *image;
- GtkWidget *label;
- GtkWidget *right_label;
- gboolean right_is_lozenge;
-};
-
-G_DEFINE_TYPE_WITH_PRIVATE(IndicatorMenuItem, indicator_menu_item, GTK_TYPE_MENU_ITEM)
-
-enum {
- PROP_0,
- PROP_ICON,
- PROP_ICON_NAME,
- PROP_LABEL,
- PROP_RIGHT,
- PROP_RIGHT_IS_LOZENGE,
- N_PROPERTIES
-};
-
-static GParamSpec *properties[N_PROPERTIES];
-
-
-static gint
-gtk_widget_get_font_size (GtkWidget *widget)
-{
- const PangoFontDescription *font;
-
- gtk_style_context_get(gtk_widget_get_style_context(widget), gtk_widget_get_state_flags(widget), "font", &font, NULL);
-
- return pango_font_description_get_size (font) / PANGO_SCALE;
-}
-
-static void
-cairo_lozenge (cairo_t *cr, double x, double y, double w, double h)
-{
- double radius = MIN (w / 2.0, h / 2.0);
- double x1 = x + w - radius;
- double x2 = x + radius;
- double y1 = y + radius;
- double y2 = y + h - radius;
-
- cairo_move_to (cr, x+radius, y);
- cairo_arc (cr, x1, y1, radius, M_PI * 1.5, M_PI * 2);
- cairo_arc (cr, x1, y2, radius, 0, M_PI * 0.5);
- cairo_arc (cr, x2, y2, radius, M_PI * 0.5, M_PI);
- cairo_arc (cr, x2, y1, radius, M_PI, M_PI * 1.5);
-}
-
-static gboolean
-detail_label_draw (GtkWidget *widget,
- cairo_t *cr,
- gpointer data)
-{
- GtkAllocation allocation;
- double x, y, w, h;
- GdkRGBA color;
- PangoLayout *layout;
- PangoRectangle layout_extents;
- gboolean is_lozenge = *(gboolean *)data;
- gint font_size = gtk_widget_get_font_size (widget);
-
- /* let the label handle the drawing if it's not a lozenge */
- if (!is_lozenge)
- return FALSE;
-
- layout = gtk_label_get_layout (GTK_LABEL(widget));
- pango_layout_get_extents (layout, NULL, &layout_extents);
- pango_extents_to_pixels (&layout_extents, NULL);
-
- gtk_widget_get_allocation (widget, &allocation);
- x = -font_size / 2.0;
- y = 1;
- w = allocation.width;
- h = MIN (allocation.height, layout_extents.height + 4);
-
- if (layout_extents.width == 0)
- return TRUE;
-
- 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);
-
- cairo_set_line_width (cr, 1.0);
- cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
- cairo_lozenge (cr, x - font_size / 2.0, y, w + font_size, h);
-
- x += (w - layout_extents.width) / 2.0;
- y += (h - layout_extents.height) / 2.0;
- cairo_move_to (cr, floor (x), floor (y));
- pango_cairo_layout_path (cr, layout);
- cairo_fill (cr);
-
- return TRUE;
-}
-
-
-static void
-indicator_menu_item_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- IndicatorMenuItem *self = INDICATOR_MENU_ITEM (object);
-
- switch (property_id)
- {
- case PROP_ICON:
- g_value_set_object (value, indicator_menu_item_get_icon (self));
- break;
-
- case PROP_ICON_NAME:
- g_value_set_string (value, indicator_menu_item_get_icon_name (self));
- break;
-
- case PROP_LABEL:
- g_value_set_string (value, gtk_label_get_label (GTK_LABEL (self->priv->label)));
- break;
-
- case PROP_RIGHT:
- g_value_set_string (value, gtk_label_get_label (GTK_LABEL (self->priv->right_label)));
- break;
-
- case PROP_RIGHT_IS_LOZENGE:
- g_value_set_boolean (value, self->priv->right_is_lozenge);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-
-static void
-indicator_menu_item_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- switch (property_id)
- {
- case PROP_ICON:
- indicator_menu_item_set_icon (INDICATOR_MENU_ITEM (object),
- g_value_get_object (value));
- break;
-
- case PROP_ICON_NAME:
- indicator_menu_item_set_icon_name (INDICATOR_MENU_ITEM (object),
- g_value_get_string (value));
- break;
-
- case PROP_LABEL:
- indicator_menu_item_set_label (INDICATOR_MENU_ITEM (object),
- g_value_get_string (value));
- break;
-
- case PROP_RIGHT:
- indicator_menu_item_set_right (INDICATOR_MENU_ITEM (object),
- g_value_get_string (value));
- break;
-
- case PROP_RIGHT_IS_LOZENGE:
- indicator_menu_item_set_right_is_lozenge (INDICATOR_MENU_ITEM (object),
- g_value_get_boolean (value));
- break;
-
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-
-static void
-indicator_menu_item_dispose (GObject *object)
-{
- IndicatorMenuItem *self = INDICATOR_MENU_ITEM (object);
-
- g_clear_object (&self->priv->image);
- g_clear_object (&self->priv->label);
- g_clear_object (&self->priv->right_label);
-
- G_OBJECT_CLASS (indicator_menu_item_parent_class)->dispose (object);
-}
-
-
-static void
-indicator_menu_item_class_init (IndicatorMenuItemClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->get_property = indicator_menu_item_get_property;
- object_class->set_property = indicator_menu_item_set_property;
- object_class->dispose = indicator_menu_item_dispose;
-
- properties[PROP_ICON] = g_param_spec_object ("icon",
- "Icon",
- "Icon for this menu item",
- GDK_TYPE_PIXBUF,
- G_PARAM_READWRITE);
-
- properties[PROP_ICON_NAME] = g_param_spec_string ("icon-name",
- "Icon name",
- "Name of the themed icon",
- "",
- G_PARAM_READWRITE);
-
- properties[PROP_LABEL] = g_param_spec_string ("label",
- "Label",
- "The text for the main label",
- "",
- G_PARAM_READWRITE);
-
- properties[PROP_RIGHT] = g_param_spec_string ("right",
- "Right",
- "The text on the right side of the menu item",
- "",
- G_PARAM_READWRITE);
-
- properties[PROP_RIGHT_IS_LOZENGE] = g_param_spec_boolean ("right-is-lozenge",
- "Right is a lozenge",
- "Whether the right label is displayed as a lonzenge",
- FALSE,
- G_PARAM_READWRITE);
-
- g_object_class_install_properties (object_class, N_PROPERTIES, properties);
-}
-
-
-static void
-indicator_menu_item_init (IndicatorMenuItem *self)
-{
- IndicatorMenuItemPrivate *priv;
- gint spacing;
- GtkWidget *hbox;
-
- priv = indicator_menu_item_get_instance_private(self);
- self->priv = priv;
-
- gtk_widget_style_get (GTK_WIDGET (self),
- "toggle-spacing", &spacing,
- NULL);
-
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, spacing);
-
- priv->image = g_object_new (GTK_TYPE_IMAGE, NULL);
- g_object_ref_sink (priv->image);
- gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (priv->image), FALSE, FALSE, 0);
-
- priv->label = g_object_new (GTK_TYPE_LABEL,
- "xalign", 0.0,
- NULL);
- g_object_ref_sink (priv->label);
- gtk_box_pack_start (GTK_BOX (hbox), priv->label, TRUE, TRUE, 0);
-
- priv->right_label = g_object_new (GTK_TYPE_LABEL,
- "xalign", 1.0,
- "width-chars", 2,
- NULL);
- gtk_style_context_add_class (gtk_widget_get_style_context (priv->right_label),
- "accelerator");
- g_signal_connect (priv->right_label,
- "draw",
- G_CALLBACK (detail_label_draw),
- &priv->right_is_lozenge);
- g_object_ref_sink (priv->right_label);
- gtk_box_pack_start (GTK_BOX (hbox),
- priv->right_label,
- FALSE,
- FALSE,
- gtk_widget_get_font_size (priv->right_label) / 2.0 + 1);
-
- gtk_container_add (GTK_CONTAINER (self), hbox);
-
- priv->right_is_lozenge = FALSE;
-}
-
-
-IndicatorMenuItem *
-indicator_menu_item_new (void)
-{
- return g_object_new (INDICATOR_TYPE_MENU_ITEM, NULL);
-}
-
-
-const gchar *
-indicator_menu_item_get_label (IndicatorMenuItem *self)
-{
- return gtk_label_get_label (GTK_LABEL (self->priv->label));
-}
-
-
-void
-indicator_menu_item_set_label (IndicatorMenuItem *self,
- const gchar *text)
-{
- gtk_label_set_label (GTK_LABEL (self->priv->label), text);
- g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_LABEL]);
-}
-
-
-const gchar *
-indicator_menu_item_get_right (IndicatorMenuItem *self)
-{
- return gtk_label_get_label (GTK_LABEL (self->priv->right_label));
-}
-
-
-void
-indicator_menu_item_set_right (IndicatorMenuItem *self,
- const gchar *text)
-{
- gtk_label_set_label (GTK_LABEL (self->priv->right_label), text);
- g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_RIGHT]);
-}
-
-
-gboolean
-indicator_menu_item_get_right_is_lozenge (IndicatorMenuItem *self)
-{
- return self->priv->right_is_lozenge;
-}
-
-
-void
-indicator_menu_item_set_right_is_lozenge (IndicatorMenuItem *self,
- gboolean is_lozenge)
-{
- self->priv->right_is_lozenge = is_lozenge;
- gtk_widget_queue_draw (self->priv->right_label);
- g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_RIGHT_IS_LOZENGE]);
-}
-
-
-GdkPixbuf *
-indicator_menu_item_get_icon (IndicatorMenuItem *self)
-{
- if (gtk_image_get_storage_type (self->priv->image) == GTK_IMAGE_PIXBUF)
- return gtk_image_get_pixbuf (self->priv->image);
- else
- return NULL;
-}
-
-
-void
-indicator_menu_item_set_icon (IndicatorMenuItem *self,
- GdkPixbuf *icon)
-{
- gtk_image_set_from_pixbuf (self->priv->image, icon);
- g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ICON]);
-}
-
-
-const gchar *
-indicator_menu_item_get_icon_name (IndicatorMenuItem *self)
-{
- const gchar *name = NULL;
-
- if (gtk_image_get_storage_type (self->priv->image) == GTK_IMAGE_ICON_NAME)
- gtk_image_get_icon_name (self->priv->image, &name, NULL);
-
- return name;
-}
-
-
-void
-indicator_menu_item_set_icon_name (IndicatorMenuItem *self,
- const gchar *name)
-{
- gtk_image_set_from_icon_name (self->priv->image, name, GTK_ICON_SIZE_MENU);
- g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ICON_NAME]);
-}
diff --git a/src/indicator-menu-item.h b/src/indicator-menu-item.h
deleted file mode 100644
index 84d6b74..0000000
--- a/src/indicator-menu-item.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2012 Canonical Ltd.
- *
- * Authors: 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
- * 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 INDICATOR_MENU_ITEM_H
-#define INDICATOR_MENU_ITEM_H
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define INDICATOR_TYPE_MENU_ITEM indicator_menu_item_get_type()
-
-#define INDICATOR_MENU_ITEM(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
- INDICATOR_TYPE_MENU_ITEM, IndicatorMenuItem))
-
-#define INDICATOR_MENU_ITEM_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), \
- INDICATOR_TYPE_MENU_ITEM, IndicatorMenuItemClass))
-
-#define INDICATOR_IS_MENU_ITEM(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
- INDICATOR_TYPE_MENU_ITEM))
-
-#define INDICATOR_IS_MENU_ITEM_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), \
- INDICATOR_TYPE_MENU_ITEM))
-
-#define INDICATOR_MENU_ITEM_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), \
- INDICATOR_TYPE_MENU_ITEM, IndicatorMenuItemClass))
-
-typedef struct _IndicatorMenuItem IndicatorMenuItem;
-typedef struct _IndicatorMenuItemClass IndicatorMenuItemClass;
-typedef struct _IndicatorMenuItemPrivate IndicatorMenuItemPrivate;
-
-struct _IndicatorMenuItem
-{
- GtkMenuItem parent;
- IndicatorMenuItemPrivate *priv;
-};
-
-struct _IndicatorMenuItemClass
-{
- GtkMenuItemClass parent_class;
-};
-
-GType indicator_menu_item_get_type (void) G_GNUC_CONST;
-
-IndicatorMenuItem *indicator_menu_item_new (void);
-
-const gchar * indicator_menu_item_get_label (IndicatorMenuItem *self);
-void indicator_menu_item_set_label (IndicatorMenuItem *self, const gchar *text);
-const gchar * indicator_menu_item_get_right (IndicatorMenuItem *self);
-void indicator_menu_item_set_right (IndicatorMenuItem *self, const gchar *text);
-
-gboolean indicator_menu_item_get_right_is_lozenge (IndicatorMenuItem *self);
-void indicator_menu_item_set_right_is_lozenge (IndicatorMenuItem *self, gboolean is_lozenge);
-const gchar * indicator_menu_item_get_icon_name (IndicatorMenuItem *self);
-void indicator_menu_item_set_icon (IndicatorMenuItem *self, GdkPixbuf *icon);
-GdkPixbuf * indicator_menu_item_get_icon (IndicatorMenuItem *self);
-void indicator_menu_item_set_icon_name (IndicatorMenuItem *self, const gchar *name);
-
-G_END_DECLS
-
-#endif
diff --git a/src/indicator-printer-state-notifier.c b/src/indicator-printer-state-notifier.c
index 7a587a0..12f77c6 100644
--- a/src/indicator-printer-state-notifier.c
+++ b/src/indicator-printer-state-notifier.c
@@ -1,7 +1,9 @@
/*
* Copyright 2012 Canonical Ltd.
+ * Copyright 2022 Robert Tari
*
* Authors: Lars Uebernickel <lars.uebernickel@canonical.com>
+ * Robert Tari <robert@tari.in>
*
* 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
@@ -17,9 +19,8 @@
*/
#include "indicator-printer-state-notifier.h"
-
+#include <ayatana/common/utils.h>
#include <glib/gi18n.h>
-#include <gtk/gtk.h>
#include <cups/cups.h>
#include <string.h>
#include <stdarg.h>
@@ -27,9 +28,6 @@
#include "cups-notifier.h"
#include "spawn-printer-settings.h"
-
-#define RESPONSE_SHOW_SYSTEM_SETTINGS 1
-
struct _IndicatorPrinterStateNotifierPrivate
{
CupsNotifier *cups_notifier;
@@ -95,12 +93,9 @@ show_alert_box (const gchar *printer,
const gchar *reason,
int njobs)
{
- GtkWidget *dialog;
- GtkWidget *image;
gchar *primary_text;
gchar *secondary_text;
- image = gtk_image_new_from_icon_name ("printer", GTK_ICON_SIZE_DIALOG);
primary_text = g_strdup_printf (reason, printer);
secondary_text = g_strdup_printf (ngettext(
@@ -108,31 +103,14 @@ show_alert_box (const gchar *printer,
"You have %d jobs queued to print on this printer.", njobs),
njobs);
- dialog = g_object_new (GTK_TYPE_MESSAGE_DIALOG,
- "title", _("Printing Problem"),
- "icon-name", "printer",
- "image", image,
- "text", primary_text,
- "secondary-text", secondary_text,
- "urgency-hint", TRUE,
- "focus-on-map", FALSE,
- "window-position", GTK_WIN_POS_CENTER,
- "skip-taskbar-hint", FALSE,
- "deletable", FALSE,
- NULL);
-
+ gchar *sText = g_strdup_printf("<b>%s</b>\n\n%s", primary_text, secondary_text);
g_free (primary_text);
g_free (secondary_text);
- gtk_dialog_add_buttons(GTK_DIALOG (dialog), _("_Settingsā€¦"), RESPONSE_SHOW_SYSTEM_SETTINGS, _("_OK"), GTK_RESPONSE_OK, NULL);
- gtk_dialog_set_default_response (GTK_DIALOG (dialog),
- GTK_RESPONSE_OK);
- gtk_widget_show_all (dialog);
-
- if (gtk_dialog_run (GTK_DIALOG (dialog)) == RESPONSE_SHOW_SYSTEM_SETTINGS)
- spawn_printer_settings ();
+ ayatana_common_utils_zenity_warning ("printer", _("Printing Problem"), sText);
+ g_free (sText);
- gtk_widget_destroy (dialog);
+ spawn_printer_settings ();
}
diff --git a/src/indicator-printers-menu.c b/src/indicator-printers-menu.c
deleted file mode 100644
index bf0bc07..0000000
--- a/src/indicator-printers-menu.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Copyright 2012 Canonical Ltd.
- *
- * Authors: 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
- * 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 "indicator-printers-menu.h"
-
-#include <glib/gi18n.h>
-
-#include <cups/cups.h>
-
-#include "spawn-printer-settings.h"
-
-struct _IndicatorPrintersMenuPrivate
-{
- DbusmenuMenuitem *root;
- GHashTable *printers; /* printer name -> dbusmenuitem */
- CupsNotifier *cups_notifier;
-};
-
-G_DEFINE_TYPE_WITH_PRIVATE(IndicatorPrintersMenu, indicator_printers_menu, G_TYPE_OBJECT)
-
-enum {
- PROP_0,
- PROP_CUPS_NOTIFIER,
- NUM_PROPERTIES
-};
-
-static GParamSpec *properties[NUM_PROPERTIES];
-
-
-static void
-dispose (GObject *object)
-{
- IndicatorPrintersMenu *self = INDICATOR_PRINTERS_MENU (object);
-
- if (self->priv->printers) {
- g_hash_table_unref (self->priv->printers);
- self->priv->printers = NULL;
- }
-
- g_clear_object (&self->priv->root);
- g_clear_object (&self->priv->cups_notifier);
-
- G_OBJECT_CLASS (indicator_printers_menu_parent_class)->dispose (object);
-}
-
-
-void
-set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- IndicatorPrintersMenu *self = INDICATOR_PRINTERS_MENU (object);
-
- switch (property_id) {
- case PROP_CUPS_NOTIFIER:
- indicator_printers_menu_set_cups_notifier (self,
- g_value_get_object (value));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-
-void
-get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- IndicatorPrintersMenu *self = INDICATOR_PRINTERS_MENU (object);
-
- switch (property_id) {
- case PROP_CUPS_NOTIFIER:
- g_value_set_object (value,
- indicator_printers_menu_get_cups_notifier (self));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-
-static void
-indicator_printers_menu_class_init (IndicatorPrintersMenuClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->dispose = dispose;
- object_class->get_property = get_property;
- object_class->set_property = set_property;
-
- properties[PROP_CUPS_NOTIFIER] = g_param_spec_object ("cups-notifier",
- "Cups Notifier",
- "A cups notifier object",
- CUPS_TYPE_NOTIFIER,
- G_PARAM_READWRITE);
-
- g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
-}
-
-
-static void
-on_printer_item_activated (DbusmenuMenuitem *menuitem,
- guint timestamp,
- gpointer user_data)
-{
- const gchar *printer = user_data;
- spawn_printer_settings_with_args ("--show-jobs %s", printer);
-}
-
-
-static void
-update_indicator_visibility (IndicatorPrintersMenu *self)
-{
- GList *it;
- gboolean is_visible = FALSE;
-
- for (it = dbusmenu_menuitem_get_children (self->priv->root);
- it;
- it = g_list_next (it))
- {
- DbusmenuMenuitem *child = it->data;
- if ((is_visible = dbusmenu_menuitem_property_get_bool (child, "visible")))
- break;
- }
-
- dbusmenu_menuitem_property_set_bool (self->priv->root, "visible", is_visible);
-}
-
-
-static void
-update_printer_menuitem (IndicatorPrintersMenu *self,
- const char *printer,
- int state)
-{
- DbusmenuMenuitem *item;
- int njobs;
- cups_job_t *jobs;
-
- njobs = cupsGetJobs (&jobs, printer, 1, CUPS_WHICHJOBS_ACTIVE);
- cupsFreeJobs (njobs, jobs);
-
- if (njobs < 0) {
- g_warning ("printer '%s' does not exist\n", printer);
- return;
- }
-
- item = g_hash_table_lookup (self->priv->printers, printer);
-
- if (!item) {
- item = dbusmenu_menuitem_new ();
- dbusmenu_menuitem_property_set (item, "type", "indicator-item");
- dbusmenu_menuitem_property_set (item, "indicator-icon-name", "printer");
- dbusmenu_menuitem_property_set (item, "indicator-label", printer);
- g_signal_connect_data (item, "item-activated",
- G_CALLBACK (on_printer_item_activated),
- g_strdup (printer), (GClosureNotify) g_free, 0);
-
- dbusmenu_menuitem_child_append(self->priv->root, item);
- g_hash_table_insert (self->priv->printers, g_strdup (printer), item);
- }
-
- if (njobs == 0) {
- dbusmenu_menuitem_property_set_bool (item, "visible", FALSE);
- update_indicator_visibility (self);
- return;
- }
-
- /* there are jobs for this printer. Make sure the indicator and the menu
- * item for that printer are shown */
- dbusmenu_menuitem_property_set_bool (self->priv->root, "visible", TRUE);
- dbusmenu_menuitem_property_set_bool (item, "visible", TRUE);
-
- switch (state) {
- case IPP_PRINTER_STOPPED:
- dbusmenu_menuitem_property_set (item, "indicator-right", _("Paused"));
- dbusmenu_menuitem_property_set_bool (item, "indicator-right-is-lozenge", FALSE);
- break;
-
- case IPP_PRINTER_PROCESSING: {
- gchar *jobstr = g_strdup_printf ("%d", njobs);
- dbusmenu_menuitem_property_set (item, "indicator-right", jobstr);
- dbusmenu_menuitem_property_set_bool (item, "indicator-right-is-lozenge", TRUE);
- g_free (jobstr);
- break;
- }
- }
-}
-
-
-static void
-update_all_printer_menuitems (IndicatorPrintersMenu *self)
-{
- int ndests, i;
- cups_dest_t *dests;
-
- ndests = cupsGetDests (&dests);
- for (i = 0; i < ndests; i++) {
- const char *option = cupsGetOption ("printer-state",
- dests[i].num_options,
- dests[i].options);
- if (option != NULL) {
- int state = atoi (option);
- update_printer_menuitem (self, dests[i].name, state);
- }
- }
- cupsFreeDests (ndests, dests);
-}
-
-
-static void
-update_job (CupsNotifier *cups_notifier,
- const gchar *text,
- const gchar *printer_uri,
- const gchar *printer_name,
- guint printer_state,
- const gchar *printer_state_reasons,
- gboolean printer_is_accepting_jobs,
- guint job_id,
- guint job_state,
- const gchar *job_state_reasons,
- const gchar *job_name,
- guint job_impressions_completed,
- gpointer user_data)
-{
- IndicatorPrintersMenu *self = INDICATOR_PRINTERS_MENU (user_data);
-
- /* CUPS doesn't send the printer's name for these events. Update all menu
- * items as a temporary workaround */
- if (job_state == IPP_JOB_CANCELLED ||
- job_state == IPP_JOB_ABORTED ||
- job_state == IPP_JOB_COMPLETED)
- update_all_printer_menuitems (self);
- else
- update_printer_menuitem (self, printer_name, printer_state);
-}
-
-
-static void
-on_printer_state_changed (CupsNotifier *object,
- const gchar *text,
- const gchar *printer_uri,
- const gchar *printer_name,
- guint printer_state,
- const gchar *printer_state_reasons,
- gboolean printer_is_accepting_jobs,
- gpointer user_data)
-{
- IndicatorPrintersMenu *self = INDICATOR_PRINTERS_MENU (user_data);
-
- update_printer_menuitem (self, printer_name, printer_state);
-}
-
-
-static void
-indicator_printers_menu_init (IndicatorPrintersMenu *self)
-{
- self->priv = indicator_printers_menu_get_instance_private(self);
-
- self->priv->root = dbusmenu_menuitem_new ();
- dbusmenu_menuitem_property_set_bool (self->priv->root, "visible", FALSE);
-
- self->priv->printers = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- g_object_unref);
-
- /* create initial menu items */
- update_all_printer_menuitems (self);
-}
-
-
-IndicatorPrintersMenu *
-indicator_printers_menu_new (void)
-{
- return g_object_new (INDICATOR_TYPE_PRINTERS_MENU, NULL);
-}
-
-
-DbusmenuMenuitem *
-indicator_printers_menu_get_root (IndicatorPrintersMenu *self)
-{
- return self->priv->root;
-}
-
-
-CupsNotifier *
-indicator_printers_menu_get_cups_notifier (IndicatorPrintersMenu *self)
-{
- return self->priv->cups_notifier;
-}
-
-
-void
-indicator_printers_menu_set_cups_notifier (IndicatorPrintersMenu *self,
- CupsNotifier *cups_notifier)
-{
- if (self->priv->cups_notifier) {
- g_object_disconnect (self->priv->cups_notifier,
- "any-signal", update_job, self,
- "any-signal", on_printer_state_changed, self,
- NULL);
- g_clear_object (&self->priv->cups_notifier);
- }
-
- if (cups_notifier) {
- self->priv->cups_notifier = g_object_ref (cups_notifier);
- g_object_connect (self->priv->cups_notifier,
- "signal::job-created", update_job, self,
- "signal::job-state", update_job, self,
- "signal::job-completed", update_job, self,
- "signal::printer-state-changed", on_printer_state_changed, self,
- NULL);
- }
-}
diff --git a/src/indicator-printers-menu.h b/src/indicator-printers-menu.h
deleted file mode 100644
index c10f221..0000000
--- a/src/indicator-printers-menu.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2012 Canonical Ltd.
- *
- * Authors: 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
- * 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 INDICATOR_PRINTERS_MENU_H
-#define INDICATOR_PRINTERS_MENU_H
-
-#include <glib-object.h>
-#include <libdbusmenu-glib/dbusmenu-glib.h>
-
-#include "cups-notifier.h"
-
-G_BEGIN_DECLS
-
-#define INDICATOR_TYPE_PRINTERS_MENU indicator_printers_menu_get_type()
-
-#define INDICATOR_PRINTERS_MENU(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
- INDICATOR_TYPE_PRINTERS_MENU, IndicatorPrintersMenu))
-
-#define INDICATOR_PRINTERS_MENU_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), \
- INDICATOR_TYPE_PRINTERS_MENU, IndicatorPrintersMenuClass))
-
-#define INDICATOR_IS_PRINTERS_MENU(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
- INDICATOR_TYPE_PRINTERS_MENU))
-
-#define INDICATOR_IS_PRINTERS_MENU_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), \
- INDICATOR_TYPE_PRINTERS_MENU))
-
-#define INDICATOR_PRINTERS_MENU_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), \
- INDICATOR_TYPE_PRINTERS_MENU, IndicatorPrintersMenuClass))
-
-typedef struct _IndicatorPrintersMenu IndicatorPrintersMenu;
-typedef struct _IndicatorPrintersMenuClass IndicatorPrintersMenuClass;
-typedef struct _IndicatorPrintersMenuPrivate IndicatorPrintersMenuPrivate;
-
-struct _IndicatorPrintersMenu
-{
- GObject parent;
- IndicatorPrintersMenuPrivate *priv;
-};
-
-struct _IndicatorPrintersMenuClass
-{
- GObjectClass parent_class;
-};
-
-GType indicator_printers_menu_get_type (void) G_GNUC_CONST;
-
-IndicatorPrintersMenu *indicator_printers_menu_new (void);
-DbusmenuMenuitem * indicator_printers_menu_get_root (IndicatorPrintersMenu *menu);
-CupsNotifier * indicator_printers_menu_get_cups_notifier (IndicatorPrintersMenu *self);
-void indicator_printers_menu_set_cups_notifier (IndicatorPrintersMenu *self,
- CupsNotifier *cups_notifier);
-
-G_END_DECLS
-
-#endif
diff --git a/src/indicator-printers-service.c b/src/indicator-printers-service.c
index 8d31360..ed9553c 100644
--- a/src/indicator-printers-service.c
+++ b/src/indicator-printers-service.c
@@ -1,7 +1,9 @@
/*
* Copyright 2012 Canonical Ltd.
+ * Copyright 2022 Robert Tari
*
* Authors: Lars Uebernickel <lars.uebernickel@canonical.com>
+ * Robert Tari <robert@tari.in>
*
* 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
@@ -16,190 +18,491 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <libayatana-indicator/indicator-service.h>
-#include <libdbusmenu-glib/dbusmenu-glib.h>
-#include <gtk/gtk.h>
#include <cups/cups.h>
#include "dbus-names.h"
-#include "config.h"
#include <glib/gi18n-lib.h>
+#include <gio/gio.h>
+#include "indicator-printers-service.h"
#include "cups-notifier.h"
-#include "indicator-printers-menu.h"
#include "indicator-printer-state-notifier.h"
+#include "spawn-printer-settings.h"
#define NOTIFY_LEASE_DURATION (24 * 60 * 60)
+static guint m_nSignal = 0;
-static int
-create_subscription ()
-{
- ipp_t *req;
- ipp_t *resp;
- ipp_attribute_t *attr;
- int id = 0;
-
- req = ippNewRequest (IPP_CREATE_PRINTER_SUBSCRIPTION);
- ippAddString (req, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, "/");
- ippAddString (req, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD,
- "notify-events", NULL, "all");
- ippAddString (req, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI,
- "notify-recipient-uri", NULL, "dbus://");
- ippAddInteger (req, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
- "notify-lease-duration", NOTIFY_LEASE_DURATION);
-
- resp = cupsDoRequest (CUPS_HTTP_DEFAULT, req, "/");
- if (!resp || cupsLastError() != IPP_OK) {
- g_warning ("Error subscribing to CUPS notifications: %s\n",
- cupsLastErrorString ());
- return 0;
+enum
+{
+ SECTION_HEADER = (1<<0),
+ SECTION_PRINTERS = (1<<2)
+};
+
+enum
+{
+ PROFILE_PHONE,
+ PROFILE_DESKTOP,
+ N_PROFILES
+};
+
+static const char *const lMenuNames[N_PROFILES] =
+{
+ "phone",
+ "desktop"
+};
+
+struct ProfileMenuInfo
+{
+ GMenu *pMenu;
+ GMenu *pSubmenu;
+ guint nExportId;
+};
+
+struct _IndicatorPrintersServicePrivate
+{
+ GCancellable *pCancellable;
+ IndicatorPrinterStateNotifier *pStateNotifier;
+ CupsNotifier *pCupsNotifier;
+ guint nOwnId;
+ guint nActionsId;
+ GDBusConnection *pConnection;
+ gboolean bMenusBuilt;
+ int nSubscriptionId;
+ struct ProfileMenuInfo lMenus[N_PROFILES];
+ GSimpleActionGroup *pActionGroup;
+ GSimpleAction *pHeaderAction;
+ GSimpleAction *pPrinterAction;
+ GMenu *pPrintersSection;
+ gboolean bVisible;
+};
+
+typedef IndicatorPrintersServicePrivate priv_t;
+
+G_DEFINE_TYPE_WITH_PRIVATE (IndicatorPrintersService, indicator_printers_service, G_TYPE_OBJECT)
+
+static void rebuildNow (IndicatorPrintersService *self, guint nSections);
+
+static void unexport (IndicatorPrintersService *self)
+{
+ if (self->pPrivate->nSubscriptionId > 0)
+ {
+ ipp_t *pRequest = ippNewRequest (IPP_CANCEL_SUBSCRIPTION);
+ ippAddString (pRequest, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "/");
+ ippAddInteger (pRequest, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "notify-subscription-id", self->pPrivate->nSubscriptionId);
+ ipp_t *pResponse = cupsDoRequest (CUPS_HTTP_DEFAULT, pRequest, "/");
+
+ if (!pResponse || cupsLastError () != IPP_OK)
+ {
+ g_warning ("Error subscribing to CUPS notifications: %s\n", cupsLastErrorString ());
+
+ return;
+ }
+
+ ippDelete (pResponse);
}
- attr = ippFindAttribute (resp, "notify-subscription-id", IPP_TAG_INTEGER);
- if (attr)
- id = ippGetInteger (attr, 0);
- else
- g_warning ("ipp-create-printer-subscription response doesn't contain "
- "subscription id.\n");
+ // Unexport the menus
+ for (int i = 0; i < N_PROFILES; ++i)
+ {
+ guint *pId = &self->pPrivate->lMenus[i].nExportId;
+
+ if (*pId)
+ {
+ g_dbus_connection_unexport_menu_model (self->pPrivate->pConnection, *pId);
+ *pId = 0;
+ }
+ }
+
+ // Unexport the actions
+ if (self->pPrivate->nActionsId)
+ {
+ g_dbus_connection_unexport_action_group (self->pPrivate->pConnection, self->pPrivate->nActionsId);
+ self->pPrivate->nActionsId = 0;
+ }
+}
- ippDelete (resp);
- return id;
+static void onPrinterStateChanged (CupsNotifier *pNotifier, const gchar *sText, const gchar *sPrinterUri, const gchar *sPrinterName, guint nPrinterState, const gchar *sPrinterStateReasons, gboolean bPrinterIsAcceptingJobs, IndicatorPrintersService *self)
+{
+ rebuildNow(self, SECTION_PRINTERS | SECTION_HEADER);
}
+static void onJobChanged (CupsNotifier *pNotifier, const gchar *sText, const gchar *sPrinterUri, const gchar *sPrinterName, guint nPrinterState, const gchar *sPrinterStateReasons, gboolean bPrinterIsAcceptingJobs, guint nJobId, guint nJobState, const gchar *sJobStateReasons, const gchar *sJobName, guint nJobImpressionsCompleted, IndicatorPrintersService *self)
+{
+ rebuildNow(self, SECTION_PRINTERS | SECTION_HEADER);
+}
-static gboolean
-renew_subscription (int id)
+static void onDispose (GObject *pObject)
{
- ipp_t *req;
- ipp_t *resp;
+ IndicatorPrintersService *self = INDICATOR_PRINTERS_SERVICE (pObject);
- req = ippNewRequest (IPP_RENEW_SUBSCRIPTION);
- ippAddInteger (req, IPP_TAG_OPERATION, IPP_TAG_INTEGER,
- "notify-subscription-id", id);
- ippAddString (req, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, "/");
- ippAddString (req, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI,
- "notify-recipient-uri", NULL, "dbus://");
- ippAddInteger (req, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
- "notify-lease-duration", NOTIFY_LEASE_DURATION);
+ unexport (self);
- resp = cupsDoRequest (CUPS_HTTP_DEFAULT, req, "/");
- if (!resp || cupsLastError() != IPP_OK) {
- g_warning ("Error renewing CUPS subscription %d: %s\n",
- id, cupsLastErrorString ());
- return FALSE;
+ if (self->pPrivate->pCancellable != NULL)
+ {
+ g_cancellable_cancel (self->pPrivate->pCancellable);
+ g_clear_object (&self->pPrivate->pCancellable);
}
- ippDelete (resp);
- return TRUE;
+ if (self->pPrivate->pCupsNotifier)
+ {
+ g_object_disconnect (self->pPrivate->pCupsNotifier, "any-signal", onJobChanged, self, "any-signal", onPrinterStateChanged, self, NULL);
+ g_clear_object (&self->pPrivate->pCupsNotifier);
+ }
+
+ g_object_unref (self->pPrivate->pStateNotifier);
+ g_clear_object (&self->pPrivate->pPrinterAction);
+ g_clear_object (&self->pPrivate->pHeaderAction);
+ g_clear_object (&self->pPrivate->pActionGroup);
+ g_clear_object (&self->pPrivate->pConnection);
+
+ G_OBJECT_CLASS (indicator_printers_service_parent_class)->dispose (pObject);
+}
+
+static void indicator_printers_service_class_init (IndicatorPrintersServiceClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->dispose = onDispose;
+ m_nSignal = g_signal_new ("name-lost", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IndicatorPrintersServiceClass, pNameLost), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}
+static int createSubscription ()
+{
+ int nId = 0;
+
+ ipp_t *pRequest = ippNewRequest (IPP_CREATE_PRINTER_SUBSCRIPTION);
+ ippAddString (pRequest, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "/");
+ ippAddString (pRequest, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, "notify-events", NULL, "all");
+ ippAddString (pRequest, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI, "notify-recipient-uri", NULL, "dbus://");
+ ippAddInteger (pRequest, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, "notify-lease-duration", NOTIFY_LEASE_DURATION);
+ ipp_t *pResponse = cupsDoRequest (CUPS_HTTP_DEFAULT, pRequest, "/");
+
+ if (!pResponse || cupsLastError () != IPP_OK)
+ {
+ g_warning ("Error subscribing to CUPS notifications: %s\n", cupsLastErrorString ());
+
+ return 0;
+ }
+
+ ipp_attribute_t *pAttribute = ippFindAttribute (pResponse, "notify-subscription-id", IPP_TAG_INTEGER);
+
+ if (pAttribute)
+ {
+ nId = ippGetInteger (pAttribute, 0);
+ }
+ else
+ {
+ g_warning ("ipp-create-printer-subscription response doesn't contain subscription id.\n");
+ }
+
+ ippDelete (pResponse);
-static gboolean
-renew_subscription_timeout (gpointer userdata)
+ return nId;
+}
+
+static gboolean renewSubscriptionTimeout (gpointer pData)
{
- int *subscription_id = userdata;
+ int *nSubscriptionId = pData;
+ gboolean bRenewed = TRUE;
+ ipp_t *pRequest = ippNewRequest (IPP_RENEW_SUBSCRIPTION);
+ ippAddInteger (pRequest, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "notify-subscription-id", *nSubscriptionId);
+ ippAddString (pRequest, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "/");
+ ippAddString (pRequest, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI, "notify-recipient-uri", NULL, "dbus://");
+ ippAddInteger (pRequest, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, "notify-lease-duration", NOTIFY_LEASE_DURATION);
+ ipp_t *pResponse = cupsDoRequest (CUPS_HTTP_DEFAULT, pRequest, "/");
+
+ if (!pResponse || cupsLastError () != IPP_OK)
+ {
+ g_warning ("Error renewing CUPS subscription %d: %s\n", *nSubscriptionId, cupsLastErrorString ());
+ bRenewed = FALSE;
+ }
+ else
+ {
+ ippDelete (pResponse);
+ }
- if (*subscription_id <= 0 || !renew_subscription (*subscription_id))
- *subscription_id = create_subscription ();
+ if (*nSubscriptionId <= 0 || !bRenewed)
+ {
+ *nSubscriptionId = createSubscription ();
+ }
return TRUE;
}
+static GVariant *createHeaderState (IndicatorPrintersService *self)
+{
+ GVariantBuilder b;
+
+ g_variant_builder_init (&b, G_VARIANT_TYPE ("a{sv}"));
+ g_variant_builder_add (&b, "{sv}", "title", g_variant_new_string (_("Printers")));
+ g_variant_builder_add (&b, "{sv}", "tooltip", g_variant_new_string (_("Show print jobs and queues")));
+ g_variant_builder_add (&b, "{sv}", "visible", g_variant_new_boolean (TRUE));
+
+ if (self->pPrivate->bVisible)
+ {
+ GIcon *pIcon = g_themed_icon_new_with_default_fallbacks ("printer-symbolic");
+ g_variant_builder_add (&b, "{sv}", "accessible-desc", g_variant_new_string (_("Printers")));
+
+ if (pIcon)
+ {
+ GVariant *pSerialized = g_icon_serialize (pIcon);
+
+ if (pSerialized != NULL)
+ {
+ g_variant_builder_add (&b, "{sv}", "icon", pSerialized);
+ g_variant_unref (pSerialized);
+ }
+
+ g_object_unref (pIcon);
+ }
+ }
+
+ return g_variant_builder_end (&b);
+}
-void
-cancel_subscription (int id)
+static void onPrinterItemActivated (GSimpleAction *pAction, GVariant *pVariant, gpointer pData)
{
- ipp_t *req;
- ipp_t *resp;
+ const gchar *sPrinter = g_variant_get_string(pVariant, NULL);
+ spawn_printer_settings_with_args ("--show-jobs %s", sPrinter);
+}
- if (id <= 0)
- return;
+static void initActions (IndicatorPrintersService *self)
+{
+ self->pPrivate->pActionGroup = g_simple_action_group_new ();
- req = ippNewRequest (IPP_CANCEL_SUBSCRIPTION);
- ippAddString (req, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, "/");
- ippAddInteger (req, IPP_TAG_OPERATION, IPP_TAG_INTEGER,
- "notify-subscription-id", id);
+ GSimpleAction *pAction = g_simple_action_new_stateful ("_header", NULL, createHeaderState (self));
+ g_action_map_add_action (G_ACTION_MAP (self->pPrivate->pActionGroup), G_ACTION (pAction));
+ self->pPrivate->pHeaderAction = pAction;
- resp = cupsDoRequest (CUPS_HTTP_DEFAULT, req, "/");
- if (!resp || cupsLastError() != IPP_OK) {
- g_warning ("Error subscribing to CUPS notifications: %s\n",
- cupsLastErrorString ());
- return;
+ pAction = g_simple_action_new("printer", G_VARIANT_TYPE_STRING);
+ g_action_map_add_action (G_ACTION_MAP (self->pPrivate->pActionGroup), G_ACTION (pAction));
+ self->pPrivate->pPrinterAction = pAction;
+ g_signal_connect(pAction, "activate", G_CALLBACK(onPrinterItemActivated), self);
+
+ rebuildNow (self, SECTION_HEADER);
+}
+
+static GMenuModel *createPrintersSection (IndicatorPrintersService *self)
+{
+ self->pPrivate->pPrintersSection = g_menu_new ();
+ self->pPrivate->bVisible = FALSE;
+ cups_dest_t *lDests;
+ gint nDests = cupsGetDests (&lDests);
+
+ for (gint i = 0; i < nDests; i++)
+ {
+ const gchar *sOption = cupsGetOption ("printer-state", lDests[i].num_options, lDests[i].options);
+
+ if (sOption != NULL)
+ {
+ cups_job_t *lJobs;
+ gint nJobs = cupsGetJobs (&lJobs, lDests[i].name, 1, CUPS_WHICHJOBS_ACTIVE);
+ cupsFreeJobs (nJobs, lJobs);
+
+ if (nJobs < 0)
+ {
+ g_warning ("printer '%s' does not exist\n", lDests[i].name);
+ }
+ else if (nJobs != 0)
+ {
+ GMenuItem *pItem = g_menu_item_new (lDests[i].name, NULL);
+ g_menu_item_set_attribute (pItem, "x-ayatana-type", "s", "org.ayatana.indicator.basic");
+ g_menu_item_set_action_and_target_value(pItem, "indicator.printer", g_variant_new_string (lDests[i].name));
+ GIcon *pIcon = g_themed_icon_new_with_default_fallbacks ("printer");
+ GVariant *pSerialized = g_icon_serialize(pIcon);
+
+ if (pSerialized != NULL)
+ {
+ g_menu_item_set_attribute_value(pItem, G_MENU_ATTRIBUTE_ICON, pSerialized);
+ g_variant_unref(pSerialized);
+ }
+
+ g_object_unref(pIcon);
+
+ gint nState = atoi (sOption);
+
+ switch (nState)
+ {
+ case IPP_PRINTER_STOPPED:
+ {
+ g_menu_item_set_attribute (pItem, "x-ayatana-secondary-text", "s", _("Paused"));
+
+ break;
+ }
+ case IPP_PRINTER_PROCESSING:
+ {
+ g_menu_item_set_attribute (pItem, "x-ayatana-secondary-count", "i", nJobs);
+
+ break;
+ }
+ }
+
+ g_menu_append_item(self->pPrivate->pPrintersSection, pItem);
+ g_object_unref(pItem);
+ self->pPrivate->bVisible = TRUE;
+ }
+ }
+ }
+
+ cupsFreeDests (nDests, lDests);
+
+ return G_MENU_MODEL (self->pPrivate->pPrintersSection);
+}
+
+static void createMenu (IndicatorPrintersService *self, int nProfile)
+{
+ g_assert (0 <= nProfile && nProfile < N_PROFILES);
+ g_assert (self->pPrivate->lMenus[nProfile].pMenu == NULL);
+
+ GMenuModel *lSections[16];
+ guint nSection = 0;
+
+ // Build the sections
+ switch (nProfile)
+ {
+ case PROFILE_PHONE:
+ case PROFILE_DESKTOP:
+ {
+ lSections[nSection++] = createPrintersSection (self);
+
+ break;
+ }
+
+ break;
+ }
+
+ // Add sections to the submenu
+ GMenu *pSubmenu = g_menu_new ();
+
+ for (guint i = 0; i < nSection; ++i)
+ {
+ g_menu_append_section (pSubmenu, NULL, lSections[i]);
+ g_object_unref (lSections[i]);
}
- ippDelete (resp);
+ // Add submenu to the header
+ GMenuItem *pHeader = g_menu_item_new (NULL, "indicator._header");
+ g_menu_item_set_attribute (pHeader, "x-ayatana-type", "s", "org.ayatana.indicator.root");
+ g_menu_item_set_submenu (pHeader, G_MENU_MODEL (pSubmenu));
+ g_object_unref (pSubmenu);
+
+ // Add header to the menu
+ GMenu *pMenu = g_menu_new ();
+ g_menu_append_item (pMenu, pHeader);
+ g_object_unref (pHeader);
+
+ self->pPrivate->lMenus[nProfile].pMenu = pMenu;
+ self->pPrivate->lMenus[nProfile].pSubmenu = pSubmenu;
}
-static void
-name_lost (GDBusConnection *connection,
- const gchar *name,
- gpointer user_data)
+static void onBusAcquired (GDBusConnection *pConnection, const gchar *sName, gpointer pSelf)
{
- int subscription_id = GPOINTER_TO_INT (user_data);
+ g_debug ("bus acquired: %s", sName);
+
+ IndicatorPrintersService *self = INDICATOR_PRINTERS_SERVICE (pSelf);
+ guint nId;
+ GError *pError = NULL;
+ GString *pPath = g_string_new (NULL);
+ self->pPrivate->pConnection = (GDBusConnection*)g_object_ref (G_OBJECT (pConnection));
+
+ // Export the actions
+ if ((nId = g_dbus_connection_export_action_group (pConnection, INDICATOR_PRINTERS_DBUS_OBJECT_PATH, G_ACTION_GROUP (self->pPrivate->pActionGroup), &pError)))
+ {
+ self->pPrivate->nActionsId = nId;
+ }
+ else
+ {
+ g_warning ("cannot export action group: %s", pError->message);
+ g_clear_error (&pError);
+ }
- cancel_subscription (subscription_id);
- gtk_main_quit ();
+ // Export the menus
+ for (gint nProfile = 0; nProfile < N_PROFILES; ++nProfile)
+ {
+ struct ProfileMenuInfo *pInfo = &self->pPrivate->lMenus[nProfile];
+
+ g_string_printf (pPath, "%s/%s", INDICATOR_PRINTERS_DBUS_OBJECT_PATH, lMenuNames[nProfile]);
+
+ if ((nId = g_dbus_connection_export_menu_model (pConnection, pPath->str, G_MENU_MODEL (pInfo->pMenu), &pError)))
+ {
+ pInfo->nExportId = nId;
+ }
+ else
+ {
+ g_warning ("cannot export %s menu: %s", pPath->str, pError->message);
+ g_clear_error (&pError);
+ }
+ }
+
+ g_string_free (pPath, TRUE);
}
-int main (int argc, char *argv[])
+static void onNameLost (GDBusConnection *pConnection, const gchar *sName, gpointer pSelf)
{
- /* Init i18n */
- setlocale (LC_ALL, "");
- bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
- textdomain (GETTEXT_PACKAGE);
+ IndicatorPrintersService *self = INDICATOR_PRINTERS_SERVICE (pSelf);
- DbusmenuServer *menuserver;
- CupsNotifier *cups_notifier;
- IndicatorPrintersMenu *menu;
- IndicatorPrinterStateNotifier *state_notifier;
- GError *error = NULL;
- int subscription_id;
+ g_debug ("%s %s name lost %s", G_STRLOC, G_STRFUNC, sName);
- gtk_init (&argc, &argv);
+ unexport (self);
+}
- subscription_id = create_subscription ();
- g_timeout_add_seconds (NOTIFY_LEASE_DURATION - 60,
- renew_subscription_timeout,
- &subscription_id);
+static void indicator_printers_service_init (IndicatorPrintersService *self)
+{
+ self->pPrivate = indicator_printers_service_get_instance_private (self);
+ self->pPrivate->pCancellable = g_cancellable_new ();
+
+ GError *pError = NULL;
+ self->pPrivate->nSubscriptionId = createSubscription ();
+ g_timeout_add_seconds (NOTIFY_LEASE_DURATION - 60, renewSubscriptionTimeout, &self->pPrivate->nSubscriptionId);
+ self->pPrivate->pCupsNotifier = cups_notifier_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, 0, NULL, CUPS_DBUS_PATH, NULL, &pError);
+
+ if (pError)
+ {
+ g_error ("Error creating cups notify handler: %s", pError->message);
+ g_error_free (pError);
+ }
- g_bus_own_name (G_BUS_TYPE_SESSION,
- INDICATOR_PRINTERS_DBUS_NAME,
- G_BUS_NAME_OWNER_FLAGS_NONE,
- NULL, NULL, name_lost,
- GINT_TO_POINTER (subscription_id), NULL);
+ g_object_connect (self->pPrivate->pCupsNotifier, "signal::job-created", onJobChanged, self, "signal::job-state", onJobChanged, self, "signal::job-completed", onJobChanged, self, "signal::printer-state-changed", onPrinterStateChanged, self, NULL);
+ self->pPrivate->pStateNotifier = g_object_new (INDICATOR_TYPE_PRINTER_STATE_NOTIFIER, "cups-notifier", self->pPrivate->pCupsNotifier, NULL);
+ initActions (self);
- cups_notifier = cups_notifier_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
- 0,
- NULL,
- CUPS_DBUS_PATH,
- NULL,
- &error);
- if (error) {
- g_warning ("Error creating cups notify handler: %s", error->message);
- g_error_free (error);
- return 1;
+ for (gint nProfile = 0; nProfile < N_PROFILES; ++nProfile)
+ {
+ createMenu (self, nProfile);
}
- menu = g_object_new (INDICATOR_TYPE_PRINTERS_MENU,
- "cups-notifier", cups_notifier,
- NULL);
+ self->pPrivate->bMenusBuilt = TRUE;
+ self->pPrivate->nOwnId = g_bus_own_name (G_BUS_TYPE_SESSION, INDICATOR_PRINTERS_DBUS_NAME, G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT, onBusAcquired, NULL, onNameLost, self, NULL);
+}
+
+IndicatorPrintersService *indicator_printers_service_new ()
+{
+ GObject *pObject = g_object_new (INDICATOR_TYPE_PRINTERS_SERVICE, NULL);
+
+ return INDICATOR_PRINTERS_SERVICE (pObject);
+}
+
+static void rebuildSection (GMenu *pMenu, int nPos, GMenuModel *pSection)
+{
+ g_menu_remove (pMenu, nPos);
+ g_menu_insert_section (pMenu, nPos, NULL, pSection);
+ g_object_unref (pSection);
+}
- menuserver = dbusmenu_server_new (INDICATOR_PRINTERS_DBUS_OBJECT_PATH);
- dbusmenu_server_set_root (menuserver,
- indicator_printers_menu_get_root (menu));
+static void rebuildNow (IndicatorPrintersService *self, guint nSections)
+{
+ struct ProfileMenuInfo *pinfo = &self->pPrivate->lMenus[PROFILE_DESKTOP];
- state_notifier = g_object_new (INDICATOR_TYPE_PRINTER_STATE_NOTIFIER,
- "cups-notifier", cups_notifier,
- NULL);
+ if (nSections & SECTION_HEADER)
+ {
+ g_simple_action_set_state (self->pPrivate->pHeaderAction, createHeaderState (self));
+ }
- gtk_main ();
+ if (!self->pPrivate->bMenusBuilt)
+ {
+ return;
+ }
- g_object_unref (menu);
- g_object_unref (menuserver);
- g_object_unref (state_notifier);
- g_object_unref (cups_notifier);
- return 0;
+ if (nSections & SECTION_PRINTERS)
+ {
+ rebuildSection (pinfo->pSubmenu, 0, createPrintersSection (self));
+ }
}
diff --git a/src/indicator-printers-service.h b/src/indicator-printers-service.h
new file mode 100644
index 0000000..0b093c1
--- /dev/null
+++ b/src/indicator-printers-service.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2022 Robert Tari
+ *
+ * Authors: Robert Tari <robert@tari.in>
+ *
+ * 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 __INDICATOR_PRINTERS_SERVICE_H__
+#define __INDICATOR_PRINTERS_SERVICE_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define INDICATOR_PRINTERS_SERVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_PRINTERS_SERVICE, IndicatorPrintersService))
+#define INDICATOR_TYPE_PRINTERS_SERVICE (indicator_printers_service_get_type ())
+#define INDICATOR_IS_PRINTERS_SERVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_PRINTERS_SERVICE))
+
+typedef struct _IndicatorPrintersService IndicatorPrintersService;
+typedef struct _IndicatorPrintersServiceClass IndicatorPrintersServiceClass;
+typedef struct _IndicatorPrintersServicePrivate IndicatorPrintersServicePrivate;
+
+struct _IndicatorPrintersService
+{
+ GObject parent;
+ IndicatorPrintersServicePrivate *pPrivate;
+};
+
+struct _IndicatorPrintersServiceClass
+{
+ GObjectClass parent_class;
+ void (*pNameLost) (IndicatorPrintersService *self);
+};
+
+GType indicator_printers_service_get_type (void);
+IndicatorPrintersService *indicator_printers_service_new ();
+
+G_END_DECLS
+
+#endif
diff --git a/src/indicator-printers.c b/src/indicator-printers.c
deleted file mode 100644
index ba263c9..0000000
--- a/src/indicator-printers.c
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright 2012 Canonical Ltd.
- *
- * Authors: 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
- * 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 "config.h"
-
-#include "indicator-printers.h"
-#include "indicator-menu-item.h"
-#include "dbus-names.h"
-
-#include <glib/gi18n-lib.h>
-#include <gtk/gtk.h>
-#include <gio/gio.h>
-
-#include <libayatana-indicator/indicator.h>
-#include <libayatana-indicator/indicator-image-helper.h>
-
-#include <libdbusmenu-gtk/menu.h>
-#include <libdbusmenu-gtk/menuitem.h>
-
-
-INDICATOR_SET_VERSION
-INDICATOR_SET_TYPE(INDICATOR_PRINTERS_TYPE)
-
-struct _IndicatorPrintersPrivate
-{
- IndicatorObjectEntry entry;
- guint name_watch;
-};
-
-G_DEFINE_TYPE_WITH_PRIVATE(IndicatorPrinters, indicator_printers, INDICATOR_OBJECT_TYPE)
-
-static void
-dispose (GObject *object)
-{
- IndicatorPrinters *self = INDICATOR_PRINTERS (object);
- if (self->priv->name_watch != 0) {
- g_bus_unwatch_name(self->priv->name_watch);
- self->priv->name_watch = 0;
- }
- g_clear_object (&self->priv->entry.menu);
- g_clear_object (&self->priv->entry.image);
- G_OBJECT_CLASS (indicator_printers_parent_class)->dispose (object);
-}
-
-
-static GList *
-get_entries (IndicatorObject *io)
-{
- IndicatorPrinters *self = INDICATOR_PRINTERS (io);
- return g_list_append (NULL, &self->priv->entry);
-}
-
-
-static void
-indicator_printers_class_init (IndicatorPrintersClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- IndicatorObjectClass *io_class = INDICATOR_OBJECT_CLASS (klass);
-
- object_class->dispose = dispose;
-
- io_class->get_entries = get_entries;
-}
-
-
-static void
-name_vanished (GDBusConnection * con,
- const gchar * name,
- gpointer user_data)
-{
- IndicatorPrinters *self = INDICATOR_PRINTERS (user_data);
-
- indicator_object_set_visible (INDICATOR_OBJECT (self), FALSE);
-}
-
-
-static GdkPixbuf *
-gdk_pixbuf_new_from_encoded_data (guchar *data,
- gsize length)
-{
- GInputStream * input;
- GError *err = NULL;
- GdkPixbuf *img;
-
- input = g_memory_input_stream_new_from_data(data, length, NULL);
- if (input == NULL)
- return NULL;
-
- img = gdk_pixbuf_new_from_stream(input, NULL, &err);
- if (err) {
- g_warning("%s", err->message);
- g_error_free(err);
- }
-
- g_object_unref(input);
- return img;
-}
-
-
-static GdkPixbuf *
-g_variant_get_image (GVariant *value)
-{
- const gchar *strvalue = NULL;
- gsize length = 0;
- guchar *icondata;
- GdkPixbuf *img;
-
- if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
- strvalue = g_variant_get_string(value, NULL);
-
- if (!strvalue || !*strvalue) {
- g_warning ("%s: value does not contain a base64 encoded image",
- __func__);
- return NULL;
- }
-
- icondata = g_base64_decode(strvalue, &length);
- img = gdk_pixbuf_new_from_encoded_data (icondata, length);
-
- g_free(icondata);
- return img;
-}
-
-
-static gboolean
-properties_match (const gchar *name,
- const gchar *prop,
- GVariant *value,
- const GVariantType *type)
-{
- return !g_strcmp0 (name, prop) && g_variant_is_of_type (value, type);
-}
-
-
-static void
-indicator_prop_change_cb (DbusmenuMenuitem *mi,
- gchar *prop,
- GVariant *value,
- gpointer user_data)
-{
- IndicatorMenuItem *menuitem = user_data;
-
- if (properties_match (prop, "indicator-label", value, G_VARIANT_TYPE_STRING))
- indicator_menu_item_set_label (menuitem, g_variant_get_string (value, NULL));
-
- else if (properties_match (prop, "indicator-right", value, G_VARIANT_TYPE_STRING))
- indicator_menu_item_set_right (menuitem, g_variant_get_string (value, NULL));
-
- else if (properties_match (prop, "indicator-icon-name", value, G_VARIANT_TYPE_STRING))
- indicator_menu_item_set_icon_name (menuitem, g_variant_get_string (value, NULL));
-
- else if (properties_match (prop, "indicator-icon", value, G_VARIANT_TYPE_STRING)) {
- GdkPixbuf *pb = g_variant_get_image (value);
- indicator_menu_item_set_icon (menuitem, pb);
- g_object_unref (pb);
- }
-
- else if (properties_match (prop, "visible", value, G_VARIANT_TYPE_BOOLEAN))
- gtk_widget_set_visible (GTK_WIDGET (menuitem), g_variant_get_boolean (value));
-
- else if (properties_match (prop, "indicator-right-is-lozenge", value, G_VARIANT_TYPE_BOOLEAN))
- indicator_menu_item_set_right_is_lozenge (menuitem, g_variant_get_boolean (value));
-}
-
-
-static void
-root_property_changed (DbusmenuMenuitem *mi,
- gchar *prop,
- GVariant *value,
- gpointer user_data)
-{
- IndicatorObject *io = user_data;
-
- if (properties_match (prop, "visible", value, G_VARIANT_TYPE_BOOLEAN))
- indicator_object_set_visible (io, g_variant_get_boolean (value));
-}
-
-
-static gboolean
-new_indicator_item (DbusmenuMenuitem *newitem,
- DbusmenuMenuitem *parent,
- DbusmenuClient *client,
- gpointer user_data)
-{
- GtkWidget *menuitem;
- const gchar *icon_name, *text, *right_text;
- GVariant *icon;
- gboolean is_lozenge, visible;
-
- icon_name = dbusmenu_menuitem_property_get (newitem, "indicator-icon-name");
- icon = dbusmenu_menuitem_property_get_variant (newitem, "indicator-icon");
- text = dbusmenu_menuitem_property_get (newitem, "indicator-label");
- right_text = dbusmenu_menuitem_property_get (newitem, "indicator-right");
- is_lozenge = dbusmenu_menuitem_property_get_bool (newitem, "indicator-right-is-lozenge");
- visible = dbusmenu_menuitem_property_get_bool (newitem, "visible");
-
- menuitem = g_object_new (INDICATOR_TYPE_MENU_ITEM,
- "icon-name", icon_name,
- "label", text,
- "right", right_text,
- "right-is-lozenge", is_lozenge,
- "visible", visible,
- NULL);
- if (icon) {
- GdkPixbuf *pb = g_variant_get_image (icon);
- indicator_menu_item_set_icon (INDICATOR_MENU_ITEM (menuitem), pb);
- g_object_unref (pb);
- }
- gtk_widget_show_all (menuitem);
-
- dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client),
- newitem,
- GTK_MENU_ITEM (menuitem),
- parent);
-
- g_signal_connect(G_OBJECT(newitem),
- "property-changed",
- G_CALLBACK(indicator_prop_change_cb),
- menuitem);
-
- return TRUE;
-}
-
-
-static void
-root_changed (DbusmenuClient *client,
- DbusmenuMenuitem *newroot,
- gpointer user_data)
-{
- IndicatorPrinters *indicator = user_data;
- gboolean is_visible;
-
- if (newroot) {
- is_visible = dbusmenu_menuitem_property_get_bool (newroot, "visible");
- g_signal_connect (newroot, "property-changed",
- G_CALLBACK (root_property_changed), indicator);
- }
- else
- is_visible = FALSE;
-
- indicator_object_set_visible (INDICATOR_OBJECT (indicator), is_visible);
-}
-
-
-static void
-indicator_printers_init (IndicatorPrinters *self)
-{
- IndicatorPrintersPrivate *priv;
- DbusmenuGtkMenu *menu;
- DbusmenuClient *client;
- GtkImage *image;
-
- priv = indicator_printers_get_instance_private(self);
- self->priv = priv;
-
- priv->name_watch = g_bus_watch_name(G_BUS_TYPE_SESSION,
- INDICATOR_PRINTERS_DBUS_NAME,
- G_BUS_NAME_WATCHER_FLAGS_NONE,
- NULL, /* appeared */
- name_vanished,
- self, NULL);
-
- menu = dbusmenu_gtkmenu_new(INDICATOR_PRINTERS_DBUS_NAME,
- INDICATOR_PRINTERS_DBUS_OBJECT_PATH);
-
- client = DBUSMENU_CLIENT (dbusmenu_gtkmenu_get_client (menu));
- dbusmenu_client_add_type_handler(client,
- "indicator-item",
- new_indicator_item);
- g_signal_connect (client, "root-changed", G_CALLBACK (root_changed), self);
-
- image = indicator_image_helper ("printer-symbolic");
- gtk_widget_show (GTK_WIDGET (image));
-
- priv->entry.name_hint = PACKAGE_NAME;
- priv->entry.accessible_desc = _("Printers");
- priv->entry.menu = GTK_MENU (g_object_ref_sink (menu));
- priv->entry.image = g_object_ref_sink (image);
-
- indicator_object_set_visible (INDICATOR_OBJECT (self), FALSE);
-}
-
-
-IndicatorPrinters *
-indicator_printers_new (void)
-{
- return g_object_new (INDICATOR_PRINTERS_TYPE, NULL);
-}
diff --git a/src/indicator-printers.h b/src/indicator-printers.h
deleted file mode 100644
index 51b790c..0000000
--- a/src/indicator-printers.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2012 Canonical Ltd.
- *
- * Authors: 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
- * 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 INDICATOR_PRINTERS_H
-#define INDICATOR_PRINTERS_H
-
-#include <libayatana-indicator/indicator-object.h>
-
-G_BEGIN_DECLS
-
-#define INDICATOR_PRINTERS_TYPE indicator_printers_get_type()
-
-#define INDICATOR_PRINTERS(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
- INDICATOR_PRINTERS_TYPE, IndicatorPrinters))
-
-#define INDICATOR_PRINTERS_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), \
- INDICATOR_PRINTERS_TYPE, IndicatorPrintersClass))
-
-#define INDICATOR_IS_PRINTERS(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
- INDICATOR_PRINTERS_TYPE))
-
-#define INDICATOR_IS_PRINTERS_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), \
- INDICATOR_PRINTERS_TYPE))
-
-#define INDICATOR_PRINTERS_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), \
- INDICATOR_PRINTERS_TYPE, IndicatorPrintersClass))
-
-typedef struct _IndicatorPrinters IndicatorPrinters;
-typedef struct _IndicatorPrintersClass IndicatorPrintersClass;
-typedef struct _IndicatorPrintersPrivate IndicatorPrintersPrivate;
-
-struct _IndicatorPrinters
-{
- IndicatorObject parent;
- IndicatorPrintersPrivate *priv;
-};
-
-struct _IndicatorPrintersClass
-{
- IndicatorObjectClass parent_class;
-};
-
-GType indicator_printers_get_type (void) G_GNUC_CONST;
-
-IndicatorPrinters *indicator_printers_new (void);
-
-G_END_DECLS
-
-#endif
-
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..6cc5103
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2022 Robert Tari
+ *
+ * Authors:
+ * Robert Tari <robert@tari.in>
+ *
+ * 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 <locale.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include "indicator-printers-service.h"
+
+static void onNameLost (gpointer pInstance G_GNUC_UNUSED, gpointer pLoop)
+{
+ g_message("Exiting: service couldn't acquire or lost ownership of busname");
+ g_main_loop_quit ((GMainLoop*) pLoop);
+}
+
+int main (int argc G_GNUC_UNUSED, char **argv G_GNUC_UNUSED)
+{
+ setlocale (LC_ALL, "");
+ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ IndicatorPrintersService *pService = indicator_printers_service_new (NULL);
+ GMainLoop *pLoop = g_main_loop_new (NULL, FALSE);
+ g_signal_connect (pService, "name-lost", G_CALLBACK (onNameLost), pLoop);
+ g_main_loop_run (pLoop);
+
+ g_main_loop_unref (pLoop);
+ g_clear_object (&pService);
+
+ return 0;
+}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 0000000..78d8965
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,12 @@
+# cups-notifier.h
+# cups-notifier.c
+include (GdbusCodegen)
+add_gdbus_codegen_with_namespace (CUPS_NOTIFIER cups-notifier org.cups.cupsd Cups "${CMAKE_SOURCE_DIR}/src/org.cups.cupsd.Notifier.xml")
+
+# mock-cups-notifier
+add_executable (mock-cups-notifier mock-cups-notifier.c ${CUPS_NOTIFIER})
+target_include_directories (mock-cups-notifier PUBLIC ${SERVICE_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})
+target_link_libraries (mock-cups-notifier ${SERVICE_LIBRARIES})
+add_test (mock-cups-notifier mock-cups-notifier)
+
+
diff --git a/test/Makefile.am b/test/Makefile.am
deleted file mode 100644
index 0ecb702..0000000
--- a/test/Makefile.am
+++ /dev/null
@@ -1,30 +0,0 @@
-noinst_PROGRAMS = mock-cups-notifier
-DISTCLEANFILES = mock-cups-notifier
-
-cups_notifier_sources = \
- cups-notifier.c \
- cups-notifier.h
-
-$(cups_notifier_sources): $(top_srcdir)/src/org.cups.cupsd.Notifier.xml
- gdbus-codegen \
- --interface-prefix org.cups.cupsd \
- --c-namespace Cups \
- --generate-c-code cups-notifier \
- $^
-
-mock_cups_notifier_SOURCES = \
- mock-cups-notifier.c
-
-nodist_mock_cups_notifier_SOURCES = $(cups_notifier_sources)
-
-mock_cups_notifier_CPPFLAGS = \
- $(SERVICE_CFLAGS) \
- -I$(top_builddir)/src
-
-mock_cups_notifier_LDADD = $(SERVICE_LIBS)
-
-BUILT_SOURCES = $(cups_notifier_sources)
-CLEANFILES = $(BUILT_SOURCES)
-
-DISTCLEANFILES = \
- Makefile.in \ No newline at end of file
diff --git a/update-po.sh b/update-po.sh
index 5f9e9fd..2043358 100755
--- a/update-po.sh
+++ b/update-po.sh
@@ -16,7 +16,7 @@ set -x
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
-GETTEXT_DOMAIN=$(cat configure.ac | grep -E "^GETTEXT_PACKAGE=" | sed -e 's/GETTEXT_PACKAGE=//')
+GETTEXT_DOMAIN=$(cat CMakeLists.txt | grep 'set.*(.*GETTEXT_PACKAGE' | sed -r -e 's/.*\"([^"]+)\"\)/\1/')
cp po/${GETTEXT_DOMAIN}.pot po/${GETTEXT_DOMAIN}.pot~
diff --git a/update-pot.sh b/update-pot.sh
index b0cb9b5..43a8d06 100755
--- a/update-pot.sh
+++ b/update-pot.sh
@@ -14,7 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
-GETTEXT_DOMAIN=$(cat configure.ac | grep -E "^GETTEXT_PACKAGE=" | sed -e 's/GETTEXT_PACKAGE=//')
+GETTEXT_DOMAIN=$(cat CMakeLists.txt | grep 'set.*(.*GETTEXT_PACKAGE' | sed -r -e 's/.*\"([^"]+)\"\)/\1/')
cd po/ && intltool-update --gettext-package ${GETTEXT_DOMAIN} --pot && cd - 1>/dev/null