Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 467528
Collapse All | Expand All

(-)configure.ac (+6 lines)
Lines 1425-1430 Link Here
1425
      AC_DEFINE(HAVE_CUPS_API_1_2, 1,
1425
      AC_DEFINE(HAVE_CUPS_API_1_2, 1,
1426
                [Define to 1 if CUPS 1.2 API is available])
1426
                [Define to 1 if CUPS 1.2 API is available])
1427
    fi
1427
    fi
1428
    if test $CUPS_API_MAJOR -gt 1 -o \
1429
	    $CUPS_API_MAJOR -eq 1 -a $CUPS_API_MINOR -ge 6; then
1430
      AC_DEFINE(HAVE_CUPS_API_1_6, 1, 
1431
                [Define to 1 if CUPS 1.6 API is available])
1432
1433
    fi
1428
1434
1429
    AC_SUBST(CUPS_API_MAJOR)
1435
    AC_SUBST(CUPS_API_MAJOR)
1430
    AC_SUBST(CUPS_API_MINOR)
1436
    AC_SUBST(CUPS_API_MINOR)
(-)modules/printbackends/cups/gtkcupsutils.c (-6 / +14 lines)
Lines 83-88 Link Here
83
  _get_read_data
83
  _get_read_data
84
};
84
};
85
85
86
#ifndef HAVE_CUPS_API_1_6
87
#define ippSetOperation(ipp_request, ipp_op_id) ipp_request->request.op.operation_id = ipp_op_id
88
#define ippSetRequestId(ipp_request, ipp_rq_id) ipp_request->request.op.request_id = ipp_rq_id
89
#define ippSetState(ipp_request, ipp_state) ipp_request->state = ipp_state
90
#define ippGetString(attr, index, foo) attr->values[index].string.text
91
#define ippGetCount(attr) attr->num_values
92
#endif
93
86
static void
94
static void
87
gtk_cups_result_set_error (GtkCupsResult    *result,
95
gtk_cups_result_set_error (GtkCupsResult    *result,
88
                           GtkCupsErrorType  error_type,
96
                           GtkCupsErrorType  error_type,
Lines 165-172 Link Here
165
  request->data_io = data_io;
173
  request->data_io = data_io;
166
174
167
  request->ipp_request = ippNew ();
175
  request->ipp_request = ippNew ();
168
  request->ipp_request->request.op.operation_id = operation_id;
176
  ippSetOperation (request->ipp_request, operation_id);
169
  request->ipp_request->request.op.request_id = 1;
177
  ippSetRequestId (request->ipp_request, 1);
170
178
171
  language = cupsLangDefault ();
179
  language = cupsLangDefault ();
172
180
Lines 355-362 Link Here
355
                                  name,
363
                                  name,
356
                                  tag);
364
                                  tag);
357
365
358
  if (attribute != NULL && attribute->values != NULL)
366
  if (attribute != NULL && ippGetCount (attribute) > 0)
359
    return attribute->values[0].string.text;
367
      return ippGetString (attribute, 0, NULL);
360
  else
368
  else
361
    return NULL;
369
    return NULL;
362
}
370
}
Lines 734-740 Link Here
734
    request->attempts = 0;
742
    request->attempts = 0;
735
743
736
    request->state = GTK_CUPS_POST_WRITE_REQUEST;
744
    request->state = GTK_CUPS_POST_WRITE_REQUEST;
737
    request->ipp_request->state = IPP_IDLE;
745
    ippSetState (request->ipp_request, IPP_IDLE);
738
}
746
}
739
747
740
static void 
748
static void 
Lines 1227-1233 Link Here
1227
  request->state = GTK_CUPS_GET_CHECK;
1235
  request->state = GTK_CUPS_GET_CHECK;
1228
  request->poll_state = GTK_CUPS_HTTP_READ;
1236
  request->poll_state = GTK_CUPS_HTTP_READ;
1229
  
1237
  
1230
  request->ipp_request->state = IPP_IDLE;
1238
  ippSetState (request->ipp_request, IPP_IDLE);
1231
}
1239
}
1232
1240
1233
static void 
1241
static void 
(-)modules/printbackends/cups/gtkprintbackendcups.c (-334 / +426 lines)
Lines 30-35 Link Here
30
#include <sys/stat.h>
30
#include <sys/stat.h>
31
#include <stdlib.h>
31
#include <stdlib.h>
32
#include <time.h>
32
#include <time.h>
33
/* Cups 1.6 deprecates ppdFindAttr(), ppdFindCustomOption(),
34
 * ppdFirstCustomParam(), and ppdNextCustomParam() among others. This
35
 * turns off the warning so that it will compile.
36
 */
37
#ifdef HAVE_CUPS_API_1_6
38
# define _PPD_DEPRECATED
39
#endif
33
40
34
#include <cups/cups.h>
41
#include <cups/cups.h>
35
#include <cups/language.h>
42
#include <cups/language.h>
Lines 241-247 Link Here
241
{
248
{
242
  return gtk_print_backend_cups_new ();
249
  return gtk_print_backend_cups_new ();
243
}
250
}
244
251
/* CUPS 1.6 Getter/Setter Functions CUPS 1.6 makes private most of the
252
 * IPP structures and enforces access via new getter functions, which
253
 * are unfortunately not available in earlier versions. We define
254
 * below those getter functions as macros for use when building
255
 * against earlier CUPS versions.
256
 */
257
#ifndef HAVE_CUPS_API_1_6
258
#define ippGetOperation(ipp_request) ipp_request->request.op.operation_id
259
#define ippGetInteger(attr, index) attr->values[index].integer
260
#define ippGetBoolean(attr, index) attr->values[index].boolean
261
#define ippGetString(attr, index, foo) attr->values[index].string.text
262
#define ippGetValueTag(attr) attr->value_tag
263
#define ippGetName(attr) attr->name
264
#define ippGetCount(attr) attr->num_values
265
#define ippGetGroupTag(attr) attr->group_tag
266
#endif
245
/*
267
/*
246
 * GtkPrintBackendCups
268
 * GtkPrintBackendCups
247
 */
269
 */
Lines 469-475 Link Here
469
      ipp_t *response = gtk_cups_result_get_response (result);
491
      ipp_t *response = gtk_cups_result_get_response (result);
470
492
471
      if ((attr = ippFindAttribute (response, "job-id", IPP_TAG_INTEGER)) != NULL)
493
      if ((attr = ippFindAttribute (response, "job-id", IPP_TAG_INTEGER)) != NULL)
472
	job_id = attr->values[0].integer;
494
	job_id = ippGetInteger (attr, 0);
473
495
474
      if (!gtk_print_job_get_track_print_status (ps->job) || job_id == 0)
496
      if (!gtk_print_job_get_track_print_status (ps->job) || job_id == 0)
475
	gtk_print_job_set_status (ps->job, GTK_PRINT_STATUS_FINISHED);
497
	gtk_print_job_set_status (ps->job, GTK_PRINT_STATUS_FINISHED);
Lines 862-868 Link Here
862
884
863
      dispatch->backend->authentication_lock = TRUE;
885
      dispatch->backend->authentication_lock = TRUE;
864
886
865
      switch (dispatch->request->ipp_request->request.op.operation_id)
887
      switch (ippGetOperation (dispatch->request->ipp_request))
866
        {
888
        {
867
          case IPP_PRINT_JOB:
889
          case IPP_PRINT_JOB:
868
            if (job_title != NULL && printer_name != NULL)
890
            if (job_title != NULL && printer_name != NULL)
Lines 890-896 Link Here
890
            break;
912
            break;
891
          default:
913
          default:
892
            /* work around gcc warning about 0 not being a value for this enum */
914
            /* work around gcc warning about 0 not being a value for this enum */
893
            if (dispatch->request->ipp_request->request.op.operation_id == 0)
915
            if (ippGetOperation (dispatch->request->ipp_request) == 0)
894
              prompt = g_strdup_printf ( _("Authentication is required to get a file from %s"), hostname);
916
              prompt = g_strdup_printf ( _("Authentication is required to get a file from %s"), hostname);
895
            else
917
            else
896
              prompt = g_strdup_printf ( _("Authentication is required on %s"), hostname);
918
              prompt = g_strdup_printf ( _("Authentication is required on %s"), hostname);
Lines 1478-1487 Link Here
1478
    }
1500
    }
1479
1501
1480
  data->counter++;
1502
  data->counter++;
1481
  
1503
1482
  response = gtk_cups_result_get_response (result);
1504
  response = gtk_cups_result_get_response (result);
1483
1505
1484
  state = 0;
1506
  state = 0;
1507
1508
#ifdef HAVE_CUPS_API_1_6
1509
  attr = ippFindAttribute (response, "job-state", IPP_TAG_INTEGER);
1510
  state = ippGetInteger (attr, 0);
1511
#else
1485
  for (attr = response->attrs; attr != NULL; attr = attr->next) 
1512
  for (attr = response->attrs; attr != NULL; attr = attr->next) 
1486
    {
1513
    {
1487
      if (!attr->name)
1514
      if (!attr->name)
Lines 1489-1495 Link Here
1489
      
1516
      
1490
      _CUPS_MAP_ATTR_INT (attr, state, "job-state");
1517
      _CUPS_MAP_ATTR_INT (attr, state, "job-state");
1491
    }
1518
    }
1492
  
1519
#endif
1520
1493
  done = FALSE;
1521
  done = FALSE;
1494
  switch (state)
1522
  switch (state)
1495
    {
1523
    {
Lines 1613-1618 Link Here
1613
  printer_name = gtk_printer_get_name (printer);
1641
  printer_name = gtk_printer_get_name (printer);
1614
  return g_ascii_strcasecmp (printer_name, find_name);
1642
  return g_ascii_strcasecmp (printer_name, find_name);
1615
}
1643
}
1644
/* Printer messages we're interested in */
1645
static const char * const printer_messages[] =
1646
  {
1647
    "toner-low",
1648
    "toner-empty",
1649
    "developer-low",
1650
    "developer-empty",
1651
    "marker-supply-low",
1652
    "marker-supply-empty",
1653
    "cover-open",
1654
    "door-open",
1655
    "media-low",
1656
    "media-empty",
1657
    "offline",
1658
    "other"
1659
  };
1660
/* Our translatable versions of the printer messages */
1661
static const char * printer_strings[] =
1662
  {
1663
    N_("Printer '%s' is low on toner."),
1664
    N_("Printer '%s' has no toner left."),
1665
    /* Translators: "Developer" like on photo development context */
1666
    N_("Printer '%s' is low on developer."),
1667
    /* Translators: "Developer" like on photo development context */
1668
    N_("Printer '%s' is out of developer."),
1669
    /* Translators: "marker" is one color bin of the printer */
1670
    N_("Printer '%s' is low on at least one marker supply."),
1671
    /* Translators: "marker" is one color bin of the printer */
1672
    N_("Printer '%s' is out of at least one marker supply."),
1673
    N_("The cover is open on printer '%s'."),
1674
    N_("The door is open on printer '%s'."),
1675
    N_("Printer '%s' is low on paper."),
1676
    N_("Printer '%s' is out of paper."),
1677
    N_("Printer '%s' is currently offline."),
1678
    N_("There is a problem on printer '%s'.")
1679
  };
1680
1681
typedef enum
1682
  {
1683
    GTK_PRINTER_STATE_LEVEL_NONE = 0,
1684
    GTK_PRINTER_STATE_LEVEL_INFO = 1,
1685
    GTK_PRINTER_STATE_LEVEL_WARNING = 2,
1686
    GTK_PRINTER_STATE_LEVEL_ERROR = 3
1687
  } PrinterStateLevel;
1688
1689
typedef struct
1690
{
1691
  const gchar *printer_name;
1692
  const gchar *printer_uri;
1693
  const gchar *member_uris;
1694
  const gchar *location;
1695
  const gchar *description;
1696
  const gchar *state_msg;
1697
  const gchar *reason_msg;
1698
  PrinterStateLevel reason_level;
1699
  gint state;
1700
  gint job_count;
1701
  gboolean is_paused;
1702
  gboolean is_accepting_jobs;
1703
  const gchar *default_cover_before;
1704
  const gchar *default_cover_after;
1705
  gboolean default_printer;
1706
  gboolean got_printer_type;
1707
  gboolean remote_printer;
1708
  gchar  **auth_info_required;
1709
} PrinterSetupInfo;
1710
1711
static void
1712
cups_printer_handle_attribute (GtkPrintBackendCups *cups_backend,
1713
			       ipp_attribute_t *attr,
1714
			       PrinterSetupInfo *info)
1715
{
1716
  gint i,j;
1717
1718
  if (strcmp (ippGetName (attr), "printer-name") == 0 &&
1719
      ippGetValueTag (attr) == IPP_TAG_NAME)
1720
    info->printer_name = ippGetString (attr, 0, NULL);
1721
  else if (strcmp (ippGetName (attr), "printer-uri-supported") == 0 &&
1722
	   ippGetValueTag (attr) == IPP_TAG_URI)
1723
    info->printer_uri = ippGetString (attr, 0, NULL);
1724
  else if (strcmp (ippGetName (attr), "member-uris") == 0 &&
1725
	   ippGetValueTag (attr) == IPP_TAG_URI)
1726
    info->member_uris = ippGetString (attr, 0, NULL);
1727
  else if (strcmp (ippGetName (attr), "printer-location") == 0)
1728
    info->location = ippGetString (attr, 0, NULL);
1729
  else if (strcmp (ippGetName (attr), "printer-info") == 0)
1730
    info->description = ippGetString (attr, 0, NULL);
1731
  else if (strcmp (ippGetName (attr), "printer-state-message") == 0)
1732
    info->state_msg = ippGetString (attr, 0, NULL);
1733
  else if (strcmp (ippGetName (attr), "printer-state-reasons") == 0)
1734
    /* Store most important reason to reason_msg and set
1735
       its importance at printer_state_reason_level */
1736
    {
1737
      for (i = 0; i < ippGetCount (attr); i++)
1738
	{
1739
	  gboolean interested_in = FALSE;
1740
	  if (strcmp (ippGetString (attr, i, NULL), "none") == 0)
1741
	    continue;
1742
	  /* Sets is_paused flag for paused printer. */
1743
	  if (strcmp (ippGetString (attr, i, NULL), "paused") == 0)
1744
	    {
1745
	      info->is_paused = TRUE;
1746
	    }
1747
1748
	  for (j = 0; j < G_N_ELEMENTS (printer_messages); j++)
1749
	    if (strncmp (ippGetString (attr, i, NULL), printer_messages[j], strlen (printer_messages[j])) == 0)
1750
	      {
1751
		interested_in = TRUE;
1752
		break;
1753
	      }
1754
1755
	  if (!interested_in)
1756
	    continue;
1757
	  if (g_str_has_suffix (ippGetString (attr, i, NULL), "-report"))
1758
	    {
1759
	      if (info->reason_level <= GTK_PRINTER_STATE_LEVEL_INFO)
1760
		{
1761
		  info->reason_msg = ippGetString (attr, i, NULL);
1762
		  info->reason_level = GTK_PRINTER_STATE_LEVEL_INFO;
1763
		}
1764
	    }
1765
	  else if (g_str_has_suffix (ippGetString (attr, i, NULL), "-warning"))
1766
	    {
1767
	      if (info->reason_level <= GTK_PRINTER_STATE_LEVEL_WARNING)
1768
		{
1769
		  info->reason_msg = ippGetString (attr, i, NULL);
1770
		  info->reason_level = GTK_PRINTER_STATE_LEVEL_WARNING;
1771
		}
1772
	    }
1773
	  else  /* It is error in the case of no suffix. */
1774
	    {
1775
	      info->reason_msg = ippGetString (attr, i, NULL);
1776
	      info->reason_level = GTK_PRINTER_STATE_LEVEL_ERROR;
1777
	    }
1778
	}
1779
    }
1780
  else if (strcmp (ippGetName (attr), "printer-state") == 0)
1781
    info->state = ippGetInteger (attr, 0);
1782
  else if (strcmp (ippGetName (attr), "queued-job-count") == 0)
1783
    info->job_count = ippGetInteger (attr, 0);
1784
  else if (strcmp (ippGetName (attr), "printer-is-accepting-jobs") == 0)
1785
    {
1786
      if (ippGetBoolean (attr, 0) == 1)
1787
	info->is_accepting_jobs = TRUE;
1788
      else
1789
	info->is_accepting_jobs = FALSE;
1790
    }
1791
  else if (strcmp (ippGetName (attr), "job-sheets-supported") == 0)
1792
    {
1793
      if (cups_backend->covers == NULL)
1794
	{
1795
	  cups_backend->number_of_covers = ippGetCount (attr);
1796
	  cups_backend->covers = g_new (char *, cups_backend->number_of_covers + 1);
1797
	  for (i = 0; i < cups_backend->number_of_covers; i++)
1798
	    cups_backend->covers[i] = g_strdup (ippGetString (attr, i, NULL));
1799
	  cups_backend->covers[cups_backend->number_of_covers] = NULL;
1800
	}
1801
    }
1802
  else if (strcmp (ippGetName (attr), "job-sheets-default") == 0)
1803
    {
1804
      if (ippGetCount (attr) == 2)
1805
	{
1806
	  info->default_cover_before = ippGetString (attr, 0, NULL);
1807
	  info->default_cover_after = ippGetString (attr, 1, NULL);
1808
	}
1809
    }
1810
  else if (strcmp (ippGetName (attr), "printer-type") == 0)
1811
    {
1812
      info->got_printer_type = TRUE;
1813
      if (ippGetInteger (attr, 0) & 0x00020000)
1814
	info->default_printer = TRUE;
1815
      else
1816
	info->default_printer = FALSE;
1817
1818
      if (ippGetInteger (attr, 0) & 0x00000002)
1819
	info->remote_printer = TRUE;
1820
      else
1821
	info->remote_printer = FALSE;
1822
    }
1823
  else if (strcmp (ippGetName (attr), "auth-info-required") == 0)
1824
    {
1825
      if (strcmp (ippGetString (attr, 0, NULL), "none") != 0)
1826
	{
1827
	  info->auth_info_required = g_new0 (gchar *, ippGetCount (attr) + 1);
1828
	  for (i = 0; i < ippGetCount (attr); i++)
1829
	    info->auth_info_required[i] = g_strdup (ippGetString (attr, i, NULL));
1830
	}
1831
    }
1832
  else
1833
    {
1834
      GTK_NOTE (PRINTING,
1835
		g_print ("CUPS Backend: Attribute %s ignored", ippGetName (attr)));
1836
    }
1837
1838
}
1839
1840
static GtkPrinter*
1841
cups_create_printer (GtkPrintBackendCups *cups_backend,
1842
		     PrinterSetupInfo *info)
1843
{
1844
  GtkPrinterCups *cups_printer;
1845
  GtkPrinter *printer;
1846
  char uri[HTTP_MAX_URI];	/* Printer URI */
1847
  char method[HTTP_MAX_URI];	/* Method/scheme name */
1848
  char username[HTTP_MAX_URI];	/* Username:password */
1849
  char hostname[HTTP_MAX_URI];	/* Hostname */
1850
  char resource[HTTP_MAX_URI];	/* Resource name */
1851
  int  port;			/* Port number */
1852
  char *cups_server;            /* CUPS server */
1853
  GtkPrintBackend *backend = GTK_PRINT_BACKEND (cups_backend);
1854
1855
#ifdef HAVE_COLORD
1856
  cups_printer = gtk_printer_cups_new (info->printer_name,
1857
				       backend,
1858
				       cups_backend->colord_client);
1859
#else
1860
  cups_printer = gtk_printer_cups_new (info->printer_name, backend, NULL);
1861
#endif
1862
1863
  cups_printer->device_uri = g_strdup_printf ("/printers/%s",
1864
					      info->printer_name);
1865
1866
  /* Check to see if we are looking at a class */
1867
  if (info->member_uris)
1868
    {
1869
      cups_printer->printer_uri = g_strdup (info->member_uris);
1870
      /* TODO if member_uris is a class we need to recursivly find a printer */
1871
      GTK_NOTE (PRINTING,
1872
		g_print ("CUPS Backend: Found class with printer %s\n",
1873
			 info->member_uris));
1874
    }
1875
  else
1876
    {
1877
      cups_printer->printer_uri = g_strdup (info->printer_uri);
1878
      GTK_NOTE (PRINTING,
1879
		g_print ("CUPS Backend: Found printer %s\n", info->printer_uri));
1880
    }
1881
1882
#ifdef HAVE_CUPS_API_1_2
1883
  httpSeparateURI (HTTP_URI_CODING_ALL, cups_printer->printer_uri, 
1884
		   method, sizeof (method), 
1885
		   username, sizeof (username),
1886
		   hostname, sizeof (hostname),
1887
		   &port, 
1888
		   resource, sizeof (resource));
1889
1890
#else
1891
  httpSeparate (cups_printer->printer_uri, 
1892
		method, 
1893
		username, 
1894
		hostname,
1895
		&port, 
1896
		resource);
1897
#endif
1898
1899
  if (strncmp (resource, "/printers/", 10) == 0)
1900
    {
1901
      cups_printer->ppd_name = g_strdup (resource + 10);
1902
      GTK_NOTE (PRINTING,
1903
		g_print ("CUPS Backend: Setting ppd name '%s' for printer/class '%s'\n", cups_printer->ppd_name, info->printer_name));
1904
    }
1905
1906
  gethostname (uri, sizeof (uri));
1907
  cups_server = g_strdup (cupsServer());
1908
1909
  if (strcasecmp (uri, hostname) == 0)
1910
    strcpy (hostname, "localhost");
1911
1912
  /* if the cups server is local and listening at a unix domain socket 
1913
   * then use the socket connection
1914
   */
1915
  if ((strstr (hostname, "localhost") != NULL) &&
1916
      (cups_server[0] == '/'))
1917
    strcpy (hostname, cups_server);
1918
1919
  g_free (cups_server);
1920
1921
  cups_printer->default_cover_before = g_strdup (info->default_cover_before);
1922
  cups_printer->default_cover_after = g_strdup (info->default_cover_after);
1923
1924
  cups_printer->hostname = g_strdup (hostname);
1925
  cups_printer->port = port;
1926
	  
1927
  cups_printer->auth_info_required = g_strdupv (info->auth_info_required);
1928
  g_strfreev (info->auth_info_required);
1929
1930
  printer = GTK_PRINTER (cups_printer);
1931
	  
1932
  if (cups_backend->default_printer != NULL &&
1933
      strcmp (cups_backend->default_printer, gtk_printer_get_name (printer)) == 0)
1934
    gtk_printer_set_is_default (printer, TRUE);
1935
1936
	  
1937
  gtk_print_backend_add_printer (backend, printer);
1938
  return printer;
1939
}
1616
1940
1617
static void
1941
static void
1618
cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend,
1942
cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend,
Lines 1662-1869 Link Here
1662
  removed_printer_checklist = gtk_print_backend_get_printer_list (backend);
1986
  removed_printer_checklist = gtk_print_backend_get_printer_list (backend);
1663
								  
1987
								  
1664
  response = gtk_cups_result_get_response (result);
1988
  response = gtk_cups_result_get_response (result);
1989
#ifdef HAVE_CUPS_API_1_6
1990
  for (attr = ippFirstAttribute (response); attr != NULL;
1991
       attr = ippNextAttribute (response))
1992
    {
1993
      GtkPrinter *printer;
1994
      gboolean status_changed = FALSE;
1995
      GList *node;
1996
      gint i;
1997
      PrinterSetupInfo *info = g_slice_new0 (PrinterSetupInfo);
1665
1998
1999
      /* Skip leading attributes until we hit a printer...
2000
       */
2001
      while (attr != NULL && ippGetGroupTag (attr) != IPP_TAG_PRINTER)
2002
        attr = ippNextAttribute (response);
2003
2004
      if (attr == NULL)
2005
        break;
2006
      while (attr != NULL && ippGetGroupTag (attr) == IPP_TAG_PRINTER)
2007
      {
2008
	cups_printer_handle_attribute (cups_backend, attr, info);
2009
        attr = ippNextAttribute (response);
2010
      }
2011
#else
1666
  for (attr = response->attrs; attr != NULL; attr = attr->next)
2012
  for (attr = response->attrs; attr != NULL; attr = attr->next)
1667
    {
2013
    {
1668
      GtkPrinter *printer;
2014
      GtkPrinter *printer;
1669
      const gchar *printer_name = NULL;
1670
      const gchar *printer_uri = NULL;
1671
      const gchar *member_uris = NULL;
1672
      const gchar *location = NULL;
1673
      const gchar *description = NULL;
1674
      const gchar *state_msg = NULL;
1675
      gint state = 0;
1676
      gint job_count = 0;
1677
      gboolean status_changed = FALSE;
2015
      gboolean status_changed = FALSE;
1678
      GList *node;
2016
      GList *node;
1679
      gint i,j;
2017
      gint i;
1680
      const gchar *reason_msg = NULL;
2018
      PrinterSetupInfo *info = g_slice_new0 (PrinterSetupInfo);
1681
      gchar *reason_msg_desc = NULL;
2019
1682
      gchar *tmp_msg = NULL;
1683
      gchar *tmp_msg2 = NULL;
1684
      gint printer_state_reason_level = 0; /* 0 - none, 1 - report, 2 - warning, 3 - error */
1685
      gboolean interested_in = FALSE;
1686
      gboolean found = FALSE;
1687
      static const char * const reasons[] =	/* Reasons we're interested in */
1688
        {
1689
          "toner-low",
1690
          "toner-empty",
1691
          "developer-low",
1692
          "developer-empty",
1693
          "marker-supply-low",
1694
          "marker-supply-empty",
1695
          "cover-open",
1696
          "door-open",
1697
          "media-low",
1698
          "media-empty",
1699
          "offline",
1700
          "other"
1701
        };
1702
      static const char * reasons_descs[] =
1703
        {
1704
          N_("Printer '%s' is low on toner."),
1705
          N_("Printer '%s' has no toner left."),
1706
          /* Translators: "Developer" like on photo development context */
1707
          N_("Printer '%s' is low on developer."),
1708
          /* Translators: "Developer" like on photo development context */
1709
          N_("Printer '%s' is out of developer."),
1710
          /* Translators: "marker" is one color bin of the printer */
1711
          N_("Printer '%s' is low on at least one marker supply."),
1712
          /* Translators: "marker" is one color bin of the printer */
1713
          N_("Printer '%s' is out of at least one marker supply."),
1714
          N_("The cover is open on printer '%s'."),
1715
          N_("The door is open on printer '%s'."),
1716
          N_("Printer '%s' is low on paper."),
1717
          N_("Printer '%s' is out of paper."),
1718
          N_("Printer '%s' is currently offline."),
1719
          N_("There is a problem on printer '%s'.")
1720
        };
1721
      gboolean is_paused = FALSE;
1722
      gboolean is_accepting_jobs = TRUE;
1723
      gboolean default_printer = FALSE;
1724
      gboolean got_printer_type = FALSE;
1725
      gchar   *default_cover_before = NULL;
1726
      gchar   *default_cover_after = NULL;
1727
      gboolean remote_printer = FALSE;
1728
      gchar  **auth_info_required = NULL;
1729
      
1730
      /* Skip leading attributes until we hit a printer...
2020
      /* Skip leading attributes until we hit a printer...
1731
       */
2021
       */
1732
      while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
2022
      while (attr != NULL && ippGetGroupTag (attr) != IPP_TAG_PRINTER)
1733
        attr = attr->next;
2023
        attr = attr->next;
1734
2024
1735
      if (attr == NULL)
2025
      if (attr == NULL)
1736
        break;
2026
        break;
1737
2027
      while (attr != NULL && ippGetGroupTag (attr) == IPP_TAG_PRINTER)
1738
      while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
1739
      {
2028
      {
1740
        if (strcmp (attr->name, "printer-name") == 0 &&
2029
	cups_printer_handle_attribute (cups_backend, attr, info);
1741
	    attr->value_tag == IPP_TAG_NAME)
1742
	  printer_name = attr->values[0].string.text;
1743
	else if (strcmp (attr->name, "printer-uri-supported") == 0 &&
1744
		 attr->value_tag == IPP_TAG_URI)
1745
	  printer_uri = attr->values[0].string.text;
1746
	else if (strcmp (attr->name, "member-uris") == 0 &&
1747
		 attr->value_tag == IPP_TAG_URI)
1748
	  member_uris = attr->values[0].string.text;
1749
        else if (strcmp (attr->name, "printer-location") == 0)
1750
          location = attr->values[0].string.text;
1751
        else if (strcmp (attr->name, "printer-info") == 0)
1752
          description = attr->values[0].string.text;
1753
        else if (strcmp (attr->name, "printer-state-message") == 0)
1754
          state_msg = attr->values[0].string.text;
1755
        else if (strcmp (attr->name, "printer-state-reasons") == 0)
1756
          /* Store most important reason to reason_msg and set
1757
             its importance at printer_state_reason_level */
1758
          {
1759
            for (i = 0; i < attr->num_values; i++)
1760
              {
1761
                if (strcmp (attr->values[i].string.text, "none") != 0)
1762
                  {
1763
                    /* Sets is_paused flag for paused printer. */
1764
                    if (strcmp (attr->values[i].string.text, "paused") == 0)
1765
                      {
1766
                        is_paused = TRUE;
1767
                      }
1768
1769
                    interested_in = FALSE;
1770
                    for (j = 0; j < G_N_ELEMENTS (reasons); j++)
1771
                        if (strncmp (attr->values[i].string.text, reasons[j], strlen (reasons[j])) == 0)
1772
                          {
1773
                            interested_in = TRUE;
1774
                            break;
1775
                          }
1776
1777
                    if (interested_in)
1778
                      {
1779
                        if (g_str_has_suffix (attr->values[i].string.text, "-report"))
1780
                          {
1781
                            if (printer_state_reason_level <= 1)
1782
                              {
1783
                                reason_msg = attr->values[i].string.text;
1784
                                printer_state_reason_level = 1;
1785
                              }
1786
                          }
1787
                        else if (g_str_has_suffix (attr->values[i].string.text, "-warning"))
1788
                          {
1789
                            if (printer_state_reason_level <= 2)
1790
                              {
1791
                                reason_msg = attr->values[i].string.text;
1792
                                printer_state_reason_level = 2;
1793
                              }
1794
                          }
1795
                        else  /* It is error in the case of no suffix. */
1796
                          {
1797
                            reason_msg = attr->values[i].string.text;
1798
                            printer_state_reason_level = 3;
1799
                          }
1800
                      }
1801
                  }
1802
              }
1803
          }
1804
        else if (strcmp (attr->name, "printer-state") == 0)
1805
          state = attr->values[0].integer;
1806
        else if (strcmp (attr->name, "queued-job-count") == 0)
1807
          job_count = attr->values[0].integer;
1808
        else if (strcmp (attr->name, "printer-is-accepting-jobs") == 0)
1809
          {
1810
            if (attr->values[0].boolean == 1)
1811
              is_accepting_jobs = TRUE;
1812
            else
1813
              is_accepting_jobs = FALSE;
1814
          }
1815
        else if (strcmp (attr->name, "job-sheets-supported") == 0)
1816
          {
1817
            if (cups_backend->covers == NULL)
1818
              {
1819
                cups_backend->number_of_covers = attr->num_values;
1820
                cups_backend->covers = g_new (char *, cups_backend->number_of_covers + 1);
1821
                for (i = 0; i < cups_backend->number_of_covers; i++)
1822
                  cups_backend->covers[i] = g_strdup (attr->values[i].string.text);
1823
                cups_backend->covers[cups_backend->number_of_covers] = NULL;
1824
              }
1825
          }
1826
        else if (strcmp (attr->name, "job-sheets-default") == 0)
1827
          {
1828
            if (attr->num_values == 2)
1829
              {
1830
                default_cover_before = attr->values[0].string.text;
1831
                default_cover_after = attr->values[1].string.text;
1832
              }
1833
          }
1834
        else if (strcmp (attr->name, "printer-type") == 0)
1835
          {
1836
            got_printer_type = TRUE;
1837
            if (attr->values[0].integer & 0x00020000)
1838
              default_printer = TRUE;
1839
            else
1840
              default_printer = FALSE;
1841
1842
            if (attr->values[0].integer & 0x00000002)
1843
              remote_printer = TRUE;
1844
            else
1845
              remote_printer = FALSE;
1846
          }
1847
        else if (strcmp (attr->name, "auth-info-required") == 0)
1848
          {
1849
            if (strcmp (attr->values[0].string.text, "none") != 0)
1850
              {
1851
                auth_info_required = g_new0 (gchar *, attr->num_values + 1);
1852
                for (i = 0; i < attr->num_values; i++)
1853
                  auth_info_required[i] = g_strdup (attr->values[i].string.text);
1854
              }
1855
          }
1856
        else
1857
	  {
1858
	    GTK_NOTE (PRINTING,
1859
                      g_print ("CUPS Backend: Attribute %s ignored", attr->name));
1860
	  }
1861
1862
        attr = attr->next;
2030
        attr = attr->next;
1863
      }
2031
      }
2032
#endif
1864
2033
1865
      if (printer_name == NULL ||
2034
      if (info->printer_name == NULL ||
1866
	  (printer_uri == NULL && member_uris == NULL))
2035
	  (info->printer_uri == NULL && info->member_uris == NULL))
1867
      {
2036
      {
1868
        if (attr == NULL)
2037
        if (attr == NULL)
1869
	  break;
2038
	  break;
Lines 1871-1889 Link Here
1871
          continue;
2040
          continue;
1872
      }
2041
      }
1873
2042
1874
      if (got_printer_type)
2043
      if (info->got_printer_type)
1875
        {
2044
        {
1876
          if (default_printer && !cups_backend->got_default_printer)
2045
          if (info->default_printer && !cups_backend->got_default_printer)
1877
            {
2046
            {
1878
              if (!remote_printer)
2047
              if (!info->remote_printer)
1879
                {
2048
                {
1880
                  cups_backend->got_default_printer = TRUE;
2049
                  cups_backend->got_default_printer = TRUE;
1881
                  cups_backend->default_printer = g_strdup (printer_name);
2050
                  cups_backend->default_printer = g_strdup (info->printer_name);
1882
                }
2051
                }
1883
              else
2052
              else
1884
                {
2053
                {
1885
                  if (remote_default_printer == NULL)
2054
                  if (remote_default_printer == NULL)
1886
                    remote_default_printer = g_strdup (printer_name);
2055
                    remote_default_printer = g_strdup (info->printer_name);
1887
                }
2056
                }
1888
            }
2057
            }
1889
        }
2058
        }
Lines 1894-2004 Link Here
1894
        }
2063
        }
1895
2064
1896
      /* remove name from checklist if it was found */
2065
      /* remove name from checklist if it was found */
1897
      node = g_list_find_custom (removed_printer_checklist, printer_name, (GCompareFunc) find_printer);
2066
      node = g_list_find_custom (removed_printer_checklist,
1898
      removed_printer_checklist = g_list_delete_link (removed_printer_checklist, node);
2067
				 info->printer_name,
2068
				 (GCompareFunc) find_printer);
2069
      removed_printer_checklist = g_list_delete_link (removed_printer_checklist,
2070
						      node);
1899
 
2071
 
1900
      printer = gtk_print_backend_find_printer (backend, printer_name);
2072
      printer = gtk_print_backend_find_printer (backend, info->printer_name);
1901
      if (!printer)
2073
      if (!printer)
1902
        {
2074
	{
1903
	  GtkPrinterCups *cups_printer;
2075
	  printer = cups_create_printer (cups_backend, info);
1904
	  char uri[HTTP_MAX_URI];	/* Printer URI */
2076
	  list_has_changed = TRUE;
1905
	  char method[HTTP_MAX_URI];	/* Method/scheme name */
2077
	}
1906
	  char username[HTTP_MAX_URI];	/* Username:password */
1907
	  char hostname[HTTP_MAX_URI];	/* Hostname */
1908
	  char resource[HTTP_MAX_URI];	/* Resource name */
1909
	  int  port;			/* Port number */
1910
	  char *cups_server;            /* CUPS server */
1911
	  
1912
          list_has_changed = TRUE;
1913
#ifdef HAVE_COLORD
1914
          cups_printer = gtk_printer_cups_new (printer_name,
1915
                                               backend,
1916
                                               cups_backend->colord_client);
1917
#else
1918
          cups_printer = gtk_printer_cups_new (printer_name, backend, NULL);
1919
#endif
1920
1921
	  cups_printer->device_uri = g_strdup_printf ("/printers/%s", printer_name);
1922
1923
          /* Check to see if we are looking at a class */
1924
	  if (member_uris)
1925
	    {
1926
	      cups_printer->printer_uri = g_strdup (member_uris);
1927
	      /* TODO if member_uris is a class we need to recursivly find a printer */
1928
	      GTK_NOTE (PRINTING,
1929
                        g_print ("CUPS Backend: Found class with printer %s\n", member_uris));
1930
	    }
1931
	  else
1932
	    {
1933
	      cups_printer->printer_uri = g_strdup (printer_uri);
1934
              GTK_NOTE (PRINTING,
1935
                        g_print ("CUPS Backend: Found printer %s\n", printer_uri));
1936
            }
1937
1938
#if (CUPS_VERSION_MAJOR == 1 && CUPS_VERSION_MINOR >= 2) || CUPS_VERSION_MAJOR > 1
1939
	  httpSeparateURI (HTTP_URI_CODING_ALL, cups_printer->printer_uri, 
1940
			   method, sizeof (method), 
1941
			   username, sizeof (username),
1942
			   hostname, sizeof (hostname),
1943
			   &port, 
1944
			   resource, sizeof (resource));
1945
1946
#else
1947
	  httpSeparate (cups_printer->printer_uri, 
1948
			method, 
1949
			username, 
1950
			hostname,
1951
			&port, 
1952
			resource);
1953
#endif
1954
1955
          if (strncmp (resource, "/printers/", 10) == 0)
1956
	    {
1957
	      cups_printer->ppd_name = g_strdup (resource + 10);
1958
              GTK_NOTE (PRINTING,
1959
                        g_print ("CUPS Backend: Setting ppd name '%s' for printer/class '%s'\n", cups_printer->ppd_name, printer_name));
1960
            }
1961
1962
	  gethostname (uri, sizeof (uri));
1963
	  cups_server = g_strdup (cupsServer());
1964
1965
	  if (strcasecmp (uri, hostname) == 0)
1966
	    strcpy (hostname, "localhost");
1967
1968
          /* if the cups server is local and listening at a unix domain socket 
1969
           * then use the socket connection
1970
           */
1971
	  if ((strstr (hostname, "localhost") != NULL) &&
1972
	      (cups_server[0] == '/'))
1973
	    strcpy (hostname, cups_server);
1974
1975
	  g_free (cups_server);
1976
1977
          cups_printer->default_cover_before = g_strdup (default_cover_before);
1978
          cups_printer->default_cover_after = g_strdup (default_cover_after);
1979
1980
	  cups_printer->hostname = g_strdup (hostname);
1981
	  cups_printer->port = port;
1982
	  
1983
          cups_printer->auth_info_required = g_strdupv (auth_info_required);
1984
          g_strfreev (auth_info_required);
1985
1986
	  printer = GTK_PRINTER (cups_printer);
1987
	  
1988
	  if (cups_backend->default_printer != NULL &&
1989
	      strcmp (cups_backend->default_printer, gtk_printer_get_name (printer)) == 0)
1990
	    gtk_printer_set_is_default (printer, TRUE);
1991
1992
	  
1993
	  gtk_print_backend_add_printer (backend, printer);
1994
        }
1995
      else
2078
      else
1996
	g_object_ref (printer);
2079
	g_object_ref (printer);
1997
2080
1998
      GTK_PRINTER_CUPS (printer)->remote = remote_printer;
2081
      GTK_PRINTER_CUPS (printer)->remote = info->remote_printer;
1999
2082
2000
      gtk_printer_set_is_paused (printer, is_paused);
2083
      gtk_printer_set_is_paused (printer, info->is_paused);
2001
      gtk_printer_set_is_accepting_jobs (printer, is_accepting_jobs);
2084
      gtk_printer_set_is_accepting_jobs (printer, info->is_accepting_jobs);
2002
2085
2003
      if (!gtk_printer_is_active (printer))
2086
      if (!gtk_printer_is_active (printer))
2004
        {
2087
        {
Lines 2021-2092 Link Here
2021
      cups_request_printer_info (cups_backend, gtk_printer_get_name (printer));
2104
      cups_request_printer_info (cups_backend, gtk_printer_get_name (printer));
2022
#endif
2105
#endif
2023
2106
2024
      GTK_PRINTER_CUPS (printer)->state = state;
2107
      GTK_PRINTER_CUPS (printer)->state = info->state;
2025
      status_changed = gtk_printer_set_job_count (printer, job_count);
2108
      status_changed = gtk_printer_set_job_count (printer, info->job_count);
2026
      status_changed |= gtk_printer_set_location (printer, location);
2109
      status_changed |= gtk_printer_set_location (printer, info->location);
2027
      status_changed |= gtk_printer_set_description (printer, description);
2110
      status_changed |= gtk_printer_set_description (printer,
2028
2111
						     info->description);
2029
      if (state_msg != NULL && strlen (state_msg) == 0)
2112
2030
        {
2113
      if (info->state_msg != NULL && strlen (info->state_msg) == 0)
2031
          if (is_paused && !is_accepting_jobs)
2114
        {
2032
		  /* Translators: this is a printer status. */
2115
	  gchar *tmp_msg2 = NULL;
2116
	  if (info->is_paused && !info->is_accepting_jobs)
2117
	    /* Translators: this is a printer status. */
2033
            tmp_msg2 = g_strdup ( N_("Paused ; Rejecting Jobs"));
2118
            tmp_msg2 = g_strdup ( N_("Paused ; Rejecting Jobs"));
2034
          if (is_paused && is_accepting_jobs)
2119
          if (info->is_paused && info->is_accepting_jobs)
2035
		  /* Translators: this is a printer status. */
2120
	    /* Translators: this is a printer status. */
2036
            tmp_msg2 = g_strdup ( N_("Paused"));
2121
            tmp_msg2 = g_strdup ( N_("Paused"));
2037
          if (!is_paused && !is_accepting_jobs)
2122
          if (!info->is_paused && !info->is_accepting_jobs)
2038
		  /* Translators: this is a printer status. */
2123
	    /* Translators: this is a printer status. */
2039
            tmp_msg2 = g_strdup ( N_("Rejecting Jobs"));
2124
            tmp_msg2 = g_strdup ( N_("Rejecting Jobs"));
2040
2125
2041
          if (tmp_msg2 != NULL)
2126
          if (tmp_msg2 != NULL)
2042
            state_msg = tmp_msg2;
2127
	    {
2043
        }
2128
	      info->state_msg = tmp_msg2;
2129
	      g_free (tmp_msg2);
2130
	    }
2131
	}
2044
2132
2045
      /* Set description of the reason and combine it with printer-state-message. */
2133
      /* Set description of the reason and combine it with printer-state-message. */
2046
      if ( (reason_msg != NULL))
2134
      if ( (info->reason_msg != NULL))
2047
        {
2135
        {
2048
          for (i = 0; i < G_N_ELEMENTS (reasons); i++)
2136
	  gchar *reason_msg_desc = NULL;
2137
	  gboolean found = FALSE;
2138
2139
          for (i = 0; i < G_N_ELEMENTS (printer_messages); i++)
2049
            {
2140
            {
2050
              if (strncmp (reason_msg, reasons[i], strlen (reasons[i])) == 0)
2141
              if (strncmp (info->reason_msg, printer_messages[i],
2142
			   strlen (printer_messages[i])) == 0)
2051
                {
2143
                {
2052
                  reason_msg_desc = g_strdup_printf (reasons_descs[i], printer_name);
2144
                  reason_msg_desc = g_strdup_printf (printer_strings[i],
2145
						     info->printer_name);
2053
                  found = TRUE;
2146
                  found = TRUE;
2054
                  break;
2147
                  break;
2055
                }
2148
                }
2056
            }
2149
            }
2057
2150
2058
          if (!found)
2151
          if (!found)
2059
            printer_state_reason_level = 0;
2152
            info->reason_level = GTK_PRINTER_STATE_LEVEL_NONE;
2060
2153
2061
          if (printer_state_reason_level >= 2)
2154
          if (info->reason_level >= GTK_PRINTER_STATE_LEVEL_WARNING)
2062
            {
2155
            {
2063
              if (strlen (state_msg) == 0)
2156
              if (strlen (info->state_msg) == 0)
2064
                state_msg = reason_msg_desc;
2157
                info->state_msg = reason_msg_desc;
2065
              else
2158
              else
2066
                {
2159
                {
2067
                  tmp_msg = g_strjoin (" ; ", state_msg, reason_msg_desc, NULL);
2160
		  gchar *tmp_msg = NULL;
2068
                  state_msg = tmp_msg;
2161
		  tmp_msg = g_strjoin (" ; ", info->state_msg,
2162
				       reason_msg_desc, NULL);
2163
                  info->state_msg = tmp_msg;
2164
		  g_free (tmp_msg);
2069
                }
2165
                }
2070
            }
2166
            }
2167
	  if (reason_msg_desc != NULL)
2168
	    g_free (reason_msg_desc);
2071
        }
2169
        }
2072
2170
2073
      status_changed |= gtk_printer_set_state_message (printer, state_msg);
2171
      status_changed |= gtk_printer_set_state_message (printer, info->state_msg);
2074
      status_changed |= gtk_printer_set_is_accepting_jobs (printer, is_accepting_jobs);
2172
      status_changed |= gtk_printer_set_is_accepting_jobs (printer, info->is_accepting_jobs);
2075
2076
      if (tmp_msg != NULL)
2077
        g_free (tmp_msg);
2078
2173
2079
      if (tmp_msg2 != NULL)
2080
        g_free (tmp_msg2);
2081
2174
2082
      if (reason_msg_desc != NULL)
2083
        g_free (reason_msg_desc);
2084
2175
2085
      /* Set printer icon according to importance
2176
      /* Set printer icon according to importance
2086
         (none, report, warning, error - report is omitted). */
2177
         (none, report, warning, error - report is omitted). */
2087
      if (printer_state_reason_level == 3)
2178
      if (info->reason_level == GTK_PRINTER_STATE_LEVEL_ERROR)
2088
        gtk_printer_set_icon_name (printer, "printer-error");
2179
        gtk_printer_set_icon_name (printer, "printer-error");
2089
      else if (printer_state_reason_level == 2)
2180
      else if (info->reason_level == GTK_PRINTER_STATE_LEVEL_WARNING)
2090
        gtk_printer_set_icon_name (printer, "printer-warning");
2181
        gtk_printer_set_icon_name (printer, "printer-warning");
2091
      else if (gtk_printer_is_paused (printer))
2182
      else if (gtk_printer_is_paused (printer))
2092
        gtk_printer_set_icon_name (printer, "printer-paused");
2183
        gtk_printer_set_icon_name (printer, "printer-paused");
Lines 2099-2105 Link Here
2099
2190
2100
      /* The ref is held by GtkPrintBackend, in add_printer() */
2191
      /* The ref is held by GtkPrintBackend, in add_printer() */
2101
      g_object_unref (printer);
2192
      g_object_unref (printer);
2102
      
2193
      g_slice_free (PrinterSetupInfo, info);
2194
2103
      if (attr == NULL)
2195
      if (attr == NULL)
2104
        break;
2196
        break;
2105
    }
2197
    }
Lines 2672-2678 Link Here
2672
  response = gtk_cups_result_get_response (result);
2764
  response = gtk_cups_result_get_response (result);
2673
  
2765
  
2674
  if ((attr = ippFindAttribute (response, "printer-name", IPP_TAG_NAME)) != NULL)
2766
  if ((attr = ippFindAttribute (response, "printer-name", IPP_TAG_NAME)) != NULL)
2675
    print_backend->default_printer = g_strdup (attr->values[0].string.text);
2767
      print_backend->default_printer = g_strdup (ippGetString (attr, 0, NULL));
2676
2768
2677
  print_backend->got_default_printer = TRUE;
2769
  print_backend->got_default_printer = TRUE;
2678
2770

Return to bug 467528