diff options
Diffstat (limited to 'src/indicator-printers-menu.c')
-rw-r--r-- | src/indicator-printers-menu.c | 136 |
1 files changed, 112 insertions, 24 deletions
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); } |