⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtkprintbackendcups.c

📁 This GTK+ version 2.12.3. GTK+ is a multi-platform toolkit for creating graphical user interfaces.
💻 C
📖 第 1 页 / 共 5 页
字号:
/* GTK - The GIMP Toolkit * gtkprintbackendcups.h: Default implementation of GtkPrintBackend  * for the Common Unix Print System (CUPS) * Copyright (C) 2006, 2007 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#include <config.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <stdlib.h>#include <cups/cups.h>#include <cups/language.h>#include <cups/http.h>#include <cups/ipp.h>#include <errno.h>#include <cairo.h>#include <cairo-pdf.h>#include <cairo-ps.h>#include <glib/gi18n-lib.h>#include <gmodule.h>#include <gtk/gtkprintoperation.h>#include <gtk/gtkprintsettings.h>#include <gtk/gtkprintbackend.h>#include <gtk/gtkprinter.h>#include <gtk/gtkprinter-private.h>#include "gtkprintbackendcups.h"#include "gtkprintercups.h"#include "gtkcupsutils.h"#include "gtkdebug.h"typedef struct _GtkPrintBackendCupsClass GtkPrintBackendCupsClass;#define GTK_PRINT_BACKEND_CUPS_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PRINT_BACKEND_CUPS, GtkPrintBackendCupsClass))#define GTK_IS_PRINT_BACKEND_CUPS_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PRINT_BACKEND_CUPS))#define GTK_PRINT_BACKEND_CUPS_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PRINT_BACKEND_CUPS, GtkPrintBackendCupsClass))#define _CUPS_MAX_ATTEMPTS 10 #define _CUPS_MAX_CHUNK_SIZE 8192/* define this to see warnings about ignored ppd options */#undef PRINT_IGNORED_OPTIONS#define _CUPS_MAP_ATTR_INT(attr, v, a) {if (!g_ascii_strcasecmp (attr->name, (a))) v = attr->values[0].integer;}#define _CUPS_MAP_ATTR_STR(attr, v, a) {if (!g_ascii_strcasecmp (attr->name, (a))) v = attr->values[0].string.text;}static GType print_backend_cups_type = 0;typedef void (* GtkPrintCupsResponseCallbackFunc) (GtkPrintBackend *print_backend,                                                   GtkCupsResult   *result,                                                    gpointer         user_data);typedef enum {  DISPATCH_SETUP,  DISPATCH_REQUEST,  DISPATCH_SEND,  DISPATCH_CHECK,  DISPATCH_READ,  DISPATCH_ERROR} GtkPrintCupsDispatchState;typedef struct {  GSource source;  http_t *http;  GtkCupsRequest *request;  GPollFD *data_poll;  GtkPrintBackendCups *backend;} GtkPrintCupsDispatchWatch;struct _GtkPrintBackendCupsClass{  GtkPrintBackendClass parent_class;};struct _GtkPrintBackendCups{  GtkPrintBackend parent_instance;  char *default_printer;    guint list_printers_poll;  guint list_printers_pending : 1;  guint got_default_printer   : 1;};static GObjectClass *backend_parent_class;static void                 gtk_print_backend_cups_class_init      (GtkPrintBackendCupsClass          *class);static void                 gtk_print_backend_cups_init            (GtkPrintBackendCups               *impl);static void                 gtk_print_backend_cups_finalize        (GObject                           *object);static void                 gtk_print_backend_cups_dispose         (GObject                           *object);static void                 cups_get_printer_list                  (GtkPrintBackend                   *print_backend);static void                 cups_request_execute                   (GtkPrintBackendCups               *print_backend,								    GtkCupsRequest                    *request,								    GtkPrintCupsResponseCallbackFunc   callback,								    gpointer                           user_data,								    GDestroyNotify                     notify);static void                 cups_printer_get_settings_from_options (GtkPrinter                        *printer,								    GtkPrinterOptionSet               *options,								    GtkPrintSettings                  *settings);static gboolean             cups_printer_mark_conflicts            (GtkPrinter                        *printer,								    GtkPrinterOptionSet               *options);static GtkPrinterOptionSet *cups_printer_get_options               (GtkPrinter                        *printer,								    GtkPrintSettings                  *settings,								    GtkPageSetup                      *page_setup,                                                                    GtkPrintCapabilities               capabilities);static void                 cups_printer_prepare_for_print         (GtkPrinter                        *printer,								    GtkPrintJob                       *print_job,								    GtkPrintSettings                  *settings,								    GtkPageSetup                      *page_setup);static GList *              cups_printer_list_papers               (GtkPrinter                        *printer);static void                 cups_printer_request_details           (GtkPrinter                        *printer);static void                 cups_request_default_printer           (GtkPrintBackendCups               *print_backend);static void                 cups_request_ppd                       (GtkPrinter                        *printer);static void                 cups_printer_get_hard_margins          (GtkPrinter                        *printer,								    double                            *top,								    double                            *bottom,								    double                            *left,								    double                            *right);static GtkPrintCapabilities cups_printer_get_capabilities          (GtkPrinter                        *printer);static void                 set_option_from_settings               (GtkPrinterOption                  *option,								    GtkPrintSettings                  *setting);static void                 cups_begin_polling_info                (GtkPrintBackendCups               *print_backend,								    GtkPrintJob                       *job,								    int                                job_id);static gboolean             cups_job_info_poll_timeout             (gpointer                           user_data);static void                 gtk_print_backend_cups_print_stream    (GtkPrintBackend                   *backend,								    GtkPrintJob                       *job,								    GIOChannel                        *data_io,								    GtkPrintJobCompleteFunc            callback,								    gpointer                           user_data,								    GDestroyNotify                     dnotify);static cairo_surface_t *    cups_printer_create_cairo_surface      (GtkPrinter                        *printer,								    GtkPrintSettings                  *settings,								    gdouble                            width,								    gdouble                            height,								    GIOChannel                        *cache_io);static voidgtk_print_backend_cups_register_type (GTypeModule *module){  static const GTypeInfo print_backend_cups_info =  {    sizeof (GtkPrintBackendCupsClass),    NULL,		/* base_init */    NULL,		/* base_finalize */    (GClassInitFunc) gtk_print_backend_cups_class_init,    NULL,		/* class_finalize */    NULL,		/* class_data */    sizeof (GtkPrintBackendCups),    0,	          	/* n_preallocs */    (GInstanceInitFunc) gtk_print_backend_cups_init  };  print_backend_cups_type = g_type_module_register_type (module,                                                         GTK_TYPE_PRINT_BACKEND,                                                         "GtkPrintBackendCups",                                                         &print_backend_cups_info, 0);}G_MODULE_EXPORT void pb_module_init (GTypeModule *module){  GTK_NOTE (PRINTING,            g_print ("CUPS Backend: Initializing the CUPS print backend module\n"));   gtk_print_backend_cups_register_type (module);  gtk_printer_cups_register_type (module);}G_MODULE_EXPORT void pb_module_exit (void){}  G_MODULE_EXPORT GtkPrintBackend * pb_module_create (void){  return gtk_print_backend_cups_new ();}/* * GtkPrintBackendCups */GTypegtk_print_backend_cups_get_type (void){  return print_backend_cups_type;}/** * gtk_print_backend_cups_new: * * Creates a new #GtkPrintBackendCups object. #GtkPrintBackendCups * implements the #GtkPrintBackend interface with direct access to * the filesystem using Unix/Linux API calls * * Return value: the new #GtkPrintBackendCups object */GtkPrintBackend *gtk_print_backend_cups_new (void){  GTK_NOTE (PRINTING,            g_print ("CUPS Backend: Creating a new CUPS print backend object\n"));  return g_object_new (GTK_TYPE_PRINT_BACKEND_CUPS, NULL);}static voidgtk_print_backend_cups_class_init (GtkPrintBackendCupsClass *class){  GObjectClass *gobject_class = G_OBJECT_CLASS (class);  GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_CLASS (class);  backend_parent_class = g_type_class_peek_parent (class);  gobject_class->finalize = gtk_print_backend_cups_finalize;  gobject_class->dispose = gtk_print_backend_cups_dispose;  backend_class->request_printer_list = cups_get_printer_list;   backend_class->print_stream = gtk_print_backend_cups_print_stream;  backend_class->printer_request_details = cups_printer_request_details;  backend_class->printer_create_cairo_surface = cups_printer_create_cairo_surface;  backend_class->printer_get_options = cups_printer_get_options;  backend_class->printer_mark_conflicts = cups_printer_mark_conflicts;  backend_class->printer_get_settings_from_options = cups_printer_get_settings_from_options;  backend_class->printer_prepare_for_print = cups_printer_prepare_for_print;  backend_class->printer_list_papers = cups_printer_list_papers;  backend_class->printer_get_hard_margins = cups_printer_get_hard_margins;  backend_class->printer_get_capabilities = cups_printer_get_capabilities;}static cairo_status_t_cairo_write_to_cups (void                *closure,                      const unsigned char *data,                      unsigned int         length){  GIOChannel *io = (GIOChannel *)closure;  gsize written;  GError *error;  error = NULL;  GTK_NOTE (PRINTING,            g_print ("CUPS Backend: Writing %i byte chunk to temp file\n", length));  while (length > 0)     {      g_io_channel_write_chars (io, (gchar *)data, length, &written, &error);      if (error != NULL)	{	  GTK_NOTE (PRINTING,                    g_print ("CUPS Backend: Error writing to temp file, %s\n",                              error->message));          g_error_free (error);	  return CAIRO_STATUS_WRITE_ERROR;	}          GTK_NOTE (PRINTING,                g_print ("CUPS Backend: Wrote %i bytes to temp file\n", written));      data += written;      length -= written;    }  return CAIRO_STATUS_SUCCESS;}static cairo_surface_t *cups_printer_create_cairo_surface (GtkPrinter       *printer,				   GtkPrintSettings *settings,				   gdouble           width, 				   gdouble           height,				   GIOChannel       *cache_io){  cairo_surface_t *surface;    /* TODO: check if it is a ps or pdf printer */    surface = cairo_ps_surface_create_for_stream  (_cairo_write_to_cups, cache_io, width, height);  /* TODO: DPI from settings object? */  cairo_surface_set_fallback_resolution (surface, 300, 300);  return surface;}typedef struct {  GtkPrintJobCompleteFunc callback;  GtkPrintJob *job;  gpointer user_data;  GDestroyNotify dnotify;} CupsPrintStreamData;static voidcups_free_print_stream_data (CupsPrintStreamData *data){  GTK_NOTE (PRINTING,            g_print ("CUPS Backend: %s\n", G_STRFUNC));  if (data->dnotify)    data->dnotify (data->user_data);  g_object_unref (data->job);  g_free (data);}static voidcups_print_cb (GtkPrintBackendCups *print_backend,               GtkCupsResult       *result,               gpointer             user_data){  GError *error = NULL;  CupsPrintStreamData *ps = user_data;  GDK_THREADS_ENTER ();  GTK_NOTE (PRINTING,            g_print ("CUPS Backend: %s\n", G_STRFUNC));   if (gtk_cups_result_is_error (result))    error = g_error_new_literal (gtk_print_error_quark (),                                 GTK_PRINT_ERROR_INTERNAL_ERROR,                                 gtk_cups_result_get_error_string (result));  if (ps->callback)    ps->callback (ps->job, ps->user_data, error);  if (error == NULL)    {      int job_id = 0;      ipp_attribute_t *attr;		/* IPP job-id attribute */      ipp_t *response = gtk_cups_result_get_response (result);      if ((attr = ippFindAttribute (response, "job-id", IPP_TAG_INTEGER)) != NULL)	job_id = attr->values[0].integer;      if (!gtk_print_job_get_track_print_status (ps->job) || job_id == 0)	gtk_print_job_set_status (ps->job, GTK_PRINT_STATUS_FINISHED);      else	{	  gtk_print_job_set_status (ps->job, GTK_PRINT_STATUS_PENDING);	  cups_begin_polling_info (print_backend, ps->job, job_id);	}    }   else    gtk_print_job_set_status (ps->job, GTK_PRINT_STATUS_FINISHED_ABORTED);    if (error)    g_error_free (error);  GDK_THREADS_LEAVE ();  }static voidadd_cups_options (const gchar *key,		  const gchar *value,		  gpointer     user_data){  GtkCupsRequest *request = user_data;  if (!g_str_has_prefix (key, "cups-"))    return;  if (strcmp (value, "gtk-ignore-value") == 0)    return;    key = key + strlen ("cups-");  gtk_cups_request_encode_option (request, key, value);}static voidgtk_print_backend_cups_print_stream (GtkPrintBackend         *print_backend,                                     GtkPrintJob             *job,				     GIOChannel              *data_io,				     GtkPrintJobCompleteFunc  callback,				     gpointer                 user_data,				     GDestroyNotify           dnotify){  GtkPrinterCups *cups_printer;  CupsPrintStreamData *ps;  GtkCupsRequest *request;  GtkPrintSettings *settings;  const gchar *title;  GTK_NOTE (PRINTING,            g_print ("CUPS Backend: %s\n", G_STRFUNC));     cups_printer = GTK_PRINTER_CUPS (gtk_print_job_get_printer (job));  settings = gtk_print_job_get_settings (job);  request = gtk_cups_request_new (NULL,                                  GTK_CUPS_POST,                                  IPP_PRINT_JOB,				  data_io,				  NULL,				  cups_printer->device_uri);  gtk_cups_request_ipp_add_string (request, IPP_TAG_OPERATION,                                    IPP_TAG_URI, "printer-uri",                                   NULL, cups_printer->printer_uri);  title = gtk_print_job_get_title (job);  if (title)    gtk_cups_request_ipp_add_string (request, IPP_TAG_OPERATION,                                      IPP_TAG_NAME, "job-name",                                      NULL, title);  gtk_print_settings_foreach (settings, add_cups_options, request);    ps = g_new0 (CupsPrintStreamData, 1);  ps->callback = callback;  ps->user_data = user_data;  ps->dnotify = dnotify;  ps->job = g_object_ref (job);  cups_request_execute (GTK_PRINT_BACKEND_CUPS (print_backend),                        request,                        (GtkPrintCupsResponseCallbackFunc) cups_print_cb,                        ps,                        (GDestroyNotify)cups_free_print_stream_data);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -