~ubuntu-branches/ubuntu/saucy/gnome-settings-daemon/saucy-proposed

« back to all changes in this revision

Viewing changes to plugins/print-notifications/gsd-print-notifications-manager.c

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha, Tim Lunn, Jeremy Bicha, Rico Tzschichholz
  • Date: 2013-09-09 10:21:09 UTC
  • mfrom: (1.1.64)
  • Revision ID: package-import@ubuntu.com-20130909102109-t2zyyll79urcfz56
Tags: 3.8.5-0ubuntu1
[ Tim Lunn ]
* Refreshed patches
* debian/patches: 
  - fix_media_keys_on_unity.patch:
    Use legacy media keys keygrabber when running Unity
  - git_revert_remove_automount_helper.patch: bring back the automount
    helper, revert upstream commit and port to dbus session tracking.
  - fix_screenshots_on_unity.patch: bring back support for screenshots
    via gnome-screenshot when using unity.
  - ubuntu-lid-close-suspend.patch:
     Reimplement support for setting lid close suspend actions
  - ubuntu-fix-desktop-file.patch: Autostart in Unity too
  - fix_input_switching_on_unity.patch: Bring back support for input
    switching under Unity
  - 63_gnome_disable_background_plugin.patch: Disable loading
    of background plugin for GNOME session (LP: #1219148)

* Dropped obsolete patches:
  - power-check-null-devices.patch, Dropped: Applied in new version
  - 51_lock_screen_on_suspend.patch, Superseded by handling this key
    in gnome-screensaver. With that, g-screensaver mirrors what's
    done in g-shell, and avoids patching settings-daemon.
* gnome-settings-daemon.gsettings-override:
  - Update switch input source keys for 3.8

[ Jeremy Bicha ]
* New upstream release (LP: #1219486)
  - Two-finger scrolling enabled by default (LP: #1217166)
  - But use edge scrolling if two-finger scrolling isn't
    available (LP: #1221367)
  - Fix Super+Space switch-input-source shortcut in Unity (LP: #1201679)
* debian/control.in:
  - Bump minimum glib, gsettings-desktop-schemas, gnome-desktop3, gtk,
    libpulse, and libwacom
  - Build-depend on librsvg2-dev
  - This update needs changes to gnome-control-center so break older
    versions
* Refreshed patches
* revert_background_dropping.patch:
  - Don't drop the background plugin yet, GNOME Fallback & Unity
    still need it (when Nautilus isn't handling the desktop)
* Dropped obsolete patches:
  - bugzilla_segfault_dpms.patch: Applied in new version
  - 47_delay_pa_connect_to_idle.patch: Applied in new version
  - power-no-fallback-notifications.patch: Applied in new version
  - 60_unity_hide_status_icon.patch
  - 61_unity_use_application_indicator.patch
  - 63_unity_start_mounter.patch
  - logind_support.patch
  - and patches backported from 3.8
* Disabled patch that need to be rewritten or dropped:
  - 48_register_client_before_idle_callbacks.patch
* debian/patches/touchscreen_rotation.patch:
  - Updated with latest version from bugzilla
* debian/patches/git_revert_hardcoded_input_methods.patch:
  - Add patch from git (and also applied in Fedora 19) to not hardcode
    input methods based on the current locale

[ Rico Tzschichholz ]
* debian/patches:
  - 16_use_synchronous_notifications.patch: Refreshed

Show diffs side-by-side

added added

removed removed

Lines of Context:
52
52
#define CONNECTING_TIMEOUT               60
53
53
#define REASON_TIMEOUT                   15000
54
54
#define CUPS_CONNECTION_TEST_INTERVAL    300
 
55
#define CHECK_INTERVAL                   60 /* secs */
55
56
 
56
57
#if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 5)
57
58
#define HAVE_CUPS_1_6 1
61
62
#define ippGetStatusCode(ipp) ipp->request.status.status_code
62
63
#define ippGetInteger(attr, element) attr->values[element].integer
63
64
#define ippGetString(attr, element, language) attr->values[element].string.text
 
65
#define ippGetName(attr) attr->name
 
66
#define ippGetCount(attr) attr->num_values
 
67
#define ippGetBoolean(attr, index) attr->values[index].boolean
 
68
 
 
69
static ipp_attribute_t *
 
70
ippNextAttribute (ipp_t *ipp)
 
71
{
 
72
  if (!ipp || !ipp->current)
 
73
    return (NULL);
 
74
  return (ipp->current = ipp->current->next);
 
75
}
64
76
#endif
65
77
 
66
78
struct GsdPrintNotificationsManagerPrivate
75
87
        GHashTable                   *printing_printers;
76
88
        GList                        *active_notifications;
77
89
        guint                         cups_connection_timeout_id;
 
90
        guint                         check_source_id;
 
91
        guint                         cups_dbus_subscription_id;
 
92
        guint                         renew_source_id;
 
93
        gint                          last_notify_sequence_number;
78
94
};
79
95
 
80
96
enum {
85
101
static void     gsd_print_notifications_manager_init        (GsdPrintNotificationsManager      *print_notifications_manager);
86
102
static void     gsd_print_notifications_manager_finalize    (GObject                           *object);
87
103
static gboolean cups_connection_test                        (gpointer                           user_data);
 
104
static gboolean process_new_notifications                   (gpointer                           user_data);
88
105
 
89
106
G_DEFINE_TYPE (GsdPrintNotificationsManager, gsd_print_notifications_manager, G_TYPE_OBJECT)
90
107
 
144
161
        return !is_remote;
145
162
}
146
163
 
 
164
static gboolean
 
165
server_is_local (const gchar *server_name)
 
166
{
 
167
        if (server_name != NULL &&
 
168
            (g_ascii_strncasecmp (server_name, "localhost", 9) == 0 ||
 
169
             g_ascii_strncasecmp (server_name, "127.0.0.1", 9) == 0 ||
 
170
             g_ascii_strncasecmp (server_name, "::1", 3) == 0 ||
 
171
             server_name[0] == '/')) {
 
172
                return TRUE;
 
173
        } else {
 
174
                return FALSE;
 
175
        }
 
176
}
 
177
 
147
178
static int
148
179
strcmp0(const void *a, const void *b)
149
180
{
285
316
                      GVariant        *parameters,
286
317
                      gpointer         user_data)
287
318
{
288
 
        GsdPrintNotificationsManager *manager = (GsdPrintNotificationsManager *) user_data;
289
 
        gboolean                     printer_is_accepting_jobs;
290
 
        gboolean                     my_job = FALSE;
291
 
        gboolean                     known_reason;
292
 
        http_t                      *http;
293
 
        gchar                       *printer_name = NULL;
294
 
        gchar                       *primary_text = NULL;
295
 
        gchar                       *secondary_text = NULL;
296
 
        gchar                       *text = NULL;
297
 
        gchar                       *printer_uri = NULL;
298
 
        gchar                       *printer_state_reasons = NULL;
299
 
        gchar                       *job_state_reasons = NULL;
300
 
        gchar                       *job_name = NULL;
301
 
        gchar                       *job_uri = NULL;
302
 
        guint                        job_id;
303
 
        ipp_t                       *request, *response;
304
 
        gint                         printer_state;
305
 
        gint                         job_state;
306
 
        gint                         job_impressions_completed;
 
319
        process_new_notifications (user_data);
 
320
}
 
321
 
 
322
static void
 
323
process_cups_notification (GsdPrintNotificationsManager *manager,
 
324
                           const char                   *notify_subscribed_event,
 
325
                           const char                   *notify_text,
 
326
                           const char                   *notify_printer_uri,
 
327
                           const char                   *printer_name,
 
328
                           gint                          printer_state,
 
329
                           const char                   *printer_state_reasons,
 
330
                           gboolean                      printer_is_accepting_jobs,
 
331
                           guint                         notify_job_id,
 
332
                           gint                          job_state,
 
333
                           const char                   *job_state_reasons,
 
334
                           const char                   *job_name,
 
335
                           gint                          job_impressions_completed)
 
336
{
 
337
        ipp_attribute_t *attr;
 
338
        gboolean         my_job = FALSE;
 
339
        gboolean         known_reason;
 
340
        http_t          *http;
 
341
        gchar           *primary_text = NULL;
 
342
        gchar           *secondary_text = NULL;
 
343
        gchar           *job_uri = NULL;
 
344
        ipp_t           *request, *response;
307
345
        static const char * const reasons[] = {
308
346
                "toner-low",
309
347
                "toner-empty",
371
409
                /* Translators: The printer has detected an error (same as in system-config-printer) */
372
410
                N_("There is a problem on printer '%s'.") };
373
411
 
374
 
        if (g_strcmp0 (signal_name, "PrinterAdded") != 0 &&
375
 
            g_strcmp0 (signal_name, "PrinterDeleted") != 0 &&
376
 
            g_strcmp0 (signal_name, "PrinterStateChanged") != 0 &&
377
 
            g_strcmp0 (signal_name, "JobCompleted") != 0 &&
378
 
            g_strcmp0 (signal_name, "JobState") != 0 &&
379
 
            g_strcmp0 (signal_name, "JobCreated") != 0)
 
412
        if (g_strcmp0 (notify_subscribed_event, "printer-added") != 0 &&
 
413
            g_strcmp0 (notify_subscribed_event, "printer-deleted") != 0 &&
 
414
            g_strcmp0 (notify_subscribed_event, "printer-state-changed") != 0 &&
 
415
            g_strcmp0 (notify_subscribed_event, "job-completed") != 0 &&
 
416
            g_strcmp0 (notify_subscribed_event, "job-state-changed") != 0 &&
 
417
            g_strcmp0 (notify_subscribed_event, "job-created") != 0)
380
418
                return;
381
419
 
382
 
        if (g_variant_n_children (parameters) == 1) {
383
 
                g_variant_get (parameters, "(&s)", &text);
384
 
        } else if (g_variant_n_children (parameters) == 6) {
385
 
                g_variant_get (parameters, "(&s&s&su&sb)",
386
 
                               &text,
387
 
                               &printer_uri,
388
 
                               &printer_name,
389
 
                               &printer_state,
390
 
                               &printer_state_reasons,
391
 
                               &printer_is_accepting_jobs);
392
 
        } else if (g_variant_n_children (parameters) == 11) {
393
 
                ipp_attribute_t *attr;
394
 
 
395
 
                g_variant_get (parameters, "(&s&s&su&sbuu&s&su)",
396
 
                               &text,
397
 
                               &printer_uri,
398
 
                               &printer_name,
399
 
                               &printer_state,
400
 
                               &printer_state_reasons,
401
 
                               &printer_is_accepting_jobs,
402
 
                               &job_id,
403
 
                               &job_state,
404
 
                               &job_state_reasons,
405
 
                               &job_name,
406
 
                               &job_impressions_completed);
407
 
 
 
420
        if (notify_job_id > 0) {
408
421
                if ((http = httpConnectEncrypt (cupsServer (), ippPort (),
409
422
                                                cupsEncryption ())) == NULL) {
410
423
                        g_debug ("Connection to CUPS server \'%s\' failed.", cupsServer ());
411
 
                }
412
 
                else {
413
 
                        job_uri = g_strdup_printf ("ipp://localhost/jobs/%d", job_id);
 
424
                } else {
 
425
                        job_uri = g_strdup_printf ("ipp://localhost/jobs/%d", notify_job_id);
414
426
 
415
427
                        request = ippNewRequest (IPP_GET_JOB_ATTRIBUTES);
416
428
                        ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
433
445
                        g_free (job_uri);
434
446
                }
435
447
        }
436
 
        else {
437
 
                g_warning ("Invalid number of parameters for signal '%s'", signal_name);
438
 
                return;
439
 
        }
440
448
 
441
 
        if (g_strcmp0 (signal_name, "PrinterAdded") == 0) {
 
449
        if (g_strcmp0 (notify_subscribed_event, "printer-added") == 0) {
442
450
                cupsFreeDests (manager->priv->num_dests, manager->priv->dests);
443
451
                manager->priv->num_dests = cupsGetDests (&manager->priv->dests);
444
452
 
445
 
                /* Translators: New printer has been added */
446
453
                if (is_local_dest (printer_name,
447
454
                                   manager->priv->dests,
448
455
                                   manager->priv->num_dests)) {
 
456
                        /* Translators: New printer has been added */
449
457
                        primary_text = g_strdup (_("Printer added"));
450
458
                        secondary_text = g_strdup (printer_name);
451
459
                }
452
 
        } else if (g_strcmp0 (signal_name, "PrinterDeleted") == 0) {
453
 
                /* Translators: A printer has been removed */
 
460
        } else if (g_strcmp0 (notify_subscribed_event, "printer-deleted") == 0) {
454
461
                if (is_local_dest (printer_name,
455
462
                                   manager->priv->dests,
456
463
                                   manager->priv->num_dests)) {
 
464
                        /* Translators: A printer has been removed */
457
465
                        primary_text = g_strdup (_("Printer removed"));
458
466
                        secondary_text = g_strdup (printer_name);
459
467
                }
460
468
 
461
469
                cupsFreeDests (manager->priv->num_dests, manager->priv->dests);
462
470
                manager->priv->num_dests = cupsGetDests (&manager->priv->dests);
463
 
        } else if (g_strcmp0 (signal_name, "JobCompleted") == 0 && my_job) {
 
471
        } else if (g_strcmp0 (notify_subscribed_event, "job-completed") == 0 && my_job) {
464
472
                g_hash_table_remove (manager->priv->printing_printers,
465
473
                                     printer_name);
466
474
 
494
502
                                secondary_text = g_strdup_printf (_("\"%s\" on %s"), job_name, printer_name);
495
503
                                break;
496
504
                }
497
 
        } else if (g_strcmp0 (signal_name, "JobState") == 0 && my_job) {
 
505
        } else if (g_strcmp0 (notify_subscribed_event, "job-state-changed") == 0 && my_job) {
498
506
                switch (job_state) {
499
507
                        case IPP_JOB_PROCESSING:
500
508
                                g_hash_table_insert (manager->priv->printing_printers,
506
514
                                secondary_text = g_strdup_printf (_("\"%s\" on %s"), job_name, printer_name);
507
515
                                break;
508
516
                        case IPP_JOB_STOPPED:
 
517
                                g_hash_table_remove (manager->priv->printing_printers,
 
518
                                                     printer_name);
 
519
                                /* Translators: A print job has been stopped */
 
520
                                primary_text = g_strdup (_("Printing stopped"));
 
521
                                /* Translators: "print-job xy" on a printer */
 
522
                                secondary_text = g_strdup_printf (_("\"%s\" on %s"), job_name, printer_name);
 
523
                                break;
509
524
                        case IPP_JOB_CANCELED:
 
525
                                g_hash_table_remove (manager->priv->printing_printers,
 
526
                                                     printer_name);
 
527
                                /* Translators: A print job has been canceled */
 
528
                                primary_text = g_strdup (_("Printing canceled"));
 
529
                                /* Translators: "print-job xy" on a printer */
 
530
                                secondary_text = g_strdup_printf (_("\"%s\" on %s"), job_name, printer_name);
 
531
                                break;
510
532
                        case IPP_JOB_ABORTED:
 
533
                                g_hash_table_remove (manager->priv->printing_printers,
 
534
                                                     printer_name);
 
535
                                /* Translators: A print job has been aborted */
 
536
                                primary_text = g_strdup (_("Printing aborted"));
 
537
                                /* Translators: "print-job xy" on a printer */
 
538
                                secondary_text = g_strdup_printf (_("\"%s\" on %s"), job_name, printer_name);
 
539
                                break;
511
540
                        case IPP_JOB_COMPLETED:
512
541
                                g_hash_table_remove (manager->priv->printing_printers,
513
542
                                                     printer_name);
 
543
                                /* Translators: A print job has been completed */
 
544
                                primary_text = g_strdup (_("Printing completed"));
 
545
                                /* Translators: "print-job xy" on a printer */
 
546
                                secondary_text = g_strdup_printf (_("\"%s\" on %s"), job_name, printer_name);
514
547
                                break;
515
548
                        default:
516
549
                                break;
517
550
                }
518
 
        } else if (g_strcmp0 (signal_name, "JobCreated") == 0 && my_job) {
 
551
        } else if (g_strcmp0 (notify_subscribed_event, "job-created") == 0 && my_job) {
519
552
                if (job_state == IPP_JOB_PROCESSING) {
520
553
                        g_hash_table_insert (manager->priv->printing_printers,
521
554
                                             g_strdup (printer_name), NULL);
525
558
                        /* Translators: "print-job xy" on a printer */
526
559
                        secondary_text = g_strdup_printf (_("\"%s\" on %s"), job_name, printer_name);
527
560
                }
528
 
        } else if (g_strcmp0 (signal_name, "PrinterStateChanged") == 0) {
 
561
        } else if (g_strcmp0 (notify_subscribed_event, "printer-state-changed") == 0) {
529
562
                cups_dest_t  *dest = NULL;
530
563
                const gchar  *tmp_printer_state_reasons = NULL;
531
564
                GSList       *added_reasons = NULL;
632
665
                                                added_reasons = g_slist_append (added_reasons,
633
666
                                                                                new_state_reasons[i]);
634
667
                                }
635
 
                        }
636
 
                        else {
 
668
                        } else {
637
669
                                for (i = 0; new_state_reasons && i < g_strv_length (new_state_reasons); i++) {
638
670
                                        added_reasons = g_slist_append (added_reasons,
639
671
                                                                        new_state_reasons[i]);
655
687
 
656
688
                                                        data = g_new0 (TimeoutData, 1);
657
689
                                                        data->printer_name = g_strdup (printer_name);
658
 
                                                        data->primary_text = g_strdup (statuses_first[j]);
659
 
                                                        data->secondary_text = g_strdup_printf (statuses_second[j], printer_name);
 
690
                                                        data->primary_text = g_strdup ( _(statuses_first[j]));
 
691
                                                        data->secondary_text = g_strdup_printf ( _(statuses_second[j]), printer_name);
660
692
                                                        data->manager = manager;
661
693
 
662
694
                                                        data->timeout_id = g_timeout_add_seconds (CONNECTING_TIMEOUT, show_notification, data);
663
695
                                                        manager->priv->timeouts = g_list_append (manager->priv->timeouts, data);
664
 
                                                }
665
 
                                                else {
 
696
                                                } else {
666
697
                                                        ReasonData *reason_data;
667
 
                                                        gchar *second_row = g_strdup_printf (statuses_second[j], printer_name);
 
698
                                                        gchar *second_row = g_strdup_printf ( _(statuses_second[j]), printer_name);
668
699
 
669
 
                                                        notification = notify_notification_new (statuses_first[j],
 
700
                                                        notification = notify_notification_new ( _(statuses_first[j]),
670
701
                                                                                                second_row,
671
702
                                                                                                "printer-symbolic");
672
703
                                                        notify_notification_set_app_name (notification, _("Printers"));
811
842
        }
812
843
}
813
844
 
 
845
static gboolean
 
846
process_new_notifications (gpointer user_data)
 
847
{
 
848
        GsdPrintNotificationsManager  *manager = (GsdPrintNotificationsManager *) user_data;
 
849
        ipp_attribute_t               *attr;
 
850
        const gchar                   *notify_subscribed_event = NULL;
 
851
        const gchar                   *printer_name = NULL;
 
852
        const gchar                   *notify_text = NULL;
 
853
        const gchar                   *notify_printer_uri = NULL;
 
854
        const gchar                   *job_state_reasons = NULL;
 
855
        const gchar                   *job_name = NULL;
 
856
        const char                    *attr_name;
 
857
        gboolean                       printer_is_accepting_jobs = FALSE;
 
858
        gchar                         *printer_state_reasons = NULL;
 
859
        gchar                        **reasons;
 
860
        guint                          notify_job_id = 0;
 
861
        ipp_t                         *request;
 
862
        ipp_t                         *response;
 
863
        gint                           printer_state = -1;
 
864
        gint                           job_state = -1;
 
865
        gint                           job_impressions_completed = -1;
 
866
        gint                           notify_sequence_number = -1;
 
867
        gint                           i;
 
868
 
 
869
        request = ippNewRequest (IPP_GET_NOTIFICATIONS);
 
870
 
 
871
        ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME,
 
872
                      "requesting-user-name", NULL, cupsUser ());
 
873
 
 
874
        ippAddInteger (request, IPP_TAG_OPERATION, IPP_TAG_INTEGER,
 
875
                       "notify-subscription-ids", manager->priv->subscription_id);
 
876
 
 
877
        ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
 
878
                      "/printers/");
 
879
 
 
880
        ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL,
 
881
                      "/jobs/");
 
882
 
 
883
        ippAddInteger (request, IPP_TAG_OPERATION, IPP_TAG_INTEGER,
 
884
                       "notify-sequence-numbers",
 
885
                       manager->priv->last_notify_sequence_number + 1);
 
886
 
 
887
 
 
888
        response = cupsDoRequest (CUPS_HTTP_DEFAULT, request, "/");
 
889
 
 
890
 
 
891
        for (attr = ippFindAttribute (response, "notify-sequence-number", IPP_TAG_INTEGER);
 
892
             attr != NULL;
 
893
             attr = ippNextAttribute (response)) {
 
894
 
 
895
                attr_name = ippGetName (attr);
 
896
                if (g_strcmp0 (attr_name, "notify-sequence-number") == 0) {
 
897
                        notify_sequence_number = ippGetInteger (attr, 0);
 
898
 
 
899
                        if (notify_sequence_number > manager->priv->last_notify_sequence_number)
 
900
                                manager->priv->last_notify_sequence_number = notify_sequence_number;
 
901
 
 
902
                        if (notify_subscribed_event != NULL) {
 
903
                                process_cups_notification (manager,
 
904
                                                           notify_subscribed_event,
 
905
                                                           notify_text,
 
906
                                                           notify_printer_uri,
 
907
                                                           printer_name,
 
908
                                                           printer_state,
 
909
                                                           printer_state_reasons,
 
910
                                                           printer_is_accepting_jobs,
 
911
                                                           notify_job_id,
 
912
                                                           job_state,
 
913
                                                           job_state_reasons,
 
914
                                                           job_name,
 
915
                                                           job_impressions_completed);
 
916
 
 
917
                                g_clear_pointer (&printer_state_reasons, g_free);
 
918
                                g_clear_pointer (&job_state_reasons, g_free);
 
919
                        }
 
920
 
 
921
                        notify_subscribed_event = NULL;
 
922
                        notify_text = NULL;
 
923
                        notify_printer_uri = NULL;
 
924
                        printer_name = NULL;
 
925
                        printer_state = -1;
 
926
                        printer_state_reasons = NULL;
 
927
                        printer_is_accepting_jobs = FALSE;
 
928
                        notify_job_id = 0;
 
929
                        job_state = -1;
 
930
                        job_state_reasons = NULL;
 
931
                        job_name = NULL;
 
932
                        job_impressions_completed = -1;
 
933
                } else if (g_strcmp0 (attr_name, "notify-subscribed-event") == 0) {
 
934
                        notify_subscribed_event = ippGetString (attr, 0, NULL);
 
935
                } else if (g_strcmp0 (attr_name, "notify-text") == 0) {
 
936
                        notify_text = ippGetString (attr, 0, NULL);
 
937
                } else if (g_strcmp0 (attr_name, "notify-printer-uri") == 0) {
 
938
                        notify_printer_uri = ippGetString (attr, 0, NULL);
 
939
                } else if (g_strcmp0 (attr_name, "printer-name") == 0) {
 
940
                        printer_name = ippGetString (attr, 0, NULL);
 
941
                } else if (g_strcmp0 (attr_name, "printer-state") == 0) {
 
942
                        printer_state = ippGetInteger (attr, 0);
 
943
                } else if (g_strcmp0 (attr_name, "printer-state-reasons") == 0) {
 
944
                        reasons = g_new0 (gchar *, ippGetCount (attr) + 1);
 
945
                        for (i = 0; i < ippGetCount (attr); i++)
 
946
                                reasons[i] = g_strdup (ippGetString (attr, i, NULL));
 
947
                        printer_state_reasons = g_strjoinv (",", reasons);
 
948
                        g_strfreev (reasons);
 
949
                } else if (g_strcmp0 (attr_name, "printer-is-accepting-jobs") == 0) {
 
950
                        printer_is_accepting_jobs = ippGetBoolean (attr, 0);
 
951
                } else if (g_strcmp0 (attr_name, "notify-job-id") == 0) {
 
952
                        notify_job_id = ippGetInteger (attr, 0);
 
953
                } else if (g_strcmp0 (attr_name, "job-state") == 0) {
 
954
                        job_state = ippGetInteger (attr, 0);
 
955
                } else if (g_strcmp0 (attr_name, "job-state-reasons") == 0) {
 
956
                        reasons = g_new0 (gchar *, ippGetCount (attr) + 1);
 
957
                        for (i = 0; i < ippGetCount (attr); i++)
 
958
                                reasons[i] = g_strdup (ippGetString (attr, i, NULL));
 
959
                        job_state_reasons = g_strjoinv (",", reasons);
 
960
                        g_strfreev (reasons);
 
961
                } else if (g_strcmp0 (attr_name, "job-name") == 0) {
 
962
                        job_name = ippGetString (attr, 0, NULL);
 
963
                } else if (g_strcmp0 (attr_name, "job-impressions-completed") == 0) {
 
964
                        job_impressions_completed = ippGetInteger (attr, 0);
 
965
                }
 
966
        }
 
967
 
 
968
        if (notify_subscribed_event != NULL) {
 
969
                process_cups_notification (manager,
 
970
                                           notify_subscribed_event,
 
971
                                           notify_text,
 
972
                                           notify_printer_uri,
 
973
                                           printer_name,
 
974
                                           printer_state,
 
975
                                           printer_state_reasons,
 
976
                                           printer_is_accepting_jobs,
 
977
                                           notify_job_id,
 
978
                                           job_state,
 
979
                                           job_state_reasons,
 
980
                                           job_name,
 
981
                                           job_impressions_completed);
 
982
 
 
983
                g_clear_pointer (&printer_state_reasons, g_free);
 
984
                g_clear_pointer (&job_state_reasons, g_free);
 
985
        }
 
986
 
 
987
        if (response != NULL)
 
988
                ippDelete (response);
 
989
 
 
990
        return TRUE;
 
991
}
 
992
 
814
993
static void
815
994
scp_handler (GsdPrintNotificationsManager *manager,
816
995
             gboolean                      start)
836
1015
                                   error->message);
837
1016
                        g_error_free (error);
838
1017
                }
839
 
        }
840
 
        else if (manager->priv->scp_handler_spawned) {
 
1018
        } else if (manager->priv->scp_handler_spawned) {
841
1019
                kill (manager->priv->scp_handler_pid, SIGHUP);
842
1020
                g_spawn_close_pid (manager->priv->scp_handler_pid);
843
1021
                manager->priv->scp_handler_spawned = FALSE;
885
1063
        if ((http = httpConnectEncrypt (cupsServer (), ippPort (),
886
1064
                                        cupsEncryption ())) == NULL) {
887
1065
                g_debug ("Connection to CUPS server \'%s\' failed.", cupsServer ());
888
 
        }
889
 
        else {
 
1066
        } else {
890
1067
                if (manager->priv->subscription_id >= 0) {
891
1068
                        request = ippNewRequest (IPP_RENEW_SUBSCRIPTION);
892
1069
                        ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
898
1075
                        ippAddInteger (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
899
1076
                                      "notify-lease-duration", SUBSCRIPTION_DURATION);
900
1077
                        ippDelete (cupsDoRequest (http, request, "/"));
901
 
                }
902
 
                else {
 
1078
                } else {
903
1079
                        request = ippNewRequest (IPP_CREATE_PRINTER_SUBSCRIPTION);
904
1080
                        ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
905
1081
                                      "printer-uri", NULL,
910
1086
                                       "notify-events", num_events, NULL, events);
911
1087
                        ippAddString (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD,
912
1088
                                      "notify-pull-method", NULL, "ippget");
913
 
                        ippAddString (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI,
914
 
                                      "notify-recipient-uri", NULL, "dbus://");
 
1089
                        if (server_is_local (cupsServer ())) {
 
1090
                                ippAddString (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI,
 
1091
                                              "notify-recipient-uri", NULL, "dbus://");
 
1092
                        }
915
1093
                        ippAddInteger (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
916
1094
                                       "notify-lease-duration", SUBSCRIPTION_DURATION);
917
1095
                        response = cupsDoRequest (http, request, "/");
951
1129
                g_object_unref (connection);
952
1130
 
953
1131
                renew_subscription (user_data);
954
 
        }
955
 
        else {
 
1132
        } else {
956
1133
                g_debug ("Test connection to CUPS server \'%s:%d\' failed.", cupsServer (), ippPort ());
957
1134
        }
958
1135
}
962
1139
{
963
1140
        GSocketClient *client;
964
1141
        gchar         *address;
965
 
 
966
 
        address = g_strdup_printf ("%s:%d", cupsServer (), ippPort ());
 
1142
        int            port;
 
1143
 
 
1144
        port = ippPort ();
 
1145
 
 
1146
        address = g_strdup_printf ("%s:%d", cupsServer (), port);
967
1147
 
968
1148
        if (address && address[0] != '/') {
969
1149
                client = g_socket_client_new ();
970
1150
 
971
 
                g_debug ("Initiating test connection to CUPS server \'%s:%d\'.", cupsServer (), ippPort ());
 
1151
                g_debug ("Initiating test connection to CUPS server \'%s:%d\'.", cupsServer (), port);
972
1152
 
973
1153
                g_socket_client_connect_to_host_async (client,
974
1154
                                                       address,
975
 
                                                       631,
 
1155
                                                       port,
976
1156
                                                       NULL,
977
1157
                                                       renew_subscription_with_connection_test_cb,
978
1158
                                                       user_data);
979
1159
 
980
1160
                g_object_unref (client);
981
 
        }
982
 
        else {
 
1161
        } else {
983
1162
                renew_subscription (user_data);
984
1163
        }
985
1164
 
989
1168
}
990
1169
 
991
1170
static void
 
1171
renew_subscription_timeout_enable (GsdPrintNotificationsManager *manager,
 
1172
                                   gboolean                      enable,
 
1173
                                   gboolean                      with_connection_test)
 
1174
{
 
1175
        if (manager->priv->renew_source_id > 0)
 
1176
                g_source_remove (manager->priv->renew_source_id);
 
1177
 
 
1178
        if (enable) {
 
1179
                renew_subscription (manager);
 
1180
                if (with_connection_test)
 
1181
                        manager->priv->renew_source_id =
 
1182
                                g_timeout_add_seconds (RENEW_INTERVAL,
 
1183
                                                       renew_subscription_with_connection_test,
 
1184
                                                       manager);
 
1185
                else
 
1186
                        manager->priv->renew_source_id =
 
1187
                                g_timeout_add_seconds (RENEW_INTERVAL,
 
1188
                                                       renew_subscription,
 
1189
                                                       manager);
 
1190
        } else {
 
1191
                manager->priv->renew_source_id = 0;
 
1192
        }
 
1193
}
 
1194
 
 
1195
static void
992
1196
cups_connection_test_cb (GObject      *source_object,
993
1197
                         GAsyncResult *res,
994
1198
                         gpointer      user_data)
1008
1212
                g_object_unref (connection);
1009
1213
 
1010
1214
                manager->priv->num_dests = cupsGetDests (&manager->priv->dests);
1011
 
                gnome_settings_profile_msg ("got dests");
 
1215
                g_debug ("Got dests from remote CUPS server.");
1012
1216
 
1013
 
                renew_subscription (user_data);
1014
 
                g_timeout_add_seconds (RENEW_INTERVAL, renew_subscription_with_connection_test, manager);
1015
 
        }
1016
 
        else {
 
1217
                renew_subscription_timeout_enable (manager, TRUE, TRUE);
 
1218
                manager->priv->check_source_id = g_timeout_add_seconds (CHECK_INTERVAL, process_new_notifications, manager);
 
1219
        } else {
1017
1220
                g_debug ("Test connection to CUPS server \'%s:%d\' failed.", cupsServer (), ippPort ());
1018
1221
                if (manager->priv->cups_connection_timeout_id == 0)
1019
1222
                        manager->priv->cups_connection_timeout_id =
1027
1230
        GsdPrintNotificationsManager *manager = (GsdPrintNotificationsManager *) user_data;
1028
1231
        GSocketClient                *client;
1029
1232
        gchar                        *address;
 
1233
        int                           port = ippPort ();
1030
1234
 
1031
1235
        if (!manager->priv->dests) {
1032
 
                address = g_strdup_printf ("%s:%d", cupsServer (), ippPort ());
1033
 
 
1034
 
                if (address && address[0] != '/') {
1035
 
                        client = g_socket_client_new ();
1036
 
 
1037
 
                        g_debug ("Initiating test connection to CUPS server \'%s:%d\'.", cupsServer (), ippPort ());
1038
 
 
1039
 
                        g_socket_client_connect_to_host_async (client,
1040
 
                                                               address,
1041
 
                                                               631,
1042
 
                                                               NULL,
1043
 
                                                               cups_connection_test_cb,
1044
 
                                                               manager);
1045
 
 
1046
 
                        g_object_unref (client);
1047
 
                }
1048
 
                else {
1049
 
                        manager->priv->num_dests = cupsGetDests (&manager->priv->dests);
1050
 
                        gnome_settings_profile_msg ("got dests");
1051
 
 
1052
 
                        renew_subscription (user_data);
1053
 
                        g_timeout_add_seconds (RENEW_INTERVAL, renew_subscription_with_connection_test, manager);
1054
 
                }
1055
 
 
 
1236
                address = g_strdup_printf ("%s:%d", cupsServer (), port);
 
1237
 
 
1238
                client = g_socket_client_new ();
 
1239
 
 
1240
                g_debug ("Initiating test connection to CUPS server \'%s:%d\'.", cupsServer (), port);
 
1241
 
 
1242
                g_socket_client_connect_to_host_async (client,
 
1243
                                                       address,
 
1244
                                                       port,
 
1245
                                                       NULL,
 
1246
                                                       cups_connection_test_cb,
 
1247
                                                       manager);
 
1248
 
 
1249
                g_object_unref (client);
1056
1250
                g_free (address);
1057
1251
        }
1058
1252
 
1060
1254
                manager->priv->cups_connection_timeout_id = 0;
1061
1255
 
1062
1256
                return FALSE;
1063
 
        }
1064
 
        else {
 
1257
        } else {
1065
1258
                return TRUE;
1066
1259
        }
1067
1260
}
1068
1261
 
 
1262
static void
 
1263
gsd_print_notifications_manager_got_dbus_connection (GObject      *source_object,
 
1264
                                                     GAsyncResult *res,
 
1265
                                                     gpointer      user_data)
 
1266
{
 
1267
        GsdPrintNotificationsManager *manager = (GsdPrintNotificationsManager *) user_data;
 
1268
        GError                       *error = NULL;
 
1269
 
 
1270
        manager->priv->cups_bus_connection = g_bus_get_finish (res, &error);
 
1271
 
 
1272
        if (manager->priv->cups_bus_connection != NULL) {
 
1273
                manager->priv->cups_dbus_subscription_id =
 
1274
                        g_dbus_connection_signal_subscribe (manager->priv->cups_bus_connection,
 
1275
                                                            NULL,
 
1276
                                                            CUPS_DBUS_INTERFACE,
 
1277
                                                            NULL,
 
1278
                                                            CUPS_DBUS_PATH,
 
1279
                                                            NULL,
 
1280
                                                            0,
 
1281
                                                            on_cups_notification,
 
1282
                                                            manager,
 
1283
                                                            NULL);
 
1284
        } else {
 
1285
                g_warning ("Connection to message bus failed: %s", error->message);
 
1286
                g_error_free (error);
 
1287
        }
 
1288
}
 
1289
 
1069
1290
static gboolean
1070
1291
gsd_print_notifications_manager_start_idle (gpointer data)
1071
1292
{
1075
1296
 
1076
1297
        manager->priv->printing_printers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
1077
1298
 
1078
 
        cups_connection_test (manager);
1079
 
 
1080
 
        manager->priv->cups_bus_connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL);
1081
 
 
1082
 
        g_dbus_connection_signal_subscribe (manager->priv->cups_bus_connection,
1083
 
                                            NULL,
1084
 
                                            CUPS_DBUS_INTERFACE,
1085
 
                                            NULL,
1086
 
                                            CUPS_DBUS_PATH,
1087
 
                                            NULL,
1088
 
                                            0,
1089
 
                                            on_cups_notification,
1090
 
                                            manager,
1091
 
                                            NULL);
 
1299
 
 
1300
        if (server_is_local (cupsServer ())) {
 
1301
                manager->priv->num_dests = cupsGetDests (&manager->priv->dests);
 
1302
                g_debug ("Got dests from local CUPS server.");
 
1303
 
 
1304
                renew_subscription_timeout_enable (manager, TRUE, FALSE);
 
1305
 
 
1306
                g_bus_get (G_BUS_TYPE_SYSTEM,
 
1307
                           NULL,
 
1308
                           gsd_print_notifications_manager_got_dbus_connection,
 
1309
                           data);
 
1310
        } else {
 
1311
                cups_connection_test (manager);
 
1312
        }
1092
1313
 
1093
1314
        scp_handler (manager, TRUE);
1094
1315
 
1114
1335
        manager->priv->active_notifications = NULL;
1115
1336
        manager->priv->cups_bus_connection = NULL;
1116
1337
        manager->priv->cups_connection_timeout_id = 0;
 
1338
        manager->priv->last_notify_sequence_number = -1;
1117
1339
 
1118
1340
        g_idle_add (gsd_print_notifications_manager_start_idle, manager);
1119
1341
 
1135
1357
        manager->priv->num_dests = 0;
1136
1358
        manager->priv->dests = NULL;
1137
1359
 
 
1360
        if (manager->priv->cups_dbus_subscription_id > 0 &&
 
1361
            manager->priv->cups_bus_connection != NULL) {
 
1362
                g_dbus_connection_signal_unsubscribe (manager->priv->cups_bus_connection,
 
1363
                                                      manager->priv->cups_dbus_subscription_id);
 
1364
                manager->priv->cups_dbus_subscription_id = 0;
 
1365
        }
 
1366
 
 
1367
        renew_subscription_timeout_enable (manager, FALSE, FALSE);
 
1368
 
 
1369
        if (manager->priv->check_source_id > 0) {
 
1370
                g_source_remove (manager->priv->check_source_id);
 
1371
                manager->priv->check_source_id = 0;
 
1372
        }
 
1373
 
1138
1374
        if (manager->priv->subscription_id >= 0)
1139
1375
                cancel_subscription (manager->priv->subscription_id);
1140
1376