232
* Find out type of the given printer driver.
233
* (see xml/preferreddrivers.xml from system-config-printer)
236
get_driver_type (gchar *ppd_name,
237
gchar *ppd_device_id,
238
gchar *ppd_make_and_model,
244
if (match_level == PPD_GENERIC_MATCH)
246
if (ppd_name && g_regex_match_simple ("(foomatic(-db-compressed-ppds)?|ijsgutenprint.*):", ppd_name, 0, 0))
248
tmp = get_tag_value ("DRV", ppd_device_id);
249
if (tmp && g_regex_match_simple (".*,?R1", tmp, 0, 0))
250
return g_strdup ("generic-foomatic-recommended");
254
if (match_level == PPD_GENERIC_MATCH || match_level == PPD_NO_MATCH)
256
if (ppd_name && g_regex_match_simple ("(foomatic(-db-compressed-ppds)?|ijsgutenprint.*):Generic-ESC_P", ppd_name, 0, 0))
257
return g_strdup ("generic-escp");
259
if (ppd_name && g_regex_match_simple ("drv:///sample.drv/epson(9|24).ppd", ppd_name, 0, 0))
260
return g_strdup ("generic-escp");
262
if (g_strcmp0 (ppd_make_and_model, "Generic PostScript Printer") == 0)
263
return g_strdup ("generic-postscript");
265
if (g_strcmp0 (ppd_make_and_model, "Generic PCL 6 Printer") == 0)
266
return g_strdup ("generic-pcl6");
268
if (g_strcmp0 (ppd_make_and_model, "Generic PCL 5e Printer") == 0)
269
return g_strdup ("generic-pcl5e");
271
if (g_strcmp0 (ppd_make_and_model, "Generic PCL 5 Printer") == 0)
272
return g_strdup ("generic-pcl5");
274
if (g_strcmp0 (ppd_make_and_model, "Generic PCL Laser Printer") == 0)
275
return g_strdup ("generic-pcl");
277
return g_strdup ("generic");
281
if (ppd_name && g_regex_match_simple ("drv:///sample.drv/", ppd_name, 0, 0))
282
return g_strdup ("cups");
284
if (ppd_product && g_regex_match_simple (".*Ghostscript", ppd_product, 0, 0))
285
return g_strdup ("ghostscript");
287
if (ppd_name && g_regex_match_simple ("gutenprint.*:.*/simple|.*-gutenprint.*\\.sim", ppd_name, 0, 0))
288
return g_strdup ("gutenprint-simplified");
290
if (ppd_name && g_regex_match_simple ("gutenprint.*:|.*-gutenprint", ppd_name, 0, 0))
291
return g_strdup ("gutenprint-expert");
293
if (ppd_make_and_model && g_regex_match_simple (".* Foomatic/hpijs", ppd_make_and_model, 0, 0))
295
tmp = get_tag_value ("DRV", ppd_device_id);
296
if (tmp && g_regex_match_simple (",?R1", tmp, 0, 0))
297
return g_strdup ("foomatic-recommended-hpijs");
300
if (ppd_make_and_model && g_regex_match_simple (".* Foomatic/hpijs", ppd_make_and_model, 0, 0))
301
return g_strdup ("foomatic-hpijs");
303
if (ppd_name && g_regex_match_simple ("foomatic(-db-compressed-ppds)?:", ppd_name, 0, 0) &&
304
ppd_make_and_model && g_regex_match_simple (".* Postscript", ppd_make_and_model, 0, 0))
306
tmp = get_tag_value ("DRV", ppd_device_id);
307
if (tmp && g_regex_match_simple (".*,?R1", tmp, 0, 0))
308
return g_strdup ("foomatic-recommended-postscript");
311
if (ppd_name && g_regex_match_simple ("foomatic(-db-compressed-ppds)?:.*-Postscript", ppd_name, 0, 0))
312
return g_strdup ("foomatic-postscript");
314
if (ppd_make_and_model && g_regex_match_simple (".* Foomatic/pxlmono", ppd_make_and_model, 0, 0))
315
return g_strdup ("foomatic-pxlmono");
317
if (ppd_name && g_regex_match_simple ("(foomatic(-db-compressed-ppds)?|ijsgutenprint.*):", ppd_name, 0, 0))
319
tmp = get_tag_value ("DRV", ppd_device_id);
320
if (tmp && g_regex_match_simple (".*,?R1", tmp, 0, 0))
321
return g_strdup ("foomatic-recommended-non-postscript");
324
if (ppd_name && g_regex_match_simple ("(foomatic(-db-compressed-ppds)?|ijsgutenprint.*):.*-gutenprint", ppd_name, 0, 0))
325
return g_strdup ("foomatic-gutenprint");
327
if (ppd_name && g_regex_match_simple ("(foomatic(-db-compressed-ppds)?|ijsgutenprint.*):", ppd_name, 0, 0))
328
return g_strdup ("foomatic");
330
if (ppd_name && g_regex_match_simple ("drv:///(hp/)?hpcups.drv/|.*-hpcups", ppd_name, 0, 0) &&
331
ppd_make_and_model && g_regex_match_simple (".* plugin", ppd_make_and_model, 0, 0))
332
return g_strdup ("hpcups-plugin");
334
if (ppd_name && g_regex_match_simple ("drv:///(hp/)?hpcups.drv/|.*-hpcups", ppd_name, 0, 0))
335
return g_strdup ("hpcups");
337
if (ppd_name && g_regex_match_simple ("drv:///(hp/)?hpijs.drv/|.*-hpijs", ppd_name, 0, 0) &&
338
ppd_make_and_model && g_regex_match_simple (".* plugin", ppd_make_and_model, 0, 0))
339
return g_strdup ("hpijs-plugin");
341
if (ppd_name && g_regex_match_simple ("drv:///(hp/)?hpijs.drv/|.*-hpijs", ppd_name, 0, 0))
342
return g_strdup ("hpijs");
344
if (ppd_name && g_regex_match_simple (".*splix", ppd_name, 0, 0))
345
return g_strdup ("splix");
347
if (ppd_name && g_regex_match_simple (".*turboprint", ppd_name, 0, 0))
348
return g_strdup ("turboprint");
350
if (ppd_name && g_regex_match_simple (".*/(Ricoh|Lanier|Gestetner|InfoPrint|Infotech|Savin|NRG)/PS/", ppd_name, 0, 0))
351
return g_strdup ("manufacturer-ricoh-postscript");
353
if (ppd_name && g_regex_match_simple (".*/(Ricoh|Lanier|Gestetner|InfoPrint|Infotech|Savin|NRG)/PXL/", ppd_name, 0, 0))
354
return g_strdup ("manufacturer-ricoh-pxl");
356
if (match_level == PPD_EXACT_CMD_MATCH)
357
return g_strdup ("manufacturer-cmd");
359
return g_strdup ("manufacturer");
364
* Return preference value. The most preferred driver has the lowest value.
365
* If the value is higher or equal to 1000 then try to avoid installation
366
* of this driver. If it is higher or equal to 2000 then don't install
368
* (see xml/preferreddrivers.xml from system-config-printer)
371
get_driver_preference (PPDItem *item)
377
if (item && item->ppd_make_and_model &&
378
g_regex_match_simple ("Brother HL-2030", item->ppd_make_and_model, 0, 0))
380
tmp1 = get_tag_value ("MFG", item->ppd_device_id);
381
tmp2 = get_tag_value ("MDL", item->ppd_device_id);
383
if (tmp1 && g_regex_match_simple ("Brother", tmp1, 0, 0) &&
384
tmp2 && g_regex_match_simple ("HL-2030", tmp2, 0, 0))
386
if (item->driver_type && g_regex_match_simple ("gutenprint*", item->driver_type, 0, 0))
387
return result + 2000;
394
if (item && item->ppd_make_and_model &&
395
g_regex_match_simple ("(Ricoh|Lanier|Gestetner|InfoPrint|Infotech|Savin|NRG) ", item->ppd_make_and_model, 0, 0))
397
tmp1 = get_tag_value ("MFG", item->ppd_device_id);
399
if (tmp1 && g_regex_match_simple ("(Ricoh|Lanier|Gestetner|InfoPrint|Infotech|Savin|NRG)", tmp1, 0, 0) &&
400
((g_strcmp0 (item->driver_type, "manufacturer-ricoh-postscript") == 0) ||
401
(g_strcmp0 (item->driver_type, "manufacturer-ricoh-pxl") == 0)))
406
if (item && item->ppd_make_and_model &&
407
g_regex_match_simple ("Xerox 6250DP", item->ppd_make_and_model, 0, 0))
409
tmp1 = get_tag_value ("MFG", item->ppd_device_id);
410
tmp2 = get_tag_value ("MDL", item->ppd_device_id);
412
if (tmp1 && g_regex_match_simple ("Xerox", tmp1, 0, 0) &&
413
tmp2 && g_regex_match_simple ("6250DP", tmp2, 0, 0))
415
if (item->driver_type && g_regex_match_simple ("gutenprint*", item->driver_type, 0, 0))
416
return result + 1000;
423
if (item && g_strcmp0 (item->driver_type, "manufacturer-cmd") == 0)
427
if (item && g_strcmp0 (item->driver_type, "foomatic-recommended-hpijs") == 0)
431
if (item && g_strcmp0 (item->driver_type, "foomatic-recommended-non-postscript") == 0)
435
if (item && item->driver_type &&
436
g_regex_match_simple ("manufacturer*", item->driver_type, 0, 0))
440
if (item && g_strcmp0 (item->driver_type, "foomatic-recommended-postscript") == 0)
444
if (item && g_strcmp0 (item->driver_type, "foomatic-postscript") == 0)
448
if (item && g_strcmp0 (item->driver_type, "hpcups") == 0)
452
if (item && g_strcmp0 (item->driver_type, "hpijs") == 0)
456
if (item && item->ppd_make_and_model &&
457
g_regex_match_simple ("(HP|Hewlett-Packard) ", item->ppd_make_and_model, 0, 0))
459
tmp1 = get_tag_value ("MFG", item->ppd_device_id);
461
if (tmp1 && g_regex_match_simple ("HP|Hewlett-Packard", tmp1, 0, 0) &&
462
g_strcmp0 (item->driver_type, "foomatic-hpijs") == 0)
467
if (item && g_strcmp0 (item->driver_type, "gutenprint-simplified") == 0)
471
if (item && g_strcmp0 (item->driver_type, "gutenprint-expert") == 0)
475
if (item && g_strcmp0 (item->driver_type, "foomatic-hpijs") == 0)
479
if (item && g_strcmp0 (item->driver_type, "foomatic-gutenprint") == 0)
483
if (item && g_strcmp0 (item->driver_type, "foomatic") == 0)
487
if (item && g_strcmp0 (item->driver_type, "cups") == 0)
491
if (item && g_strcmp0 (item->driver_type, "generic-postscript") == 0)
495
if (item && g_strcmp0 (item->driver_type, "generic-foomatic-recommended") == 0)
499
if (item && g_strcmp0 (item->driver_type, "generic-pcl6") == 0)
503
if (item && g_strcmp0 (item->driver_type, "generic-pcl5c") == 0)
507
if (item && g_strcmp0 (item->driver_type, "generic-pcl5e") == 0)
511
if (item && g_strcmp0 (item->driver_type, "generic-pcl5") == 0)
515
if (item && g_strcmp0 (item->driver_type, "generic-pcl") == 0)
519
if (item && g_strcmp0 (item->driver_type, "foomatic-pxlmono") == 0)
523
if (item && g_strcmp0 (item->driver_type, "generic-escp") == 0)
527
if (item && g_strcmp0 (item->driver_type, "ghostscript") == 0)
531
if (item && g_strcmp0 (item->driver_type, "generic") == 0)
535
if (item && g_strcmp0 (item->driver_type, "hpcups-plugin") == 0)
539
if (item && g_strcmp0 (item->driver_type, "hpijs-plugin") == 0)
543
if (item && g_strcmp0 (item->driver_type, "splix") == 0)
547
if (item && g_strcmp0 (item->driver_type, "turboprint") == 0)
556
* Compare driver types according to preference order.
557
* The most preferred driver is the lowest one.
558
* (see xml/preferreddrivers.xml from system-config-printer)
561
preference_value_cmp (gconstpointer a,
564
PPDItem *c = (PPDItem *) a;
565
PPDItem *d = (PPDItem *) b;
567
if (c == NULL && d == NULL)
574
if (c->preference_value < d->preference_value)
576
else if (c->preference_value > d->preference_value)
583
/* Compare PPDItems a and b according to normalized model name */
585
item_cmp (gconstpointer a,
588
PPDItem *c = (PPDItem *) a;
589
PPDItem *d = (PPDItem *) b;
592
gchar *a_normalized = NULL;
593
gchar *b_normalized = NULL;
604
a_normalized = normalize (c->mdl);
605
b_normalized = normalize (d->mdl);
608
av = g_strsplit (a_normalized, " ", 0);
611
bv = g_strsplit (b_normalized, " ", 0);
614
a_length = g_strv_length (av);
617
b_length = g_strv_length (bv);
619
min_length = a_length < b_length ? a_length : b_length;
621
for (i = 0; i < min_length; i++)
623
if (g_ascii_isdigit (av[i][0]) && g_ascii_isdigit (bv[i][0]))
625
a_number = atol (av[i]);
626
b_number = atol (bv[i]);
627
if (a_number < b_number)
632
else if (a_number > b_number)
638
else if (g_ascii_isdigit (av[i][0]) && !g_ascii_isdigit (bv[i][0]))
643
else if (!g_ascii_isdigit (av[i][0]) && g_ascii_isdigit (bv[i][0]))
650
if (g_strcmp0 (av[i], bv[i]) != 0)
652
result = g_strcmp0 (av[i], bv[i]);
658
if (a_length < b_length)
660
else if (a_length > b_length)
671
g_free (a_normalized);
672
g_free (b_normalized);
679
get_prefix_length (gchar *a, gchar *b)
688
a_length = strlen (a);
689
b_length = strlen (b);
690
min_length = a_length < b_length ? a_length : b_length;
692
for (i = 0; i < min_length; i++)
705
* Append best matching ppds from list "ppds" to list "list"
706
* according to model name "model". Return the resulting list.
709
append_best_ppds (GList *list,
715
PPDItem *best_item = NULL;
716
gchar *mdl_normalized;
721
GList *candidates = NULL;
722
GList *tmp_list = NULL;
723
GList *result = NULL;
724
gint best_prefix_length = -1;
731
mdl = g_ascii_strdown (model, -1);
732
if (g_str_has_suffix (mdl, " series"))
734
tmp = g_strndup (mdl, strlen (mdl) - 7);
739
mdl_normalized = normalize (mdl);
741
item = g_new0 (PPDItem, 1);
742
item->ppd_device_id = g_strdup_printf ("mdl:%s;", mdl);
743
item->mdl = mdl_normalized;
745
local_ppds = g_list_copy (ppds);
746
local_ppds = g_list_append (local_ppds, item);
747
local_ppds = g_list_sort (local_ppds, item_cmp);
749
actual_item = g_list_find (local_ppds, item);
752
if (actual_item->prev)
753
candidates = g_list_append (candidates, actual_item->prev->data);
754
if (actual_item->next)
755
candidates = g_list_append (candidates, actual_item->next->data);
758
for (tmp_list = candidates; tmp_list; tmp_list = tmp_list->next)
760
tmp_item = (PPDItem *) tmp_list->data;
762
prefix_length = get_prefix_length (tmp_item->mdl, mdl_normalized);
763
if (prefix_length > best_prefix_length)
765
best_prefix_length = prefix_length;
766
best_item = tmp_item;
770
if (best_item && best_prefix_length > strlen (mdl_normalized) / 2)
772
if (best_prefix_length == strlen (mdl_normalized))
773
best_item->match_level = PPD_EXACT_MATCH;
775
best_item->match_level = PPD_CLOSE_MATCH;
777
result = g_list_append (result, ppd_item_copy (best_item));
781
/* TODO the last resort (see _findBestMatchPPDs() in ppds.py) */
784
g_list_free (candidates);
785
g_list_free (local_ppds);
787
g_free (item->ppd_device_id);
790
g_free (mdl_normalized);
797
* Return the best matching driver name
798
* for device described by given parameters.
801
get_ppd_name (gchar *device_id,
802
gchar *device_make_and_model,
805
GDBusConnection *bus;
809
PPDName *result = NULL;
810
GError *error = NULL;
813
static const char * const match_levels[] = {
820
bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
823
output = g_dbus_connection_call_sync (bus,
828
g_variant_new ("(sss)",
829
device_id ? device_id : "",
830
device_make_and_model ? device_make_and_model : "",
831
device_uri ? device_uri : ""),
833
G_DBUS_CALL_FLAGS_NONE,
838
if (output && g_variant_n_children (output) >= 1)
840
array = g_variant_get_child_value (output, 0);
842
for (j = 0; j < G_N_ELEMENTS (match_levels) && result == NULL; j++)
843
for (i = 0; i < g_variant_n_children (array) && result == NULL; i++)
845
tuple = g_variant_get_child_value (array, i);
846
if (tuple && g_variant_n_children (tuple) == 2)
848
name = g_strdup (g_variant_get_string (
849
g_variant_get_child_value (tuple, 0),
851
match = g_strdup (g_variant_get_string (
852
g_variant_get_child_value (tuple, 1),
855
if (g_strcmp0 (match, match_levels[j]) == 0)
857
result = g_new0 (PPDName, 1);
858
result->ppd_name = g_strdup (name);
860
if (g_strcmp0 (match, "exact-cmd") == 0)
861
result->ppd_match_level = PPD_EXACT_CMD_MATCH;
862
else if (g_strcmp0 (match, "exact") == 0)
863
result->ppd_match_level = PPD_EXACT_MATCH;
864
else if (g_strcmp0 (match, "close") == 0)
865
result->ppd_match_level = PPD_CLOSE_MATCH;
866
else if (g_strcmp0 (match, "generic") == 0)
867
result->ppd_match_level = PPD_GENERIC_MATCH;
868
else if (g_strcmp0 (match, "none") == 0)
869
result->ppd_match_level = PPD_NO_MATCH;
879
g_variant_unref (output);
880
g_object_unref (bus);
885
error->domain == G_DBUS_ERROR &&
886
(error->code == G_DBUS_ERROR_SERVICE_UNKNOWN ||
887
error->code == G_DBUS_ERROR_UNKNOWN_METHOD)))
889
ipp_attribute_t *attr = NULL;
890
const gchar *hp_equivalents[] = {"hp", "hewlett packard", NULL};
891
const gchar *kyocera_equivalents[] = {"kyocera", "kyocera mita", NULL};
892
const gchar *toshiba_equivalents[] = {"toshiba", "toshiba tec corp.", NULL};
893
const gchar *lexmark_equivalents[] = {"lexmark", "lexmark international", NULL};
894
gboolean ppd_exact_match_found = FALSE;
897
ipp_t *request = NULL;
898
ipp_t *response = NULL;
903
gchar *mfg_normalized = NULL;
904
gchar *mdl_normalized = NULL;
905
gchar *eq_normalized = NULL;
909
gchar *ppd_device_id;
910
gchar *ppd_make_and_model;
913
gchar **equivalents = NULL;
916
g_warning ("You should install system-config-printer which provides \
917
DBus method \"GetBestDrivers\". Using fallback solution for now.");
918
g_error_free (error);
920
mfg = get_tag_value (device_id, "mfg");
922
mfg = get_tag_value (device_id, "manufacturer");
924
mdl = get_tag_value (device_id, "mdl");
926
mdl = get_tag_value (device_id, "model");
928
mfg_normalized = normalize (mfg);
929
mdl_normalized = normalize (mdl);
931
if (mfg_normalized && mfg)
933
if (g_str_has_prefix (mfg_normalized, "hewlett") ||
934
g_str_has_prefix (mfg_normalized, "hp"))
935
equivalents = strvdup (hp_equivalents);
937
if (g_str_has_prefix (mfg_normalized, "kyocera"))
938
equivalents = strvdup (kyocera_equivalents);
940
if (g_str_has_prefix (mfg_normalized, "toshiba"))
941
equivalents = strvdup (toshiba_equivalents);
943
if (g_str_has_prefix (mfg_normalized, "lexmark"))
944
equivalents = strvdup (lexmark_equivalents);
946
if (equivalents == NULL)
948
equivalents = g_new0 (gchar *, 2);
949
equivalents[0] = g_strdup (mfg);
953
http = httpConnectEncrypt (cupsServer (),
957
/* Find usable drivers for given device */
960
/* Try exact match according to device-id */
963
request = ippNewRequest (CUPS_GET_PPDS);
964
ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_TEXT,
965
"ppd-device-id", NULL, device_id);
966
response = cupsDoRequest (http, request, "/");
969
ippGetStatusCode (response) <= IPP_OK_CONFLICT)
971
for (attr = ippFirstAttribute (response); attr != NULL; attr = ippNextAttribute (response))
973
while (attr != NULL && ippGetGroupTag (attr) != IPP_TAG_PRINTER)
974
attr = ippNextAttribute (response);
979
ppd_device_id = NULL;
980
ppd_make_and_model = NULL;
984
while (attr != NULL && ippGetGroupTag (attr) == IPP_TAG_PRINTER)
986
if (g_strcmp0 (ippGetName (attr), "ppd-device-id") == 0 &&
987
ippGetValueTag (attr) == IPP_TAG_TEXT)
988
ppd_device_id = (gchar *) ippGetString (attr, 0, NULL);
989
else if (g_strcmp0 (ippGetName (attr), "ppd-make-and-model") == 0 &&
990
ippGetValueTag (attr) == IPP_TAG_TEXT)
991
ppd_make_and_model = ippGetString (attr, 0, NULL);
992
else if (g_strcmp0 (ippGetName (attr), "ppd-name") == 0 &&
993
ippGetValueTag (attr) == IPP_TAG_NAME)
994
ppd_name = ippGetString (attr, 0, NULL);
995
else if (g_strcmp0 (ippGetName (attr), "ppd-product") == 0 &&
996
ippGetValueTag (attr) == IPP_TAG_TEXT)
997
ppd_product = ippGetString (attr, 0, NULL);
999
attr = ippNextAttribute (response);
1002
if (ppd_device_id && ppd_name)
1004
item = g_new0 (PPDItem, 1);
1005
item->ppd_name = g_strdup (ppd_name);
1006
item->ppd_device_id = g_strdup (ppd_device_id);
1007
item->ppd_make_and_model = g_strdup (ppd_make_and_model);
1008
item->ppd_product = g_strdup (ppd_product);
1010
tmp = get_tag_value (ppd_device_id, "mfg");
1012
tmp = get_tag_value (ppd_device_id, "manufacturer");
1013
item->mfg = normalize (tmp);
1016
tmp = get_tag_value (ppd_device_id, "mdl");
1018
tmp = get_tag_value (ppd_device_id, "model");
1019
item->mdl = normalize (tmp);
1022
item->match_level = PPD_EXACT_CMD_MATCH;
1023
ppd_exact_match_found = TRUE;
1024
list = g_list_append (list, item);
1033
ippDelete(response);
1036
/* Try match according to manufacturer and model fields */
1037
if (!ppd_exact_match_found && mfg_normalized && mdl_normalized)
1039
request = ippNewRequest (CUPS_GET_PPDS);
1040
response = cupsDoRequest (http, request, "/");
1043
ippGetStatusCode (response) <= IPP_OK_CONFLICT)
1045
for (i = 0; equivalents && equivalents[i]; i++)
1047
eq_normalized = normalize (equivalents[i]);
1048
for (attr = ippFirstAttribute (response); attr != NULL; attr = ippNextAttribute (response))
1050
while (attr != NULL && ippGetGroupTag (attr) != IPP_TAG_PRINTER)
1051
attr = ippNextAttribute (response);
1056
ppd_device_id = NULL;
1057
ppd_make_and_model = NULL;
1061
while (attr != NULL && ippGetGroupTag (attr) == IPP_TAG_PRINTER)
1063
if (g_strcmp0 (ippGetName (attr), "ppd-device-id") == 0 &&
1064
ippGetValueTag (attr) == IPP_TAG_TEXT)
1065
ppd_device_id = ippGetString (attr, 0, NULL);
1066
else if (g_strcmp0 (ippGetName (attr), "ppd-make-and-model") == 0 &&
1067
ippGetValueTag (attr) == IPP_TAG_TEXT)
1068
ppd_make_and_model = ippGetString (attr, 0, NULL);
1069
else if (g_strcmp0 (ippGetName (attr), "ppd-name") == 0 &&
1070
ippGetValueTag (attr) == IPP_TAG_NAME)
1071
ppd_name = ippGetString (attr, 0, NULL);
1072
else if (g_strcmp0 (ippGetName (attr), "ppd-product") == 0 &&
1073
ippGetValueTag (attr) == IPP_TAG_TEXT)
1074
ppd_product = ippGetString (attr, 0, NULL);
1076
attr = ippNextAttribute (response);
1079
if (ppd_device_id && ppd_name)
1081
item = g_new0 (PPDItem, 1);
1082
item->ppd_name = g_strdup (ppd_name);
1083
item->ppd_device_id = g_strdup (ppd_device_id);
1084
item->ppd_make_and_model = g_strdup (ppd_make_and_model);
1085
item->ppd_product = g_strdup (ppd_product);
1087
tmp = get_tag_value (ppd_device_id, "mfg");
1089
tmp = get_tag_value (ppd_device_id, "manufacturer");
1090
item->mfg = normalize (tmp);
1093
tmp = get_tag_value (ppd_device_id, "mdl");
1095
tmp = get_tag_value (ppd_device_id, "model");
1096
item->mdl = normalize (tmp);
1099
if (item->mdl && item->mfg &&
1100
g_ascii_strcasecmp (item->mdl, mdl_normalized) == 0 &&
1101
g_ascii_strcasecmp (item->mfg, eq_normalized) == 0)
1103
item->match_level = PPD_EXACT_MATCH;
1104
ppd_exact_match_found = TRUE;
1107
if (item->match_level == PPD_EXACT_MATCH)
1108
list = g_list_append (list, item);
1109
else if (item->mfg &&
1110
g_ascii_strcasecmp (item->mfg, eq_normalized) == 0)
1111
mdls = g_list_append (mdls, item);
1114
ppd_item_free (item);
1123
g_free (eq_normalized);
1128
ippDelete(response);
1135
list = append_best_ppds (list, mdls, mdl);
1137
/* Find out driver types for all listed drivers and set their preference values */
1138
for (tmp_list = list; tmp_list; tmp_list = tmp_list->next)
1140
item = (PPDItem *) tmp_list->data;
1143
item->driver_type = get_driver_type (item->ppd_name,
1144
item->ppd_device_id,
1145
item->ppd_make_and_model,
1148
item->preference_value = get_driver_preference (item);
1152
/* Sort driver list according to preference value */
1153
list = g_list_sort (list, preference_value_cmp);
1155
/* Split blacklisted drivers to tmp_list */
1156
for (tmp_list = list; tmp_list; tmp_list = tmp_list->next)
1158
item = (PPDItem *) tmp_list->data;
1159
if (item && item->preference_value >= 2000)
1167
tmp_list->prev->next = NULL;
1171
tmp_list->prev = NULL;
1172
for (tmp_list2 = tmp_list; tmp_list2; tmp_list2 = tmp_list2->next)
1174
item = (PPDItem *) tmp_list2->data;
1175
ppd_item_free (item);
1179
g_list_free (tmp_list);
1182
/* Free driver list and set the best one */
1185
item = (PPDItem *) list->data;
1188
result = g_new0 (PPDName, 1);
1189
result->ppd_name = g_strdup (item->ppd_name);
1190
result->ppd_match_level = item->match_level;
1191
switch (item->match_level)
1193
case PPD_GENERIC_MATCH:
1194
case PPD_CLOSE_MATCH:
1195
g_warning ("Found PPD does not match given device exactly!");
1202
for (tmp_list = list; tmp_list; tmp_list = tmp_list->next)
1204
item = (PPDItem *) tmp_list->data;
1205
ppd_item_free (item);
1214
for (tmp_list = mdls; tmp_list; tmp_list = tmp_list->next)
1216
item = (PPDItem *) tmp_list->data;
1217
ppd_item_free (item);
1225
g_free (mfg_normalized);
1226
g_free (mdl_normalized);
1228
g_strfreev (equivalents);
1235
165
get_dest_attr (const char *dest_name,
1236
166
const char *attr)
2591
1395
g_error_free (error);
1402
gchar *printer_name;
1403
gchar **attributes_names;
1405
GIACallback callback;
1407
GMainContext *context;
1411
get_ipp_attributes_idle_cb (gpointer user_data)
1413
GIAData *data = (GIAData *) user_data;
1415
data->callback (data->result, data->user_data);
1421
get_ipp_attributes_data_free (gpointer user_data)
1423
GIAData *data = (GIAData *) user_data;
1426
g_main_context_unref (data->context);
1427
g_free (data->printer_name);
1428
if (data->attributes_names)
1429
g_strfreev (data->attributes_names);
1434
get_ipp_attributes_cb (gpointer user_data)
1436
GIAData *data = (GIAData *) user_data;
1437
GSource *idle_source;
1439
idle_source = g_idle_source_new ();
1440
g_source_set_callback (idle_source,
1441
get_ipp_attributes_idle_cb,
1443
get_ipp_attributes_data_free);
1444
g_source_attach (idle_source, data->context);
1445
g_source_unref (idle_source);
1449
ipp_attribute_free2 (gpointer attr)
1451
IPPAttribute *attribute = (IPPAttribute *) attr;
1452
ipp_attribute_free (attribute);
1456
get_ipp_attributes_func (gpointer user_data)
1458
ipp_attribute_t *attr = NULL;
1459
GIAData *data = (GIAData *) user_data;
1461
ipp_t *response = NULL;
1463
char **requested_attrs = NULL;
1464
gint i, j, length = 0;
1466
printer_uri = g_strdup_printf ("ipp://localhost/printers/%s", data->printer_name);
1468
if (data->attributes_names)
1470
length = g_strv_length (data->attributes_names);
1472
requested_attrs = g_new0 (char *, length);
1473
for (i = 0; data->attributes_names[i]; i++)
1474
requested_attrs[i] = g_strdup (data->attributes_names[i]);
1476
request = ippNewRequest (IPP_GET_PRINTER_ATTRIBUTES);
1477
ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
1478
"printer-uri", NULL, printer_uri);
1479
ippAddStrings (request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
1480
"requested-attributes", length, NULL, (const char **) requested_attrs);
1481
response = cupsDoRequest (CUPS_HTTP_DEFAULT, request, "/");
1486
if (ippGetStatusCode (response) <= IPP_OK_CONFLICT)
1488
for (j = 0; j < length; j++)
1490
attr = ippFindAttribute (response, requested_attrs[j], IPP_TAG_ZERO);
1491
if (attr && ippGetCount (attr) > 0 && ippGetValueTag (attr) != IPP_TAG_NOVALUE)
1493
IPPAttribute *attribute;
1495
attribute = g_new0 (IPPAttribute, 1);
1496
attribute->attribute_name = g_strdup (requested_attrs[j]);
1497
attribute->attribute_values = g_new0 (IPPAttributeValue, ippGetCount (attr));
1498
attribute->num_of_values = ippGetCount (attr);
1500
if (ippGetValueTag (attr) == IPP_TAG_INTEGER ||
1501
ippGetValueTag (attr) == IPP_TAG_ENUM)
1503
attribute->attribute_type = IPP_ATTRIBUTE_TYPE_INTEGER;
1505
for (i = 0; i < ippGetCount (attr); i++)
1506
attribute->attribute_values[i].integer_value = ippGetInteger (attr, i);
1508
else if (ippGetValueTag (attr) == IPP_TAG_NAME ||
1509
ippGetValueTag (attr) == IPP_TAG_STRING ||
1510
ippGetValueTag (attr) == IPP_TAG_TEXT ||
1511
ippGetValueTag (attr) == IPP_TAG_URI ||
1512
ippGetValueTag (attr) == IPP_TAG_KEYWORD ||
1513
ippGetValueTag (attr) == IPP_TAG_URISCHEME)
1515
attribute->attribute_type = IPP_ATTRIBUTE_TYPE_STRING;
1517
for (i = 0; i < ippGetCount (attr); i++)
1518
attribute->attribute_values[i].string_value = g_strdup (ippGetString (attr, i, NULL));
1520
else if (ippGetValueTag (attr) == IPP_TAG_RANGE)
1522
attribute->attribute_type = IPP_ATTRIBUTE_TYPE_RANGE;
1524
for (i = 0; i < ippGetCount (attr); i++)
1526
attribute->attribute_values[i].lower_range =
1527
ippGetRange (attr, i, &(attribute->attribute_values[i].upper_range));
1530
else if (ippGetValueTag (attr) == IPP_TAG_BOOLEAN)
1532
attribute->attribute_type = IPP_ATTRIBUTE_TYPE_BOOLEAN;
1534
for (i = 0; i < ippGetCount (attr); i++)
1535
attribute->attribute_values[i].boolean_value = ippGetBoolean (attr, i);
1539
data->result = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, ipp_attribute_free2);
1541
g_hash_table_insert (data->result, g_strdup (requested_attrs[j]), attribute);
1546
ippDelete (response);
1550
for (i = 0; i < length; i++)
1551
g_free (requested_attrs[i]);
1552
g_free (requested_attrs);
1554
g_free (printer_uri);
1556
get_ipp_attributes_cb (data);
1562
get_ipp_attributes_async (const gchar *printer_name,
1563
gchar **attributes_names,
1564
GIACallback callback,
1569
GError *error = NULL;
1571
data = g_new0 (GIAData, 1);
1572
data->printer_name = g_strdup (printer_name);
1573
data->attributes_names = g_strdupv (attributes_names);
1574
data->callback = callback;
1575
data->user_data = user_data;
1576
data->context = g_main_context_ref_thread_default ();
1578
thread = g_thread_try_new ("get-ipp-attributes",
1579
get_ipp_attributes_func,
1585
g_warning ("%s", error->message);
1586
callback (NULL, user_data);
1588
g_error_free (error);
1589
get_ipp_attributes_data_free (data);
1593
g_thread_unref (thread);
1598
ipp_attribute_copy (IPPAttribute *attr)
1600
IPPAttribute *result = NULL;
1605
result = g_new0 (IPPAttribute, 1);
1608
result->attribute_name = g_strdup (attr->attribute_name);
1609
result->attribute_values = g_new0 (IPPAttributeValue, attr->num_of_values);
1610
for (i = 0; i < attr->num_of_values; i++)
1612
result->attribute_values[i] = attr->attribute_values[i];
1613
if (attr->attribute_values[i].string_value)
1614
result->attribute_values[i].string_value = g_strdup (attr->attribute_values[i].string_value);
1622
ipp_attribute_free (IPPAttribute *attr)
1628
for (i = 0; i < attr->num_of_values; i++)
1629
g_free (attr->attribute_values[i].string_value);
1631
g_free (attr->attribute_values);
1632
g_free (attr->attribute_name);
1641
gchar *printer_name;
1643
GCancellable *cancellable;
1644
PSPCallback callback;
1649
printer_set_ppd_async_dbus_cb (GObject *source_object,
1654
gboolean result = FALSE;
1655
PSPData *data = (PSPData *) user_data;
1656
GError *error = NULL;
1658
output = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
1661
g_object_unref (source_object);
1665
const gchar *ret_error;
1667
g_variant_get (output, "(&s)", &ret_error);
1668
if (ret_error[0] != '\0')
1669
g_warning ("%s", ret_error);
1673
g_variant_unref (output);
1677
if (error->code != G_IO_ERROR_CANCELLED)
1678
g_warning ("%s", error->message);
1679
g_error_free (error);
1682
/* Don't call callback if cancelled */
1683
if (!data->cancellable ||
1684
!g_cancellable_is_cancelled (data->cancellable))
1685
data->callback (g_strdup (data->printer_name),
1689
if (data->cancellable)
1690
g_object_unref (data->cancellable);
1694
g_unlink (data->ppd_copy);
1695
g_free (data->ppd_copy);
1698
g_free (data->printer_name);
1703
* Set ppd for given printer.
1704
* Don't use this for classes, just for printers.
1707
printer_set_ppd_async (const gchar *printer_name,
1708
const gchar *ppd_name,
1709
GCancellable *cancellable,
1710
PSPCallback callback,
1713
GDBusConnection *bus;
1715
GError *error = NULL;
1717
data = g_new0 (PSPData, 1);
1719
data->cancellable = g_object_ref (cancellable);
1720
data->callback = callback;
1721
data->user_data = user_data;
1722
data->printer_name = g_strdup (printer_name);
1724
if (printer_name == NULL ||
1725
printer_name[0] == '\0')
1730
bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
1733
g_warning ("Failed to get system bus: %s", error->message);
1734
g_error_free (error);
1738
g_dbus_connection_call (bus,
1743
g_variant_new ("(sssss)",
1749
G_VARIANT_TYPE ("(s)"),
1750
G_DBUS_CALL_FLAGS_NONE,
1753
printer_set_ppd_async_dbus_cb,
1759
callback (g_strdup (printer_name), FALSE, user_data);
1761
if (data->cancellable)
1762
g_object_unref (data->cancellable);
1763
g_free (data->printer_name);
1768
printer_set_ppd_file_async_scb (GObject *source_object,
1772
GDBusConnection *bus;
1774
PSPData *data = (PSPData *) user_data;
1775
GError *error = NULL;
1777
success = g_file_copy_finish (G_FILE (source_object),
1780
g_object_unref (source_object);
1784
g_warning ("%s", error->message);
1785
g_error_free (error);
1789
bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
1792
g_warning ("Failed to get system bus: %s", error->message);
1793
g_error_free (error);
1797
g_dbus_connection_call (bus,
1801
"PrinterAddWithPpdFile",
1802
g_variant_new ("(sssss)",
1808
G_VARIANT_TYPE ("(s)"),
1809
G_DBUS_CALL_FLAGS_NONE,
1812
printer_set_ppd_async_dbus_cb,
1818
data->callback (g_strdup (data->printer_name), FALSE, data->user_data);
1820
if (data->cancellable)
1821
g_object_unref (data->cancellable);
1822
g_free (data->printer_name);
1823
g_free (data->ppd_copy);
1828
* Set ppd for given printer.
1829
* Don't use this for classes, just for printers.
1832
printer_set_ppd_file_async (const gchar *printer_name,
1833
const gchar *ppd_filename,
1834
GCancellable *cancellable,
1835
PSPCallback callback,
1838
GFileIOStream *stream;
1840
GFile *source_ppd_file;
1841
GFile *destination_ppd_file;
1843
data = g_new0 (PSPData, 1);
1845
data->cancellable = g_object_ref (cancellable);
1846
data->callback = callback;
1847
data->user_data = user_data;
1848
data->printer_name = g_strdup (printer_name);
1850
if (printer_name == NULL ||
1851
printer_name[0] == '\0')
1857
* We need to copy the PPD to temp directory at first.
1858
* This is needed because of SELinux.
1860
source_ppd_file = g_file_new_for_path (ppd_filename);
1861
destination_ppd_file = g_file_new_tmp ("g-c-c-XXXXXX.ppd", &stream, NULL);
1862
g_object_unref (stream);
1863
data->ppd_copy = g_strdup (g_file_get_path (destination_ppd_file));
1865
g_file_copy_async (source_ppd_file,
1866
destination_ppd_file,
1867
G_FILE_COPY_OVERWRITE,
1872
printer_set_ppd_file_async_scb,
1875
g_object_unref (destination_ppd_file);
1880
callback (g_strdup (printer_name), FALSE, user_data);
1882
if (data->cancellable)
1883
g_object_unref (data->cancellable);
1884
g_free (data->printer_name);
1890
typedef void (*GPACallback) (gchar **attribute_values,
1891
gpointer user_data);
1895
gchar *attribute_name;
1898
GPACallback callback;
1900
GMainContext *context;
1904
get_ppds_attribute_idle_cb (gpointer user_data)
1906
GPAData *data = (GPAData *) user_data;
1908
data->callback (data->result, data->user_data);
1914
get_ppds_attribute_data_free (gpointer user_data)
1916
GPAData *data = (GPAData *) user_data;
1919
g_main_context_unref (data->context);
1920
g_free (data->attribute_name);
1921
g_strfreev (data->ppds_names);
1926
get_ppds_attribute_cb (gpointer user_data)
1928
GPAData *data = (GPAData *) user_data;
1929
GSource *idle_source;
1931
idle_source = g_idle_source_new ();
1932
g_source_set_callback (idle_source,
1933
get_ppds_attribute_idle_cb,
1935
get_ppds_attribute_data_free);
1936
g_source_attach (idle_source, data->context);
1937
g_source_unref (idle_source);
1941
get_ppds_attribute_func (gpointer user_data)
1943
ppd_file_t *ppd_file;
1944
ppd_attr_t *ppd_attr;
1945
GPAData *data = (GPAData *) user_data;
1946
gchar *ppd_filename;
1949
data->result = g_new0 (gchar *, g_strv_length (data->ppds_names) + 1);
1950
for (i = 0; data->ppds_names[i]; i++)
1952
ppd_filename = g_strdup (cupsGetServerPPD (CUPS_HTTP_DEFAULT, data->ppds_names[i]));
1955
ppd_file = ppdOpenFile (ppd_filename);
1958
ppd_attr = ppdFindAttr (ppd_file, data->attribute_name, NULL);
1959
if (ppd_attr != NULL)
1960
data->result[i] = g_strdup (ppd_attr->value);
1962
ppdClose (ppd_file);
1965
g_unlink (ppd_filename);
1966
g_free (ppd_filename);
1970
get_ppds_attribute_cb (data);
1976
* Get values of requested PPD attribute for given PPDs.
1979
get_ppds_attribute_async (gchar **ppds_names,
1980
gchar *attribute_name,
1981
GPACallback callback,
1986
GError *error = NULL;
1988
if (!ppds_names || !attribute_name)
1990
callback (NULL, user_data);
1994
data = g_new0 (GPAData, 1);
1995
data->ppds_names = g_strdupv (ppds_names);
1996
data->attribute_name = g_strdup (attribute_name);
1997
data->callback = callback;
1998
data->user_data = user_data;
1999
data->context = g_main_context_ref_thread_default ();
2001
thread = g_thread_try_new ("get-ppds-attribute",
2002
get_ppds_attribute_func,
2008
g_warning ("%s", error->message);
2009
callback (NULL, user_data);
2011
g_error_free (error);
2012
get_ppds_attribute_data_free (data);
2016
g_thread_unref (thread);
2022
typedef void (*GDACallback) (gchar *device_id,
2023
gchar *device_make_and_model,
2025
gpointer user_data);
2029
gchar *printer_name;
2031
GCancellable *cancellable;
2032
GList *backend_list;
2033
GDACallback callback;
2039
gchar *printer_name;
2042
GCancellable *cancellable;
2043
GPNCallback callback;
2048
get_ppd_names_async_cb (gchar **attribute_values,
2051
GPNData *data = (GPNData *) user_data;
2054
if (g_cancellable_is_cancelled (data->cancellable))
2056
g_strfreev (attribute_values);
2058
for (i = 0; data->result[i]; i++)
2060
g_free (data->result[i]->ppd_name);
2061
g_free (data->result[i]);
2064
g_free (data->result);
2065
data->result = NULL;
2070
if (attribute_values)
2072
for (i = 0; attribute_values[i]; i++)
2073
data->result[i]->ppd_display_name = attribute_values[i];
2075
g_free (attribute_values);
2079
data->callback (data->result,
2081
g_cancellable_is_cancelled (data->cancellable),
2084
if (data->cancellable)
2085
g_object_unref (data->cancellable);
2086
g_free (data->printer_name);
2091
get_ppd_names_async_dbus_scb (GObject *source_object,
2097
PPDName **result = NULL;
2098
GPNData *data = (GPNData *) user_data;
2099
GError *error = NULL;
2100
GList *driver_list = NULL;
2103
static const char * const match_levels[] = {
2110
output = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
2113
g_object_unref (source_object);
2119
g_variant_get (output, "(@a(ss))",
2129
for (j = 0; j < G_N_ELEMENTS (match_levels) && n < data->count; j++)
2131
g_variant_get (array,
2135
while ((item = g_variant_iter_next_value (iter)))
2137
g_variant_get (item,
2142
if (g_str_equal (match, match_levels[j]) && n < data->count)
2144
ppd_item = g_new0 (PPDName, 1);
2145
ppd_item->ppd_name = g_strdup (driver);
2147
if (g_strcmp0 (match, "exact-cmd") == 0)
2148
ppd_item->ppd_match_level = PPD_EXACT_CMD_MATCH;
2149
else if (g_strcmp0 (match, "exact") == 0)
2150
ppd_item->ppd_match_level = PPD_EXACT_MATCH;
2151
else if (g_strcmp0 (match, "close") == 0)
2152
ppd_item->ppd_match_level = PPD_CLOSE_MATCH;
2153
else if (g_strcmp0 (match, "generic") == 0)
2154
ppd_item->ppd_match_level = PPD_GENERIC_MATCH;
2155
else if (g_strcmp0 (match, "none") == 0)
2156
ppd_item->ppd_match_level = PPD_NO_MATCH;
2158
driver_list = g_list_append (driver_list, ppd_item);
2165
g_variant_unref (item);
2169
g_variant_unref (array);
2172
g_variant_unref (output);
2176
if (error->code != G_IO_ERROR_CANCELLED)
2177
g_warning ("%s", error->message);
2178
g_error_free (error);
2183
result = g_new0 (PPDName *, n + 1);
2185
for (iter = driver_list; iter; iter = iter->next)
2187
result[i] = iter->data;
2196
data->result = result;
2198
ppds_names = g_new0 (gchar *, n + 1);
2199
for (i = 0; i < n; i++)
2200
ppds_names[i] = g_strdup (result[i]->ppd_name);
2202
get_ppds_attribute_async (ppds_names,
2204
get_ppd_names_async_cb,
2207
g_strfreev (ppds_names);
2211
data->callback (NULL,
2213
g_cancellable_is_cancelled (data->cancellable),
2216
if (data->cancellable)
2217
g_object_unref (data->cancellable);
2218
g_free (data->printer_name);
2224
get_device_attributes_cb (gchar *device_id,
2225
gchar *device_make_and_model,
2229
GDBusConnection *bus;
2230
GError *error = NULL;
2231
GPNData *data = (GPNData *) user_data;
2233
if (g_cancellable_is_cancelled (data->cancellable))
2236
if (!device_id || !device_make_and_model || !device_uri)
2239
bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
2242
g_warning ("Failed to get system bus: %s", error->message);
2243
g_error_free (error);
2247
g_dbus_connection_call (bus,
2252
g_variant_new ("(sss)",
2254
device_make_and_model,
2256
G_VARIANT_TYPE ("(a(ss))"),
2257
G_DBUS_CALL_FLAGS_NONE,
2260
get_ppd_names_async_dbus_scb,
2266
data->callback (NULL,
2268
g_cancellable_is_cancelled (data->cancellable),
2271
if (data->cancellable)
2272
g_object_unref (data->cancellable);
2273
g_free (data->printer_name);
2278
get_device_attributes_async_dbus_cb (GObject *source_object,
2284
GDAData *data = (GDAData *) user_data;
2285
GError *error = NULL;
2287
gchar *device_id = NULL;
2288
gchar *device_make_and_model = NULL;
2290
output = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
2293
g_object_unref (source_object);
2297
const gchar *ret_error;
2298
GVariant *devices_variant = NULL;
2300
g_variant_get (output, "(&s@a{ss})",
2304
if (ret_error[0] != '\0')
2306
g_warning ("%s", ret_error);
2309
if (devices_variant)
2315
if (data->device_uri)
2323
g_variant_get (devices_variant,
2327
while ((item = g_variant_iter_next_value (iter)))
2329
g_variant_get (item,
2334
if (g_str_equal (value, data->device_uri))
2336
number = g_strrstr (key, ":");
2340
index = g_ascii_strtoll (number, &endptr, 10);
2341
if (index == 0 && endptr == (number))
2348
g_variant_unref (item);
2351
suffix = g_strdup_printf (":%d", index);
2353
g_variant_get (devices_variant,
2357
while ((item = g_variant_iter_next_value (iter)))
2362
g_variant_get (item,
2367
if (g_str_has_suffix (key, suffix))
2369
if (g_str_has_prefix (key, "device-id"))
2371
device_id = g_strdup (value);
2374
if (g_str_has_prefix (key, "device-make-and-model"))
2376
device_make_and_model = g_strdup (value);
2382
g_variant_unref (item);
2388
g_variant_unref (devices_variant);
2391
g_variant_unref (output);
2395
if (error->code != G_IO_ERROR_CANCELLED)
2396
g_warning ("%s", error->message);
2397
g_error_free (error);
2400
if (!device_id || !device_make_and_model)
2402
GVariantBuilder include_scheme_builder;
2405
g_free (device_make_and_model);
2408
device_make_and_model = NULL;
2410
if (data->backend_list && !g_cancellable_is_cancelled (data->cancellable))
2412
g_variant_builder_init (&include_scheme_builder, G_VARIANT_TYPE ("as"));
2413
g_variant_builder_add (&include_scheme_builder, "s", data->backend_list->data);
2415
tmp = data->backend_list;
2416
data->backend_list = g_list_remove_link (data->backend_list, tmp);
2417
g_list_free_full (tmp, g_free);
2419
g_dbus_connection_call (G_DBUS_CONNECTION (g_object_ref (source_object)),
2424
g_variant_new ("(iiasas)",
2427
&include_scheme_builder,
2429
G_VARIANT_TYPE ("(sa{ss})"),
2430
G_DBUS_CALL_FLAGS_NONE,
2433
get_device_attributes_async_dbus_cb,
2439
g_object_unref (source_object);
2441
if (data->backend_list)
2443
g_list_free_full (data->backend_list, g_free);
2444
data->backend_list = NULL;
2447
data->callback (device_id,
2448
device_make_and_model,
2452
if (data->cancellable)
2453
g_object_unref (data->cancellable);
2454
g_free (data->device_uri);
2455
g_free (data->printer_name);
2460
get_device_attributes_async_scb (GHashTable *result,
2463
GDBusConnection *bus;
2464
GVariantBuilder include_scheme_builder;
2466
GDAData *data = (GDAData *) user_data;
2467
GError *error = NULL;
2470
const gchar *backends[] =
2471
{"hpfax", "ncp", "beh", "bluetooth", "snmp",
2472
"dnssd", "hp", "ipp", "lpd", "parallel",
2473
"serial", "socket", "usb", NULL};
2477
attr = g_hash_table_lookup (result, "device-uri");
2478
if (attr && attr->attribute_type == IPP_ATTRIBUTE_TYPE_STRING &&
2479
attr->num_of_values > 0)
2480
data->device_uri = g_strdup (attr->attribute_values[0].string_value);
2481
g_hash_table_unref (result);
2484
if (g_cancellable_is_cancelled (data->cancellable))
2487
if (!data->device_uri)
2490
bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
2493
g_warning ("Failed to get system bus: %s", error->message);
2494
g_error_free (error);
2498
for (i = 0; backends[i]; i++)
2499
data->backend_list = g_list_prepend (data->backend_list, g_strdup (backends[i]));
2501
g_variant_builder_init (&include_scheme_builder, G_VARIANT_TYPE ("as"));
2502
g_variant_builder_add (&include_scheme_builder, "s", data->backend_list->data);
2504
tmp = data->backend_list;
2505
data->backend_list = g_list_remove_link (data->backend_list, tmp);
2506
g_list_free_full (tmp, g_free);
2508
g_dbus_connection_call (g_object_ref (bus),
2513
g_variant_new ("(iiasas)",
2516
&include_scheme_builder,
2518
G_VARIANT_TYPE ("(sa{ss})"),
2519
G_DBUS_CALL_FLAGS_NONE,
2522
get_device_attributes_async_dbus_cb,
2528
data->callback (NULL, NULL, NULL, data->user_data);
2530
if (data->cancellable)
2531
g_object_unref (data->cancellable);
2532
g_free (data->device_uri);
2533
g_free (data->printer_name);
2538
* Get device-id, device-make-and-model and device-uri for given printer.
2541
get_device_attributes_async (const gchar *printer_name,
2542
GCancellable *cancellable,
2543
GDACallback callback,
2551
callback (NULL, NULL, NULL, user_data);
2555
data = g_new0 (GDAData, 1);
2556
data->printer_name = g_strdup (printer_name);
2558
data->cancellable = g_object_ref (cancellable);
2559
data->callback = callback;
2560
data->user_data = user_data;
2562
attributes = g_new0 (gchar *, 2);
2563
attributes[0] = g_strdup ("device-uri");
2565
get_ipp_attributes_async (printer_name,
2567
get_device_attributes_async_scb,
2570
g_strfreev (attributes);
2574
* Return "count" best matching driver names for given printer.
2577
get_ppd_names_async (gchar *printer_name,
2579
GCancellable *cancellable,
2580
GPNCallback callback,
2587
callback (NULL, NULL, TRUE, user_data);
2591
data = g_new0 (GPNData, 1);
2592
data->printer_name = g_strdup (printer_name);
2593
data->count = count;
2595
data->cancellable = g_object_ref (cancellable);
2596
data->callback = callback;
2597
data->user_data = user_data;
2600
* We have to find out device-id for this printer at first.
2602
get_device_attributes_async (printer_name,
2604
get_device_attributes_cb,
2611
GCancellable *cancellable;
2612
GAPCallback callback;
2614
GMainContext *context;
2618
get_all_ppds_idle_cb (gpointer user_data)
2620
GAPData *data = (GAPData *) user_data;
2622
/* Don't call callback if cancelled */
2623
if (data->cancellable &&
2624
g_cancellable_is_cancelled (data->cancellable))
2626
ppd_list_free (data->result);
2627
data->result = NULL;
2631
data->callback (data->result, data->user_data);
2638
get_all_ppds_data_free (gpointer user_data)
2640
GAPData *data = (GAPData *) user_data;
2643
g_main_context_unref (data->context);
2644
if (data->cancellable)
2645
g_object_unref (data->cancellable);
2650
get_all_ppds_cb (gpointer user_data)
2652
GAPData *data = (GAPData *) user_data;
2653
GSource *idle_source;
2655
idle_source = g_idle_source_new ();
2656
g_source_set_callback (idle_source,
2657
get_all_ppds_idle_cb,
2659
get_all_ppds_data_free);
2660
g_source_attach (idle_source, data->context);
2661
g_source_unref (idle_source);
2664
static const struct {
2665
const char *normalized_name;
2666
const char *display_name;
2667
} manufacturers_names[] = {
2669
{ "anitech", "Anitech" },
2670
{ "apple", "Apple" },
2671
{ "apollo", "Apollo" },
2672
{ "brother", "Brother" },
2673
{ "canon", "Canon" },
2674
{ "citizen", "Citizen" },
2675
{ "citoh", "Citoh" },
2676
{ "compaq", "Compaq" },
2681
{ "epson", "Epson" },
2682
{ "fujifilm", "Fujifilm" },
2683
{ "fujitsu", "Fujitsu" },
2684
{ "gelsprinter", "Ricoh" },
2685
{ "generic", "Generic" },
2686
{ "genicom", "Genicom" },
2687
{ "gestetner", "Gestetner" },
2688
{ "hewlett packard", "Hewlett-Packard" },
2689
{ "heidelberg", "Heidelberg" },
2690
{ "hitachi", "Hitachi" },
2691
{ "hp", "Hewlett-Packard" },
2693
{ "imagen", "Imagen" },
2694
{ "imagistics", "Imagistics" },
2695
{ "infoprint", "InfoPrint" },
2696
{ "infotec", "Infotec" },
2697
{ "intellitech", "Intellitech" },
2698
{ "kodak", "Kodak" },
2699
{ "konica minolta", "Minolta" },
2700
{ "kyocera", "Kyocera" },
2701
{ "kyocera mita", "Kyocera" },
2702
{ "lanier", "Lanier" },
2703
{ "lexmark international", "Lexmark" },
2704
{ "lexmark", "Lexmark" },
2705
{ "minolta", "Minolta" },
2706
{ "minolta qms", "Minolta" },
2707
{ "mitsubishi", "Mitsubishi" },
2712
{ "oki data corp", "Oki" },
2713
{ "olivetti", "Olivetti" },
2714
{ "olympus", "Olympus" },
2715
{ "panasonic", "Panasonic" },
2717
{ "pentax", "Pentax" },
2719
{ "raven", "Raven" },
2721
{ "ricoh", "Ricoh" },
2722
{ "samsung", "Samsung" },
2723
{ "savin", "Savin" },
2724
{ "seiko", "Seiko" },
2725
{ "sharp", "Sharp" },
2726
{ "shinko", "Shinko" },
2727
{ "sipix", "SiPix" },
2730
{ "tally", "Tally" },
2731
{ "tektronix", "Tektronix" },
2732
{ "texas instruments", "Texas Instruments" },
2733
{ "toshiba", "Toshiba" },
2734
{ "toshiba tec corp.", "Toshiba" },
2735
{ "xante", "Xante" },
2736
{ "xerox", "Xerox" },
2737
{ "zebra", "Zebra" },
2741
get_all_ppds_func (gpointer user_data)
2743
ipp_attribute_t *attr;
2744
GHashTable *ppds_hash = NULL;
2745
GHashTable *manufacturers_hash = NULL;
2746
GAPData *data = (GAPData *) user_data;
2751
const gchar *ppd_make_and_model;
2752
const gchar *ppd_device_id;
2753
const gchar *ppd_name;
2754
const gchar *ppd_product;
2755
const gchar *ppd_make;
2757
gchar *mfg_normalized;
2759
gchar *manufacturer_display_name;
2762
request = ippNewRequest (CUPS_GET_PPDS);
2763
response = cupsDoRequest (CUPS_HTTP_DEFAULT, request, "/");
2766
ippGetStatusCode (response) <= IPP_OK_CONFLICT)
2769
* This hash contains names of manufacturers as keys and
2770
* values are GLists of PPD names.
2772
ppds_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
2775
* This hash contains all possible names of manufacturers as keys
2776
* and values are just first occurences of their equivalents.
2777
* This is for mapping of e.g. "Hewlett Packard" and "HP" to the same name
2778
* (the one which comes first).
2780
manufacturers_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
2782
for (i = 0; i < G_N_ELEMENTS (manufacturers_names); i++)
2784
g_hash_table_insert (manufacturers_hash,
2785
g_strdup (manufacturers_names[i].normalized_name),
2786
g_strdup (manufacturers_names[i].display_name));
2789
for (attr = ippFirstAttribute (response); attr != NULL; attr = ippNextAttribute (response))
2791
while (attr != NULL && ippGetGroupTag (attr) != IPP_TAG_PRINTER)
2792
attr = ippNextAttribute (response);
2797
ppd_device_id = NULL;
2798
ppd_make_and_model = NULL;
2803
mfg_normalized = NULL;
2806
while (attr != NULL && ippGetGroupTag (attr) == IPP_TAG_PRINTER)
2808
if (g_strcmp0 (ippGetName (attr), "ppd-device-id") == 0 &&
2809
ippGetValueTag (attr) == IPP_TAG_TEXT)
2810
ppd_device_id = ippGetString (attr, 0, NULL);
2811
else if (g_strcmp0 (ippGetName (attr), "ppd-make-and-model") == 0 &&
2812
ippGetValueTag (attr) == IPP_TAG_TEXT)
2813
ppd_make_and_model = ippGetString (attr, 0, NULL);
2814
else if (g_strcmp0 (ippGetName (attr), "ppd-name") == 0 &&
2815
ippGetValueTag (attr) == IPP_TAG_NAME)
2816
ppd_name = ippGetString (attr, 0, NULL);
2817
else if (g_strcmp0 (ippGetName (attr), "ppd-product") == 0 &&
2818
ippGetValueTag (attr) == IPP_TAG_TEXT)
2819
ppd_product = ippGetString (attr, 0, NULL);
2820
else if (g_strcmp0 (ippGetName (attr), "ppd-make") == 0 &&
2821
ippGetValueTag (attr) == IPP_TAG_TEXT)
2822
ppd_make = ippGetString (attr, 0, NULL);
2824
attr = ippNextAttribute (response);
2827
/* Get manufacturer's name */
2828
if (ppd_device_id && ppd_device_id[0] != '\0')
2830
mfg = get_tag_value (ppd_device_id, "mfg");
2832
mfg = get_tag_value (ppd_device_id, "manufacturer");
2833
mfg_normalized = normalize (mfg);
2838
ppd_make[0] != '\0')
2840
mfg = g_strdup (ppd_make);
2841
mfg_normalized = normalize (ppd_make);
2845
if (ppd_make_and_model &&
2846
ppd_make_and_model[0] != '\0')
2848
mdl = g_strdup (ppd_make_and_model);
2853
ppd_product[0] != '\0')
2855
mdl = g_strdup (ppd_product);
2860
ppd_device_id[0] != '\0')
2862
mdl = get_tag_value (ppd_device_id, "mdl");
2864
mdl = get_tag_value (ppd_device_id, "model");
2867
if (ppd_name && ppd_name[0] != '\0' &&
2868
mdl && mdl[0] != '\0' &&
2869
mfg && mfg[0] != '\0')
2871
manufacturer_display_name = g_hash_table_lookup (manufacturers_hash, mfg_normalized);
2872
if (!manufacturer_display_name)
2874
g_hash_table_insert (manufacturers_hash, g_strdup (mfg_normalized), g_strdup (mfg));
2878
g_free (mfg_normalized);
2879
mfg_normalized = normalize (manufacturer_display_name);
2882
item = g_new0 (PPDName, 1);
2883
item->ppd_name = g_strdup (ppd_name);
2884
item->ppd_display_name = g_strdup (mdl);
2885
item->ppd_match_level = -1;
2887
list = g_hash_table_lookup (ppds_hash, mfg_normalized);
2890
list = g_list_append (list, item);
2894
list = g_list_append (list, item);
2895
g_hash_table_insert (ppds_hash, g_strdup (mfg_normalized), list);
2901
g_free (mfg_normalized);
2909
ippDelete(response);
2914
GHashTableIter iter;
2918
GList *sort_list = NULL;
2922
data->result = g_new0 (PPDList, 1);
2923
data->result->num_of_manufacturers = g_hash_table_size (ppds_hash);
2924
data->result->manufacturers = g_new0 (PPDManufacturerItem *, data->result->num_of_manufacturers);
2926
g_hash_table_iter_init (&iter, ppds_hash);
2927
while (g_hash_table_iter_next (&iter, &key, &value))
2929
sort_list = g_list_append (sort_list, g_strdup (key));
2932
/* Sort list of manufacturers */
2933
sort_list = g_list_sort (sort_list, (GCompareFunc) g_strcmp0);
2936
* Fill resulting list of lists (list of manufacturers where
2937
* each item contains list of PPD names)
2940
for (list_iter = sort_list; list_iter; list_iter = list_iter->next)
2942
name = (gchar *) list_iter->data;
2943
value = g_hash_table_lookup (ppds_hash, name);
2945
data->result->manufacturers[i] = g_new0 (PPDManufacturerItem, 1);
2946
data->result->manufacturers[i]->manufacturer_name = g_strdup (name);
2947
data->result->manufacturers[i]->manufacturer_display_name = g_strdup (g_hash_table_lookup (manufacturers_hash, name));
2948
data->result->manufacturers[i]->num_of_ppds = g_list_length ((GList *) value);
2949
data->result->manufacturers[i]->ppds = g_new0 (PPDName *, data->result->manufacturers[i]->num_of_ppds);
2951
for (ppd_item = (GList *) value, j = 0; ppd_item; ppd_item = ppd_item->next, j++)
2953
data->result->manufacturers[i]->ppds[j] = ppd_item->data;
2956
g_list_free ((GList *) value);
2961
g_list_free_full (sort_list, g_free);
2962
g_hash_table_destroy (ppds_hash);
2963
g_hash_table_destroy (manufacturers_hash);
2966
get_all_ppds_cb (data);
2972
* Get names of all installed PPDs sorted by manufacturers names.
2975
get_all_ppds_async (GCancellable *cancellable,
2976
GAPCallback callback,
2981
GError *error = NULL;
2983
data = g_new0 (GAPData, 1);
2985
data->cancellable = g_object_ref (cancellable);
2986
data->callback = callback;
2987
data->user_data = user_data;
2988
data->context = g_main_context_ref_thread_default ();
2990
thread = g_thread_try_new ("get-all-ppds",
2997
g_warning ("%s", error->message);
2998
callback (NULL, user_data);
3000
g_error_free (error);
3001
get_all_ppds_data_free (data);
3005
g_thread_unref (thread);
3010
ppd_list_copy (PPDList *list)
3012
PPDList *result = NULL;
3017
result = g_new0 (PPDList, 1);
3018
result->num_of_manufacturers = list->num_of_manufacturers;
3019
result->manufacturers = g_new0 (PPDManufacturerItem *, list->num_of_manufacturers);
3021
for (i = 0; i < result->num_of_manufacturers; i++)
3023
result->manufacturers[i] = g_new0 (PPDManufacturerItem, 1);
3024
result->manufacturers[i]->num_of_ppds = list->manufacturers[i]->num_of_ppds;
3025
result->manufacturers[i]->ppds = g_new0 (PPDName *, result->manufacturers[i]->num_of_ppds);
3027
result->manufacturers[i]->manufacturer_display_name =
3028
g_strdup (list->manufacturers[i]->manufacturer_display_name);
3030
result->manufacturers[i]->manufacturer_name =
3031
g_strdup (list->manufacturers[i]->manufacturer_name);
3033
for (j = 0; j < result->manufacturers[i]->num_of_ppds; j++)
3035
result->manufacturers[i]->ppds[j] = g_new0 (PPDName, 1);
3037
result->manufacturers[i]->ppds[j]->ppd_display_name =
3038
g_strdup (list->manufacturers[i]->ppds[j]->ppd_display_name);
3040
result->manufacturers[i]->ppds[j]->ppd_name =
3041
g_strdup (list->manufacturers[i]->ppds[j]->ppd_name);
3043
result->manufacturers[i]->ppds[j]->ppd_match_level =
3044
list->manufacturers[i]->ppds[j]->ppd_match_level;
3053
ppd_list_free (PPDList *list)
3059
for (i = 0; i < list->num_of_manufacturers; i++)
3061
for (j = 0; j < list->manufacturers[i]->num_of_ppds; j++)
3063
g_free (list->manufacturers[i]->ppds[j]->ppd_name);
3064
g_free (list->manufacturers[i]->ppds[j]->ppd_display_name);
3065
g_free (list->manufacturers[i]->ppds[j]);
3068
g_free (list->manufacturers[i]->manufacturer_name);
3069
g_free (list->manufacturers[i]->manufacturer_display_name);
3070
g_free (list->manufacturers[i]->ppds);
3071
g_free (list->manufacturers[i]);
3074
g_free (list->manufacturers);
3080
get_standard_manufacturers_name (gchar *name)
3082
gchar *normalized_name;
3083
gchar *result = NULL;
3088
normalized_name = normalize (name);
3090
for (i = 0; i < G_N_ELEMENTS (manufacturers_names); i++)
3092
if (g_strcmp0 (manufacturers_names[i].normalized_name, normalized_name) == 0)
3094
result = g_strdup (manufacturers_names[i].display_name);
3099
g_free (normalized_name);
3107
gchar *printer_name;
3111
PGPCallback callback;
3113
GMainContext *context;
3117
printer_get_ppd_idle_cb (gpointer user_data)
3119
PGPData *data = (PGPData *) user_data;
3121
data->callback (data->result, data->user_data);
3127
printer_get_ppd_data_free (gpointer user_data)
3129
PGPData *data = (PGPData *) user_data;
3132
g_main_context_unref (data->context);
3133
g_free (data->result);
3134
g_free (data->printer_name);
3135
g_free (data->host_name);
3140
printer_get_ppd_cb (gpointer user_data)
3142
PGPData *data = (PGPData *) user_data;
3143
GSource *idle_source;
3145
idle_source = g_idle_source_new ();
3146
g_source_set_callback (idle_source,
3147
printer_get_ppd_idle_cb,
3149
printer_get_ppd_data_free);
3150
g_source_attach (idle_source, data->context);
3151
g_source_unref (idle_source);
3155
printer_get_ppd_func (gpointer user_data)
3157
PGPData *data = (PGPData *) user_data;
3159
if (data->host_name)
3163
http = httpConnect (data->host_name, data->port);
3166
data->result = g_strdup (cupsGetPPD2 (http, data->printer_name));
3172
data->result = g_strdup (cupsGetPPD (data->printer_name));
3175
printer_get_ppd_cb (data);
3181
printer_get_ppd_async (const gchar *printer_name,
3182
const gchar *host_name,
3184
PGPCallback callback,
3189
GError *error = NULL;
3191
data = g_new0 (PGPData, 1);
3192
data->printer_name = g_strdup (printer_name);
3193
data->host_name = g_strdup (host_name);
3195
data->callback = callback;
3196
data->user_data = user_data;
3197
data->context = g_main_context_ref_thread_default ();
3199
thread = g_thread_try_new ("printer-get-ppd",
3200
printer_get_ppd_func,
3206
g_warning ("%s", error->message);
3207
callback (NULL, user_data);
3209
g_error_free (error);
3210
printer_get_ppd_data_free (data);
3214
g_thread_unref (thread);
3220
gchar *printer_name;
3221
cups_dest_t *result;
3222
GNDCallback callback;
3224
GMainContext *context;
3228
get_named_dest_idle_cb (gpointer user_data)
3230
GNDData *data = (GNDData *) user_data;
3232
data->callback (data->result, data->user_data);
3238
get_named_dest_data_free (gpointer user_data)
3240
GNDData *data = (GNDData *) user_data;
3243
g_main_context_unref (data->context);
3244
g_free (data->printer_name);
3249
get_named_dest_cb (gpointer user_data)
3251
GNDData *data = (GNDData *) user_data;
3252
GSource *idle_source;
3254
idle_source = g_idle_source_new ();
3255
g_source_set_callback (idle_source,
3256
get_named_dest_idle_cb,
3258
get_named_dest_data_free);
3259
g_source_attach (idle_source, data->context);
3260
g_source_unref (idle_source);
3264
get_named_dest_func (gpointer user_data)
3266
GNDData *data = (GNDData *) user_data;
3268
data->result = cupsGetNamedDest (CUPS_HTTP_DEFAULT, data->printer_name, NULL);
3270
get_named_dest_cb (data);
3276
get_named_dest_async (const gchar *printer_name,
3277
GNDCallback callback,
3282
GError *error = NULL;
3284
data = g_new0 (GNDData, 1);
3285
data->printer_name = g_strdup (printer_name);
3286
data->callback = callback;
3287
data->user_data = user_data;
3288
data->context = g_main_context_ref_thread_default ();
3290
thread = g_thread_try_new ("get-named-dest",
3291
get_named_dest_func,
3297
g_warning ("%s", error->message);
3298
callback (NULL, user_data);
3300
g_error_free (error);
3301
get_named_dest_data_free (data);
3305
g_thread_unref (thread);
3311
GCancellable *cancellable;
3312
PAOCallback callback;
3317
printer_add_option_async_dbus_cb (GObject *source_object,
3322
gboolean success = FALSE;
3323
PAOData *data = (PAOData *) user_data;
3324
GError *error = NULL;
3326
output = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
3329
g_object_unref (source_object);
3333
const gchar *ret_error;
3335
g_variant_get (output, "(&s)", &ret_error);
3336
if (ret_error[0] != '\0')
3337
g_warning ("%s", ret_error);
3341
g_variant_unref (output);
3345
if (error->code != G_IO_ERROR_CANCELLED)
3346
g_warning ("%s", error->message);
3347
g_error_free (error);
3350
data->callback (success, data->user_data);
3352
if (data->cancellable)
3353
g_object_unref (data->cancellable);
3358
printer_add_option_async (const gchar *printer_name,
3359
const gchar *option_name,
3361
gboolean set_default,
3362
GCancellable *cancellable,
3363
PAOCallback callback,
3366
GVariantBuilder array_builder;
3367
GDBusConnection *bus;
3369
GError *error = NULL;
3372
bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
3375
g_warning ("Failed to get system bus: %s", error->message);
3376
g_error_free (error);
3377
callback (FALSE, user_data);
3381
g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("as"));
3384
for (i = 0; values[i]; i++)
3385
g_variant_builder_add (&array_builder, "s", values[i]);
3388
data = g_new0 (PAOData, 1);
3389
data->cancellable = cancellable;
3390
data->callback = callback;
3391
data->user_data = user_data;
3393
g_dbus_connection_call (bus,
3397
set_default ? "PrinterAddOptionDefault" :
3399
g_variant_new ("(ssas)",
3403
G_VARIANT_TYPE ("(s)"),
3404
G_DBUS_CALL_FLAGS_NONE,
3407
printer_add_option_async_dbus_cb,
3413
GCancellable *cancellable;
3414
GCDCallback callback;
3416
GList *backend_list;
3420
get_suffix_index (gchar *string)
3426
number = g_strrstr (string, ":");
3430
index = g_ascii_strtoll (number, &endptr, 10);
3431
if (index == 0 && endptr == number)
3439
get_cups_devices_async_dbus_cb (GObject *source_object,
3444
PpPrintDevice **devices = NULL;
3446
GCDData *data = (GCDData *) user_data;
3447
GError *error = NULL;
3448
GList *result = NULL;
3449
gint num_of_devices = 0;
3451
output = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
3457
const gchar *ret_error;
3458
GVariant *devices_variant = NULL;
3460
g_variant_get (output, "(&s@a{ss})",
3464
if (ret_error[0] != '\0')
3466
g_warning ("%s", ret_error);
3469
if (devices_variant)
3475
gint index = -1, max_index = -1, i;
3477
g_variant_get (devices_variant, "a{ss}", &iter);
3478
while ((item = g_variant_iter_next_value (iter)))
3480
g_variant_get (item, "{ss}", &key, &value);
3482
index = get_suffix_index (key);
3483
if (index > max_index)
3488
g_variant_unref (item);
3493
num_of_devices = max_index + 1;
3494
devices = g_new0 (PpPrintDevice *, num_of_devices);
3496
g_variant_get (devices_variant, "a{ss}", &iter);
3497
while ((item = g_variant_iter_next_value (iter)))
3499
g_variant_get (item, "{ss}", &key, &value);
3501
index = get_suffix_index (key);
3504
if (!devices[index])
3505
devices[index] = g_new0 (PpPrintDevice, 1);
3507
if (g_str_has_prefix (key, "device-class"))
3508
devices[index]->device_class = g_strdup (value);
3509
else if (g_str_has_prefix (key, "device-id"))
3510
devices[index]->device_id = g_strdup (value);
3511
else if (g_str_has_prefix (key, "device-info"))
3512
devices[index]->device_info = g_strdup (value);
3513
else if (g_str_has_prefix (key, "device-make-and-model"))
3515
devices[index]->device_make_and_model = g_strdup (value);
3516
devices[index]->device_name = g_strdup (value);
3518
else if (g_str_has_prefix (key, "device-uri"))
3519
devices[index]->device_uri = g_strdup (value);
3520
else if (g_str_has_prefix (key, "device-location"))
3521
devices[index]->device_location = g_strdup (value);
3523
devices[index]->acquisition_method = ACQUISITION_METHOD_DEFAULT_CUPS_SERVER;
3528
g_variant_unref (item);
3531
for (i = 0; i < num_of_devices; i++)
3532
result = g_list_append (result, devices[i]);
3537
g_variant_unref (devices_variant);
3540
g_variant_unref (output);
3544
if (error->domain != G_IO_ERROR ||
3545
error->code != G_IO_ERROR_CANCELLED)
3546
g_warning ("%s", error->message);
3547
g_error_free (error);
3549
data->callback (result,
3551
g_cancellable_is_cancelled (data->cancellable),
3554
g_list_free_full (data->backend_list, g_free);
3555
data->backend_list = NULL;
3556
g_object_unref (source_object);
3557
if (data->cancellable)
3558
g_object_unref (data->cancellable);
3564
if (data->backend_list)
3566
if (!g_cancellable_is_cancelled (data->cancellable))
3568
GVariantBuilder include_scheme_builder;
3570
data->callback (result,
3575
g_variant_builder_init (&include_scheme_builder, G_VARIANT_TYPE ("as"));
3576
g_variant_builder_add (&include_scheme_builder, "s", data->backend_list->data);
3578
g_free (data->backend_list->data);
3579
data->backend_list = g_list_remove_link (data->backend_list, data->backend_list);
3581
g_dbus_connection_call (G_DBUS_CONNECTION (g_object_ref (source_object)),
3586
g_variant_new ("(iiasas)",
3589
&include_scheme_builder,
3591
G_VARIANT_TYPE ("(sa{ss})"),
3592
G_DBUS_CALL_FLAGS_NONE,
3595
get_cups_devices_async_dbus_cb,
3601
data->callback (result,
3606
g_list_free_full (data->backend_list, g_free);
3607
data->backend_list = NULL;
3612
data->callback (result,
3614
g_cancellable_is_cancelled (data->cancellable),
3618
g_object_unref (source_object);
3619
if (data->cancellable)
3620
g_object_unref (data->cancellable);
3625
get_cups_devices_async (GCancellable *cancellable,
3626
GCDCallback callback,
3629
GDBusConnection *bus;
3630
GVariantBuilder include_scheme_builder;
3632
GError *error = NULL;
3634
const gchar *backends[] =
3635
{"hpfax", "ncp", "beh", "bluetooth", "snmp",
3636
"dnssd", "hp", "ipp", "lpd", "parallel",
3637
"serial", "socket", "usb", NULL};
3639
bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
3642
g_warning ("Failed to get system bus: %s", error->message);
3643
g_error_free (error);
3644
callback (NULL, TRUE, FALSE, user_data);
3648
data = g_new0 (GCDData, 1);
3650
data->cancellable = g_object_ref (cancellable);
3651
data->callback = callback;
3652
data->user_data = user_data;
3653
for (i = 0; backends[i]; i++)
3654
data->backend_list = g_list_prepend (data->backend_list, g_strdup (backends[i]));
3656
g_variant_builder_init (&include_scheme_builder, G_VARIANT_TYPE ("as"));
3657
g_variant_builder_add (&include_scheme_builder, "s", data->backend_list->data);
3659
g_free (data->backend_list->data);
3660
data->backend_list = g_list_remove_link (data->backend_list, data->backend_list);
3662
g_dbus_connection_call (bus,
3667
g_variant_new ("(iiasas)",
3670
&include_scheme_builder,
3672
G_VARIANT_TYPE ("(sa{ss})"),
3673
G_DBUS_CALL_FLAGS_NONE,
3676
get_cups_devices_async_dbus_cb,
3681
pp_print_device_free (PpPrintDevice *device)
3685
g_free (device->device_class);
3686
g_free (device->device_id);
3687
g_free (device->device_info);
3688
g_free (device->device_make_and_model);
3689
g_free (device->device_uri);
3690
g_free (device->device_location);
3691
g_free (device->device_name);
3692
g_free (device->device_ppd);
3699
gchar *printer_name;
3704
CGJCallback callback;
3706
GMainContext *context;
3710
cups_get_jobs_idle_cb (gpointer user_data)
3712
CGJData *data = (CGJData *) user_data;
3714
data->callback (data->jobs,
3722
cups_get_jobs_data_free (gpointer user_data)
3724
CGJData *data = (CGJData *) user_data;
3727
g_main_context_unref (data->context);
3728
g_free (data->printer_name);
3733
cups_get_jobs_cb (gpointer user_data)
3735
CGJData *data = (CGJData *) user_data;
3736
GSource *idle_source;
3738
idle_source = g_idle_source_new ();
3739
g_source_set_callback (idle_source,
3740
cups_get_jobs_idle_cb,
3742
cups_get_jobs_data_free);
3743
g_source_attach (idle_source, data->context);
3744
g_source_unref (idle_source);
3748
cups_get_jobs_func (gpointer user_data)
3750
CGJData *data = (CGJData *) user_data;
3752
data->num_of_jobs = cupsGetJobs (&data->jobs,
3754
data->my_jobs ? 1 : 0,
3757
cups_get_jobs_cb (data);
3763
cups_get_jobs_async (const gchar *printer_name,
3766
CGJCallback callback,
3771
GError *error = NULL;
3773
data = g_new0 (CGJData, 1);
3774
data->printer_name = g_strdup (printer_name);
3775
data->my_jobs = my_jobs;
3776
data->which_jobs = which_jobs;
3777
data->callback = callback;
3778
data->user_data = user_data;
3779
data->context = g_main_context_ref_thread_default ();
3781
thread = g_thread_try_new ("cups-get-jobs",
3788
g_warning ("%s", error->message);
3789
callback (NULL, 0, user_data);
3791
g_error_free (error);
3792
cups_get_jobs_data_free (data);
3796
g_thread_unref (thread);
3802
GCancellable *cancellable;
3803
JCPCallback callback;
3808
job_cancel_purge_async_dbus_cb (GObject *source_object,
3813
JCPData *data = (JCPData *) user_data;
3814
GError *error = NULL;
3816
output = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
3819
g_object_unref (source_object);
3823
g_variant_unref (output);
3827
if (!g_cancellable_is_cancelled (data->cancellable))
3828
g_warning ("%s", error->message);
3829
g_error_free (error);
3832
data->callback (data->user_data);
3834
if (data->cancellable)
3835
g_object_unref (data->cancellable);
3840
job_cancel_purge_async (gint job_id,
3842
GCancellable *cancellable,
3843
JCPCallback callback,
3846
GDBusConnection *bus;
3848
GError *error = NULL;
3850
bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
3853
g_warning ("Failed to get session bus: %s", error->message);
3854
g_error_free (error);
3855
callback (user_data);
3859
data = g_new0 (JCPData, 1);
3861
data->cancellable = g_object_ref (cancellable);
3862
data->callback = callback;
3863
data->user_data = user_data;
3865
g_dbus_connection_call (bus,
3870
g_variant_new ("(ib)",
3873
G_VARIANT_TYPE ("(s)"),
3874
G_DBUS_CALL_FLAGS_NONE,
3877
job_cancel_purge_async_dbus_cb,
3883
GCancellable *cancellable;
3884
JSHUCallback callback;
3889
job_set_hold_until_async_dbus_cb (GObject *source_object,
3894
JSHUData *data = (JSHUData *) user_data;
3895
GError *error = NULL;
3897
output = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
3900
g_object_unref (source_object);
3904
g_variant_unref (output);
3908
if (!g_cancellable_is_cancelled (data->cancellable))
3909
g_warning ("%s", error->message);
3910
g_error_free (error);
3913
data->callback (data->user_data);
3915
if (data->cancellable)
3916
g_object_unref (data->cancellable);
3921
job_set_hold_until_async (gint job_id,
3922
const gchar *job_hold_until,
3923
GCancellable *cancellable,
3924
JSHUCallback callback,
3927
GDBusConnection *bus;
3929
GError *error = NULL;
3931
bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
3934
g_warning ("Failed to get session bus: %s", error->message);
3935
g_error_free (error);
3936
callback (user_data);
3940
data = g_new0 (JSHUData, 1);
3942
data->cancellable = g_object_ref (cancellable);
3943
data->callback = callback;
3944
data->user_data = user_data;
3946
g_dbus_connection_call (bus,
3951
g_variant_new ("(is)",
3954
G_VARIANT_TYPE ("(s)"),
3955
G_DBUS_CALL_FLAGS_NONE,
3958
job_set_hold_until_async_dbus_cb,