diff options
-rw-r--r-- | .bzrignore | 1 | ||||
-rw-r--r-- | src/Makefile.am | 18 | ||||
-rw-r--r-- | src/indicator-printers-menu.c | 136 | ||||
-rw-r--r-- | src/org.cups.cupsd.Notifier.xml | 147 |
4 files changed, 277 insertions, 25 deletions
@@ -25,4 +25,5 @@ src/Makefile.in src/indicator-printers-service src/*.la src/*.lo +src/cups-notifier.[ch] diff --git a/src/Makefile.am b/src/Makefile.am index 5684e70..7b66b1b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,13 +12,29 @@ libprintersmenu_la_LIBADD = $(APPLET_LIBS) libprintersmenu_la_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 \ + $^ + + libexec_PROGRAMS = indicator-printers-service indicator_printers_service_SOURCES = \ indicator-printers-service.c \ indicator-printers-service.h \ indicator-printers-menu.c \ - indicator-printers-menu.h + indicator-printers-menu.h \ + $(cups_notifier_sources) indicator_printers_service_CPPFLAGS = $(SERVICE_CFLAGS) indicator_printers_service_LDADD = $(SERVICE_LIBS) + +BUILT_SOURCES = $(cups_notifier_sources) + diff --git a/src/indicator-printers-menu.c b/src/indicator-printers-menu.c index e0cfd4b..8aa4c62 100644 --- a/src/indicator-printers-menu.c +++ b/src/indicator-printers-menu.c @@ -4,6 +4,8 @@ #include <gio/gio.h> #include <cups/cups.h> +#include "cups-notifier.h" + G_DEFINE_TYPE (IndicatorPrintersMenu, indicator_printers_menu, G_TYPE_OBJECT) @@ -15,6 +17,7 @@ struct _IndicatorPrintersMenuPrivate { DbusmenuMenuitem *root; GHashTable *printers; /* printer name -> dbusmenuitem */ + CupsNotifier *cups_notifier; }; @@ -29,6 +32,7 @@ dispose (GObject *object) } g_clear_object (&priv->root); + g_clear_object (&priv->cups_notifier); G_OBJECT_CLASS (indicator_printers_menu_parent_class)->dispose (object); } @@ -45,6 +49,19 @@ indicator_printers_menu_class_init (IndicatorPrintersMenuClass *klass) } +static int +get_number_of_active_jobs (const gchar *printer) +{ + int njobs; + cups_job_t *jobs; + + njobs = cupsGetJobs (&jobs, printer, 1, CUPS_WHICHJOBS_ACTIVE); + cupsFreeJobs (njobs, jobs); + + return njobs; +} + + static void show_system_settings (DbusmenuMenuitem *menuitem, guint timestamp, @@ -79,19 +96,35 @@ show_system_settings (DbusmenuMenuitem *menuitem, g_object_unref (appinfo); } + static void -add_printer_menuitem (IndicatorPrintersMenu *self, - const char *printer, - int state, - int njobs) +update_printer_menuitem (IndicatorPrintersMenu *self, + const char *printer, + int state, + int njobs) { IndicatorPrintersMenuPrivate *priv = PRINTERS_MENU_PRIVATE (self); DbusmenuMenuitem *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); + item = g_hash_table_lookup (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"); + g_signal_connect_data (item, "item-activated", + G_CALLBACK (show_system_settings), + g_strdup (printer), (GClosureNotify) g_free, 0); + + dbusmenu_menuitem_child_append(priv->root, item); + g_hash_table_insert (priv->printers, g_strdup (printer), item); + } + + if (njobs == 0) { + dbusmenu_menuitem_property_set_bool (item, "visible", FALSE); + return; + } + dbusmenu_menuitem_property_set_bool (item, "visible", TRUE); switch (state) { @@ -108,13 +141,49 @@ add_printer_menuitem (IndicatorPrintersMenu *self, break; } } +} + + +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); + + update_printer_menuitem (self, + printer_name, + printer_state, + get_number_of_active_jobs (printer_name)); +} + - g_signal_connect_data (item, "item-activated", - G_CALLBACK (show_system_settings), - g_strdup (printer), (GClosureNotify) g_free, 0); +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); - dbusmenu_menuitem_child_append(priv->root, item); - g_hash_table_insert (priv->printers, g_strdup (printer), item); + update_printer_menuitem (self, + printer_name, + printer_state, + get_number_of_active_jobs (printer_name)); } @@ -122,9 +191,9 @@ static void indicator_printers_menu_init (IndicatorPrintersMenu *self) { IndicatorPrintersMenuPrivate *priv = PRINTERS_MENU_PRIVATE (self); - int ndests, njobs, i, state; + int ndests, i; cups_dest_t *dests; - cups_job_t *jobs; + GError *error = NULL; priv->root = dbusmenu_menuitem_new (); @@ -133,18 +202,37 @@ indicator_printers_menu_init (IndicatorPrintersMenu *self) g_free, g_object_unref); + priv->cups_notifier = cups_notifier_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + 0, + NULL, + "/org/cups/cupsd/Notifier", + NULL, + &error); + if (error) { + g_warning ("Error creating cups notify handler: %s", error->message); + g_clear_error (&error); + } + else { + g_signal_connect (priv->cups_notifier, "job-created", + G_CALLBACK (update_job), self); + g_signal_connect (priv->cups_notifier, "job-state", + G_CALLBACK (update_job), self); + g_signal_connect (priv->cups_notifier, "job-completed", + G_CALLBACK (update_job), self); + g_signal_connect (priv->cups_notifier, "printer-state-changed", + G_CALLBACK (on_printer_state_changed), self); + } + /* create initial menu items */ ndests = cupsGetDests (&dests); for (i = 0; i < ndests; i++) { - njobs = cupsGetJobs (&jobs, dests[i].name, 1, CUPS_WHICHJOBS_ACTIVE); - state = atoi (cupsGetOption ("printer-state", - dests[i].num_options, - dests[i].options)); - - if (njobs > 0) - add_printer_menuitem (self, dests[i].name, state, njobs); - - cupsFreeJobs (njobs, jobs); + int state = atoi (cupsGetOption ("printer-state", + dests[i].num_options, + dests[i].options)); + update_printer_menuitem (self, + dests[i].name, + state, + get_number_of_active_jobs (dests[i].name)); } cupsFreeDests (ndests, dests); } diff --git a/src/org.cups.cupsd.Notifier.xml b/src/org.cups.cupsd.Notifier.xml new file mode 100644 index 0000000..e70a5c3 --- /dev/null +++ b/src/org.cups.cupsd.Notifier.xml @@ -0,0 +1,147 @@ +<node> + + <interface name="org.cups.cupsd.Notifier"> + + <signal name="ServerStarted"> + <arg type="s" name="text" /> + </signal> + + <signal name="ServerRestarted"> + <arg type="s" name="text" /> + </signal> + + <signal name="ServerStopped"> + <arg type="s" name="text" /> + </signal> + + <signal name="ServerAudit"> + <arg type="s" name="text" /> + </signal> + + <signal name="PrinterAdded"> + <arg type="s" name="text" /> + <arg type="s" name="printer_uri" /> + <arg type="s" name="printer_name" /> + <arg type="u" name="printer_state" /> + <arg type="s" name="printer_state_reasons" /> + <arg type="b" name="printer_is_accepting_jobs" /> + </signal> + + <signal name="PrinterDeleted"> + <arg type="s" name="text" /> + <arg type="s" name="printer_uri" /> + <arg type="s" name="printer_name" /> + <arg type="u" name="printer_state" /> + <arg type="s" name="printer_state_reasons" /> + <arg type="b" name="printer_is_accepting_jobs" /> + </signal> + + <signal name="PrinterModified"> + <arg type="s" name="text" /> + <arg type="s" name="printer_uri" /> + <arg type="s" name="printer_name" /> + <arg type="u" name="printer_state" /> + <arg type="s" name="printer_state_reasons" /> + <arg type="b" name="printer_is_accepting_jobs" /> + </signal> + + <signal name="PrinterRestarted"> + <arg type="s" name="text" /> + <arg type="s" name="printer_uri" /> + <arg type="s" name="printer_name" /> + <arg type="u" name="printer_state" /> + <arg type="s" name="printer_state_reasons" /> + <arg type="b" name="printer_is_accepting_jobs" /> + </signal> + + <signal name="PrinterStopped"> + <arg type="s" name="text" /> + <arg type="s" name="printer_uri" /> + <arg type="s" name="printer_name" /> + <arg type="u" name="printer_state" /> + <arg type="s" name="printer_state_reasons" /> + <arg type="b" name="printer_is_accepting_jobs" /> + </signal> + + <signal name="PrinterShutdown"> + <arg type="s" name="text" /> + <arg type="s" name="printer_uri" /> + <arg type="s" name="printer_name" /> + <arg type="u" name="printer_state" /> + <arg type="s" name="printer_state_reasons" /> + <arg type="b" name="printer_is_accepting_jobs" /> + </signal> + + <signal name="PrinterStateChanged"> + <arg type="s" name="text" /> + <arg type="s" name="printer_uri" /> + <arg type="s" name="printer_name" /> + <arg type="u" name="printer_state" /> + <arg type="s" name="printer_state_reasons" /> + <arg type="b" name="printer_is_accepting_jobs" /> + </signal> + + <signal name="PrinterFinishingsChanged"> + <arg type="s" name="text" /> + <arg type="s" name="printer_uri" /> + <arg type="s" name="printer_name" /> + <arg type="u" name="printer_state" /> + <arg type="s" name="printer_state_reasons" /> + <arg type="b" name="printer_is_accepting_jobs" /> + </signal> + + <signal name="PrinterMediaChanged"> + <arg type="s" name="text" /> + <arg type="s" name="printer_uri" /> + <arg type="s" name="printer_name" /> + <arg type="u" name="printer_state" /> + <arg type="s" name="printer_state_reasons" /> + <arg type="b" name="printer_is_accepting_jobs" /> + </signal> + + <signal name="JobCreated"> + <arg type="s" name="text" /> + <arg type="s" name="printer_uri" /> + <arg type="s" name="printer_name" /> + <arg type="u" name="printer_state" /> + <arg type="s" name="printer_state_reasons" /> + <arg type="b" name="printer_is_accepting_jobs" /> + <arg type="u" name="job_id" /> + <arg type="u" name="job_state" /> + <arg type="s" name="job_state_reasons" /> + <arg type="s" name="job_name" /> + <arg type="u" name="job_impressions_completed" /> + </signal> + + <signal name="JobCompleted"> + <arg type="s" name="text" /> + <arg type="s" name="printer_uri" /> + <arg type="s" name="printer_name" /> + <arg type="u" name="printer_state" /> + <arg type="s" name="printer_state_reasons" /> + <arg type="b" name="printer_is_accepting_jobs" /> + <arg type="u" name="job_id" /> + <arg type="u" name="job_state" /> + <arg type="s" name="job_state_reasons" /> + <arg type="s" name="job_name" /> + <arg type="u" name="job_impressions_completed" /> + </signal> + + <signal name="JobState"> + <arg type="s" name="text" /> + <arg type="s" name="printer_uri" /> + <arg type="s" name="printer_name" /> + <arg type="u" name="printer_state" /> + <arg type="s" name="printer_state_reasons" /> + <arg type="b" name="printer_is_accepting_jobs" /> + <arg type="u" name="job_id" /> + <arg type="u" name="job_state" /> + <arg type="s" name="job_state_reasons" /> + <arg type="s" name="job_name" /> + <arg type="u" name="job_impressions_completed" /> + </signal> + + </interface> + +</node> + |