diff options
-rw-r--r-- | configure.in | 23 | ||||
-rw-r--r-- | gtk/Makefile.am | 8 | ||||
-rw-r--r-- | modules/printbackends/Makefile.am | 4 | ||||
-rw-r--r-- | modules/printbackends/papi/Makefile.am | 32 | ||||
-rw-r--r-- | modules/printbackends/papi/gtkprintbackendpapi.c | 862 | ||||
-rw-r--r-- | modules/printbackends/papi/gtkprintbackendpapi.h | 44 | ||||
-rw-r--r-- | modules/printbackends/papi/gtkprinterpapi.c | 116 | ||||
-rw-r--r-- | modules/printbackends/papi/gtkprinterpapi.h | 61 |
8 files changed, 1150 insertions, 0 deletions
diff --git a/configure.in b/configure.in index 8fc694761..7614ea89d 100644 --- a/configure.in +++ b/configure.in @@ -1879,6 +1879,28 @@ else AM_CONDITIONAL(HAVE_CUPS, false) fi +# Checks to see if we should compile with PAPI backend for GTK+ +# + +AC_ARG_ENABLE(papi, + [AC_HELP_STRING([--disable-papi] + [disable papi print backend])],, + [enable_papi=auto]) + +if test "x$enable_papi" = "xauto" +then + AC_MSG_CHECKING(libpapi) + AC_CHECK_LIB(papi, papiServiceCreate, have_papi=yes, have_papi=no) + if test $have_papi = yes; then + AC_DEFINE([HAVE_PAPI], [], [Define to 1 if libpapi available]) + fi + AM_CONDITIONAL(HAVE_PAPI, test $have_papi = yes) +else + AM_CONDITIONAL(HAVE_PAPI, false) +fi + +AM_CONDITIONAL(HAVE_PAPI_CUPS, test $have_papi = yes && test "x$CUPS_CONFIG" != "xno") + gtk_save_cppflags="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $GTK_DEP_CFLAGS" @@ -2107,6 +2129,7 @@ modules/printbackends/Makefile modules/printbackends/cups/Makefile modules/printbackends/lpr/Makefile modules/printbackends/file/Makefile +modules/printbackends/papi/Makefile modules/printbackends/test/Makefile perf/Makefile contrib/Makefile diff --git a/gtk/Makefile.am b/gtk/Makefile.am index a0dc9a984..d80dc7f56 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -10,11 +10,19 @@ endif SUBDIRS = theme-bits . tests DIST_SUBDIRS=theme-bits tests +if HAVE_PAPI_CUPS +GTK_PRINT_BACKENDS=file,papi,cups +else if HAVE_CUPS GTK_PRINT_BACKENDS=file,cups else +if HAVE_PAPI +GTK_PRINT_BACKENDS=file,papi +else GTK_PRINT_BACKENDS=file,lpr endif +endif +endif INCLUDES = \ -DG_LOG_DOMAIN=\"Gtk\" \ diff --git a/modules/printbackends/Makefile.am b/modules/printbackends/Makefile.am index 11d242385..ec4ad9fc0 100644 --- a/modules/printbackends/Makefile.am +++ b/modules/printbackends/Makefile.am @@ -10,6 +10,10 @@ if TEST_PRINT_BACKEND SUBDIRS += test endif +if HAVE_PAPI +SUBDIRS += papi +endif + DIST_SUBDIRS = cups file lpr test -include $(top_srcdir)/git.mk diff --git a/modules/printbackends/papi/Makefile.am b/modules/printbackends/papi/Makefile.am new file mode 100644 index 000000000..5e5c14489 --- /dev/null +++ b/modules/printbackends/papi/Makefile.am @@ -0,0 +1,32 @@ +if OS_WIN32 +no_undefined = -no-undefined +endif + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_srcdir)/gtk \ + -I$(top_builddir)/gtk \ + -I$(top_srcdir)/gdk \ + -I$(top_builddir)/gdk \ + -DGTK_PRINT_BACKEND_ENABLE_UNSUPPORTED \ + $(GTK_DEP_CFLAGS) \ + $(GTK_DEBUG_FLAGS) + +LDADDS = \ + $(GTK_DEP_LIBS) \ + $(top_builddir)/gtk/$(gtktargetlib) + +backenddir = $(libdir)/gtk-2.0/$(GTK_BINARY_VERSION)/printbackends + +backend_LTLIBRARIES = libprintbackend-papi.la + +libprintbackend_papi_la_SOURCES = \ + gtkprinterpapi.c \ + gtkprintbackendpapi.c + +noinst_HEADERS = \ + gtkprinterpapi.h \ + gtkprintbackendpapi.h + +libprintbackend_papi_la_LDFLAGS = -avoid-version -module $(no_undefined) +libprintbackend_papi_la_LIBADD = $(LDADDS) -lpapi diff --git a/modules/printbackends/papi/gtkprintbackendpapi.c b/modules/printbackends/papi/gtkprintbackendpapi.c new file mode 100644 index 000000000..eb16e1553 --- /dev/null +++ b/modules/printbackends/papi/gtkprintbackendpapi.c @@ -0,0 +1,862 @@ +/* GTK - The GIMP Toolkit + * gtkprintbackendpapi.c: Default implementation of GtkPrintBackend + * for printing to papi + * Copyright (C) 2003, Red Hat, Inc. + * Copyright (C) 2009, Sun Microsystems, 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 <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <papi.h> + +#include <config.h> +#include <errno.h> +#include <cairo.h> +#include <cairo-ps.h> + +#include <glib/gi18n-lib.h> + +#include "gtk.h" +#include "gtkprintbackendpapi.h" +#include "gtkprinterpapi.h" +#include "gtkprinter-private.h" + +typedef struct _GtkPrintBackendPapiClass GtkPrintBackendPapiClass; + +#define GTK_PRINT_BACKEND_PAPI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PRINT_BACKEND_PAPI, GtkPrintBackendPapiClass)) +#define GTK_IS_PRINT_BACKEND_PAPI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PRINT_BACKEND_PAPI)) +#define GTK_PRINT_BACKEND_PAPI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PRINT_BACKEND_PAPI, GtkPrintBackendPapiClass)) + +#define _PAPI_MAX_CHUNK_SIZE 8192 + +static GType print_backend_papi_type = 0; + +struct _GtkPrintBackendPapiClass +{ + GtkPrintBackendClass parent_class; +}; + +struct _GtkPrintBackendPapi +{ + GtkPrintBackend parent_instance; + + char *default_printer; +}; + +typedef struct { + GtkPrinter *printer; +} _PrinterStatus; + +static GObjectClass *backend_parent_class; + +static void gtk_print_backend_papi_class_init (GtkPrintBackendPapiClass *class); +static void gtk_print_backend_papi_init (GtkPrintBackendPapi *impl); +static void gtk_print_backend_papi_finalize (GObject *object); +static void gtk_print_backend_papi_dispose (GObject *object); +static void papi_request_printer_list (GtkPrintBackend *print_backend); +static gboolean papi_get_printer_list (GtkPrintBackendPapi *papi_backend); +static void papi_printer_request_details (GtkPrinter *printer); +static GtkPrintCapabilities papi_printer_get_capabilities (GtkPrinter *printer); +static void papi_printer_get_settings_from_options (GtkPrinter *printer, + GtkPrinterOptionSet *options, + GtkPrintSettings *settings); +static GtkPrinterOptionSet *papi_printer_get_options (GtkPrinter *printer, + GtkPrintSettings *settings, + GtkPageSetup *page_setup, + GtkPrintCapabilities capabilities); +static void papi_printer_prepare_for_print (GtkPrinter *printer, + GtkPrintJob *print_job, + GtkPrintSettings *settings, + GtkPageSetup *page_setup); +static cairo_surface_t * papi_printer_create_cairo_surface (GtkPrinter *printer, + GtkPrintSettings *settings, + gdouble width, + gdouble height, + GIOChannel *cache_io); +static void gtk_print_backend_papi_print_stream (GtkPrintBackend *print_backend, + GtkPrintJob *job, + GIOChannel *data_io, + GtkPrintJobCompleteFunc callback, + gpointer user_data, + GDestroyNotify dnotify); + +static gboolean papi_display_printer_status (gpointer user_data); +static void papi_display_printer_status_done (gpointer user_data); + +static void +gtk_print_backend_papi_register_type (GTypeModule *module) +{ + static const GTypeInfo print_backend_papi_info = + { + sizeof (GtkPrintBackendPapiClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) gtk_print_backend_papi_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GtkPrintBackendPapi), + 0, /* n_preallocs */ + (GInstanceInitFunc) gtk_print_backend_papi_init, + }; + + print_backend_papi_type = g_type_module_register_type (module, + GTK_TYPE_PRINT_BACKEND, + "GtkPrintBackendPapi", + &print_backend_papi_info, 0); +} + +G_MODULE_EXPORT void +pb_module_init (GTypeModule *module) +{ + gtk_print_backend_papi_register_type (module); + gtk_printer_papi_register_type (module); +} + +G_MODULE_EXPORT void +pb_module_exit (void) +{ + +} + +G_MODULE_EXPORT GtkPrintBackend * +pb_module_create (void) +{ + return gtk_print_backend_papi_new (); +} + +/* + * GtkPrintBackendPapi + */ +GType +gtk_print_backend_papi_get_type (void) +{ + return print_backend_papi_type; +} + +/** + * gtk_print_backend_papi_new: + * + * Creates a new #GtkPrintBackendPapi object. #GtkPrintBackendPapi + * implements the #GtkPrintBackend interface with direct access to + * the filesystem using Unix/Linux API calls + * + * Return value: the new #GtkPrintBackendPapi object + **/ +GtkPrintBackend * +gtk_print_backend_papi_new (void) +{ + return g_object_new (GTK_TYPE_PRINT_BACKEND_PAPI, NULL); +} + +static void +gtk_print_backend_papi_class_init (GtkPrintBackendPapiClass *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_papi_finalize; + gobject_class->dispose = gtk_print_backend_papi_dispose; + + backend_class->request_printer_list = papi_request_printer_list; + backend_class->printer_request_details = papi_printer_request_details; + backend_class->printer_get_capabilities = papi_printer_get_capabilities; + backend_class->printer_get_options = papi_printer_get_options; + backend_class->printer_get_settings_from_options = papi_printer_get_settings_from_options; + backend_class->printer_prepare_for_print = papi_printer_prepare_for_print; + backend_class->printer_create_cairo_surface = papi_printer_create_cairo_surface; + backend_class->print_stream = gtk_print_backend_papi_print_stream; +} + +static cairo_status_t +_cairo_write (void *closure, + const unsigned char *data, + unsigned int length) +{ + GIOChannel *io = (GIOChannel *)closure; + gsize written; + GError *error = NULL; + + GTK_NOTE (PRINTING, + g_print ("PAPI Backend: Writting %i byte chunk to temp file\n", length)); + + while (length > 0) + { + g_io_channel_write_chars (io, (char *)data, length, &written, &error); + + if (error != NULL) + { + GTK_NOTE (PRINTING, + g_print ("PAPI Backend: Error writting to temp file, %s\n", error->message)); + + g_error_free (error); + return CAIRO_STATUS_WRITE_ERROR; + } + + GTK_NOTE (PRINTING, + g_print ("PAPI Backend: Wrote %i bytes to temp file\n", written)); + + data += written; + length -= written; + } + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_surface_t * +papi_printer_create_cairo_surface (GtkPrinter *printer, + GtkPrintSettings *settings, + gdouble width, + gdouble height, + GIOChannel *cache_io) +{ + cairo_surface_t *surface; + + surface = cairo_ps_surface_create_for_stream (_cairo_write, cache_io, width, height); + + /* TODO: DPI from settings object? */ + cairo_surface_set_fallback_resolution (surface, 300, 300); + + return surface; +} + +typedef struct { + GtkPrintBackend *backend; + GtkPrintJobCompleteFunc callback; + GtkPrintJob *job; + gpointer user_data; + GDestroyNotify dnotify; + + papi_service_t service; + papi_stream_t stream; +} _PrintStreamData; + +static void +papi_print_cb (GtkPrintBackendPapi *print_backend, + GError *error, + gpointer user_data) +{ + _PrintStreamData *ps = (_PrintStreamData *) user_data; + + if (ps->callback) + ps->callback (ps->job, ps->user_data, error); + + if (ps->dnotify) + ps->dnotify (ps->user_data); + + gtk_print_job_set_status (ps->job, + error ? GTK_PRINT_STATUS_FINISHED_ABORTED + : GTK_PRINT_STATUS_FINISHED); + + if (ps->job) + g_object_unref (ps->job); + + g_free (ps); +} + +static gboolean +papi_write (GIOChannel *source, + GIOCondition con, + gpointer user_data) +{ + gchar buf[_PAPI_MAX_CHUNK_SIZE]; + gsize bytes_read; + GError *error; + GIOStatus status; + _PrintStreamData *ps = (_PrintStreamData *) user_data; + papi_job_t job = NULL; + + error = NULL; + status = g_io_channel_read_chars (source, + buf, + _PAPI_MAX_CHUNK_SIZE, + &bytes_read, + &error); + + /* Keep writing to PAPI input stream while there are data */ + if (status != G_IO_STATUS_ERROR) + { + papiJobStreamWrite (ps->service, ps->stream, buf, bytes_read); + } + + /* Finish reading input stream data. Closing the stream and handle to service */ + if (bytes_read == 0) { + papiJobStreamClose (ps->service, ps->stream, &job); + ps->stream = NULL; + papiJobFree (job); + papiServiceDestroy (ps->service); + ps->service = NULL; + } + + if (error != NULL || status == G_IO_STATUS_EOF) + { + papi_print_cb (GTK_PRINT_BACKEND_PAPI (ps->backend), + error, user_data); + + if (error) + g_error_free (error); + + if (error != NULL) + { + GTK_NOTE (PRINTING, + g_print ("PAPI Backend: %s\n", error->message)); + + g_error_free (error); + } + + return FALSE; + } + + GTK_NOTE (PRINTING, + g_print ("PAPI Backend: Writting %i byte chunk to papi pipe\n", bytes_read)); + + return TRUE; +} + +static void +gtk_print_backend_papi_print_stream (GtkPrintBackend *print_backend, + GtkPrintJob *job, + GIOChannel *data_io, + GtkPrintJobCompleteFunc callback, + gpointer user_data, + GDestroyNotify dnotify) +{ + GError *print_error = NULL; + GtkPrinterPapi *printer; + _PrintStreamData *ps; + GtkPrintSettings *settings; + gint argc; + gint in_fd; + gchar **argv = NULL; + const gchar *title; + char *prtnm = NULL; + GtkPrintDuplex val; + papi_status_t pstatus = NULL; + papi_attribute_t **attrs = NULL; + papi_job_ticket_t *ticket = NULL; + + printer = GTK_PRINTER_PAPI (gtk_print_job_get_printer (job)); + settings = gtk_print_job_get_settings (job); + + /* FIXME - the title should be set as the job-name */ + title = gtk_print_job_get_title (job); + + ps = g_new0 (_PrintStreamData, 1); + ps->callback = callback; + ps->user_data = user_data; + ps->dnotify = dnotify; + ps->job = g_object_ref (job); + ps->service = NULL; + ps->stream = NULL; + + /* This cannot be queried yet with the current API */ + papiAttributeListAddString (&attrs, PAPI_ATTR_EXCL, "document-format", "application/postscript"); + val = gtk_print_settings_get_duplex (settings) ; + if (val == GTK_PRINT_DUPLEX_HORIZONTAL) + papiAttributeListAddString (&attrs, PAPI_ATTR_EXCL, "Duplex", "DuplexNoTumble"); + else if (val == GTK_PRINT_DUPLEX_VERTICAL) + papiAttributeListAddString (&attrs, PAPI_ATTR_EXCL, "Duplex", "DuplexTumble"); + + if (job->num_copies > 1) + { + papiAttributeListAddInteger (&attrs, PAPI_ATTR_EXCL, "copies", job->num_copies); + } + + prtnm = strdup (gtk_printer_get_name (GTK_PRINTER(printer))); + + if (papiServiceCreate (&(ps->service), prtnm, NULL, NULL, NULL, + PAPI_ENCRYPT_NEVER, NULL) != PAPI_OK) + return; + + pstatus = papiJobStreamOpen (ps->service, prtnm, attrs, ticket, &(ps->stream)); + if (pstatus != PAPI_OK) + { + papiServiceDestroy (ps->service); + ps->service = NULL; + return; + } + + /* Everything set up fine, so get ready to wait for input data stream */ + g_io_add_watch (data_io, + G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, + (GIOFunc) papi_write, + ps); +} + + +static void +_papi_set_default_printer (GtkPrintBackendPapi *backend) +{ + char *def_printer = NULL; + char *_default_attr[] = { "printer-name", NULL }; + papi_service_t service = NULL; + papi_printer_t default_printer = NULL; + papi_attribute_t **attrs = NULL; + + if (papiServiceCreate (&service, NULL, NULL, NULL, NULL, PAPI_ENCRYPT_NEVER, + NULL) != PAPI_OK) + return; + + if (papiPrinterQuery (service, "_default", _default_attr, NULL, + &default_printer) == PAPI_OK) + { + if (default_printer != NULL) + { + attrs = papiPrinterGetAttributeList (default_printer); + + if (attrs != NULL) + if (papiAttributeListGetString (attrs, NULL, "printer-name", + &def_printer) == PAPI_OK) + { + backend->default_printer = strdup (def_printer); + } + } + } + + papiPrinterFree (default_printer); + papiServiceDestroy (service); +} + +static void +gtk_print_backend_papi_init (GtkPrintBackendPapi *backend) +{ + _papi_set_default_printer (backend); +} + +static void +gtk_print_backend_papi_finalize (GObject *object) +{ + GtkPrintBackendPapi *backend_papi; + + GTK_NOTE (PRINTING, + g_print ("PAPI Backend: finalizing PAPI backend module\n")); + + backend_papi = GTK_PRINT_BACKEND_PAPI (object); + + g_free (backend_papi->default_printer); + backend_papi->default_printer = NULL; + + backend_parent_class->finalize (object); +} + + +static void +gtk_print_backend_papi_dispose (GObject *object) +{ + GtkPrintBackendPapi *backend_papi; + + GTK_NOTE (PRINTING, + g_print ("PAPI Backend: %s\n", G_STRFUNC)); + + backend_papi = GTK_PRINT_BACKEND_PAPI (object); + + backend_parent_class->dispose (object); +} + +char ** +get_all_list(papi_service_t svc) +{ + papi_status_t status; + papi_printer_t printer = NULL; + char *attr[] = { "member-names", NULL }; + char **names = NULL; + + status = papiPrinterQuery(svc, "_all", attr, NULL, &printer); + if ((status == PAPI_OK) && (printer != NULL)) { + papi_attribute_t **attributes = + papiPrinterGetAttributeList(printer); + if (attributes != NULL) { + void *iter = NULL; + char *member = NULL; + + for (status = papiAttributeListGetString(attributes, + &iter, "member-names", &member); + status == PAPI_OK; + status = papiAttributeListGetString(attributes, + &iter, NULL, &member)) + list_append(&names, strdup(member)); + } + papiPrinterFree(printer); + } + + return (names); +} + +static char ** +get_printers_list(papi_service_t svc) +{ + papi_status_t status; + papi_printer_t *printers = NULL; + char *keys[] = { "printer-name", "printer-uri-supported", NULL }; + char **names = NULL; + + status = papiPrintersList(svc, keys, NULL, &printers); + if ((status == PAPI_OK) && (printers != NULL)) { + int i; + + for (i = 0; printers[i] != NULL; i++) { + papi_attribute_t **attributes = + papiPrinterGetAttributeList(printers[i]); + char *name = NULL; + + (void) papiAttributeListGetString(attributes, NULL, + "printer-name", &name); + if ((name != NULL) && (strcmp(name, "_default") != 0)) + list_append(&names, strdup(name)); + } + papiPrinterListFree(printers); + } + + return (names); +} + +static void +papi_request_printer_list (GtkPrintBackend *backend) +{ + GtkPrintBackendPapi *papi_backend; + + papi_backend = GTK_PRINT_BACKEND_PAPI (backend); + + /* Get the list of printers using papi API */ + papi_get_printer_list (papi_backend); +} + +static gboolean +papi_get_printer_list (GtkPrintBackendPapi *papi_backend) +{ + int i; + const char *attributes[] = /* Attributes we're interested in */ + { + "printer-name", + "printer-uri-supported", + NULL + }; + papi_status_t status, status2; + papi_service_t service = NULL; + char **printers = NULL; + GtkPrinter *printer; + GtkPrinterPapi *papi_printer; + GList *current_printer_list; + GtkPrintBackend *backend = GTK_PRINT_BACKEND (papi_backend); + + if ((status = papiServiceCreate (&service, NULL, NULL, NULL, NULL, + PAPI_ENCRYPT_NEVER, NULL)) != PAPI_OK) + return FALSE; + + if ((printers = get_all_list (service)) == NULL) + { + printers = get_printers_list (service); + } + + if (printers == NULL) + { + papiServiceDestroy (service); + return FALSE; + } + + for (i = 0; printers[i] != NULL; i++) + { + GtkPrinter *printer; + char *name = NULL, *url = NULL; + papi_attribute_t **attrs = NULL; + + printer = gtk_print_backend_find_printer (backend, printers[i]); + + if (!printer) + { + /* skip null printer name just in case */ + if (printers[i] == NULL) + continue; + + /* skip the alias _default and _all printers */ + if (strcmp(printers[i], "_default")==0 || strcmp(printers[i], "_all")==0) + continue; + + papi_printer = gtk_printer_papi_new (printers[i], backend); + printer = GTK_PRINTER (papi_printer); + + /* Only marked default printer to not have details so that + the request_details method will be called at start up + */ + + if (papi_backend->default_printer != NULL) + if (strcmp (printers[i], papi_backend->default_printer)==0) + { + gtk_printer_set_is_default (printer, TRUE); + } + + gtk_printer_set_icon_name (printer, "gtk-print"); + gtk_print_backend_add_printer (backend, printer); + gtk_printer_set_is_active (printer, TRUE); + + /* gtk_printer_set_has_details (printer, TRUE); */ + } + else + g_object_ref (printer); + + if (!gtk_printer_is_active (printer)) + { + gtk_printer_set_is_active (printer, TRUE); + gtk_printer_set_is_new (printer, TRUE); + } + + if (gtk_printer_is_new (printer)) + { + g_signal_emit_by_name (backend, "printer-added", printer); + gtk_printer_set_is_new (printer, FALSE); + } + + g_object_unref (printer); + } + + free (printers); + papiServiceDestroy (service); + + /* To set that the list of printers added is complete */ + gtk_print_backend_set_list_done (backend); + + return TRUE; +} + +static void +update_printer_status (GtkPrinter *printer) +{ + GtkPrintBackend *backend; + GtkPrinterPapi *papi_printer; + gboolean status_changed = FALSE; + + backend = gtk_printer_get_backend (printer); + papi_printer = GTK_PRINTER_PAPI (printer); + + /* if (status_changed) */ + g_signal_emit_by_name (GTK_PRINT_BACKEND (backend), + "printer-status-changed", printer); + +} + + +static GtkPrinterOptionSet * +papi_printer_get_options (GtkPrinter *printer, + GtkPrintSettings *settings, + GtkPageSetup *page_setup, + GtkPrintCapabilities capabilities) +{ + GtkPrinterOptionSet *set; + GtkPrinterOption *option; + int i; + char *print_at[] = { "now", "on-hold" }; + char *n_up[] = {"1"}; + + /* Update the printer status before the printer options are displayed */ + update_printer_status (printer); + + set = gtk_printer_option_set_new (); + + /* non-ppd related settings */ + + /* This maps to number-up-supported in PAPI. FIXME + * number-up-default is the default value. + * number-up-supported is the list of number of able to print per page + */ + option = gtk_printer_option_new ("gtk-n-up", "Pages Per Sheet", GTK_PRINTER_OPTION_TYPE_PICKONE); + gtk_printer_option_choices_from_array (option, G_N_ELEMENTS (n_up), + n_up, n_up); + gtk_printer_option_set (option, "1"); + gtk_printer_option_set_add (set, option); + g_object_unref (option); + + /* This maps to job-priority-supported and job-priority-default in PAPI - FIXME*/ + + /* This relates to job-sheets-supported in PAPI FIXME*/ + + /* This relates to job-hold-until-supported in PAPI */ + option = gtk_printer_option_new ("gtk-print-time", "Print at", GTK_PRINTER_OPTION_TYPE_PICKONE); + gtk_printer_option_choices_from_array (option, G_N_ELEMENTS (print_at), + print_at, print_at); + gtk_printer_option_set (option, "now"); + gtk_printer_option_set_add (set, option); + g_object_unref (option); + + return set; +} + +static void +papi_printer_get_settings_from_options (GtkPrinter *printer, + GtkPrinterOptionSet *options, + GtkPrintSettings *settings) +{ + GtkPrinterOption *option; + + option = gtk_printer_option_set_lookup (options, "gtk-n-up"); + if (option) + gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_NUMBER_UP, option->value); + +} + +static void +papi_printer_prepare_for_print (GtkPrinter *printer, + GtkPrintJob *print_job, + GtkPrintSettings *settings, + GtkPageSetup *page_setup) +{ + GtkPageSet page_set; + double scale; + GtkPaperSize *papersize = NULL; + char *ppd_paper_name; + + print_job->print_pages = gtk_print_settings_get_print_pages (settings); + print_job->page_ranges = NULL; + print_job->num_page_ranges = 0; + + if (print_job->print_pages == GTK_PRINT_PAGES_RANGES) + print_job->page_ranges = + gtk_print_settings_get_page_ranges (settings, + &print_job->num_page_ranges); + + print_job->collate = gtk_print_settings_get_collate (settings); + print_job->reverse = gtk_print_settings_get_reverse (settings); + print_job->num_copies = gtk_print_settings_get_n_copies (settings); + + scale = gtk_print_settings_get_scale (settings); + if (scale != 100.0) + print_job->scale = scale/100.0; + + papersize = gtk_page_setup_get_paper_size (page_setup); + ppd_paper_name = gtk_paper_size_get_ppd_name (papersize); + + page_set = gtk_print_settings_get_page_set (settings); + if (page_set == GTK_PAGE_SET_EVEN) + print_job->page_set = GTK_PAGE_SET_EVEN; + else if (page_set == GTK_PAGE_SET_ODD) + print_job->page_set = GTK_PAGE_SET_ODD; + else + print_job->page_set = GTK_PAGE_SET_ALL; + + print_job->rotate_to_orientation = TRUE; + +} + +gboolean +is_local_printer (gchar *printer_uri) +{ + if (strncmp (printer_uri, "lpsched:", 8) == 0) + return TRUE; + else + return FALSE; +} + +void +merge_ppd_data (papi_attribute_t ***attributes, gchar *ppdfile) +{ + get_ppd_attrs (attributes, ppdfile); +} + + +static void +papi_display_printer_status_done (gpointer user_data) +{ + GtkPrinter *printer = (GtkPrinter *) user_data; + GtkPrinterPapi *papi_printer; + + g_signal_emit_by_name (printer, "details-acquired", TRUE); + papi_printer = GTK_PRINTER_PAPI (printer); + return; +} + +#define IDLE 3 +#define PROCESSING 4 +#define STOPPED 5 +static gboolean +papi_display_printer_status (gpointer user_data) +{ + GtkPrinter *printer = (GtkPrinter *) user_data; + GtkPrinterPapi *papi_printer; + gchar *loc, *printer_uri, *ppdfile; + int state; + papi_service_t service; + papi_attribute_t **attrs = NULL; + papi_printer_t current_printer = NULL; + static int count = 0; + + papi_printer = GTK_PRINTER_PAPI (printer); + if (papiServiceCreate (&service, NULL, NULL, NULL, NULL, PAPI_ENCRYPT_NEVER, + NULL) != PAPI_OK) + return FALSE; + + if (papiPrinterQuery (service, papi_printer->printer_name, NULL, NULL, + ¤t_printer) != PAPI_OK) + { + /* SUN_BRANDING */ + gtk_printer_set_state_message (printer, _("printer offline")); + } + + if (current_printer != NULL) + { + attrs = papiPrinterGetAttributeList (current_printer); + } + + if (papiAttributeListGetString (attrs, NULL, "printer-info", &loc) == PAPI_OK) + { + gtk_printer_set_location (printer, loc); + } + + if (papiAttributeListGetInteger (attrs, NULL, "printer-state", &state) == PAPI_OK) + { + switch (state) + { + /* SUN_BRANDING */ + case IDLE: gtk_printer_set_state_message (printer, _("ready to print")); + break; + /* SUN_BRANDING */ + case PROCESSING: gtk_printer_set_state_message (printer, _("processing job")); + break; + + /* SUN_BRANDING */ + case STOPPED: gtk_printer_set_state_message (printer, _("paused")); + break; + /* SUN_BRANDING */ + default: gtk_printer_set_state_message (printer, _("unknown")); + break; + } + } + + papiPrinterFree (current_printer); + papiServiceDestroy (service); + gtk_printer_set_has_details (printer, TRUE); + + return FALSE; +} + +static void +papi_printer_request_details (GtkPrinter *printer) +{ + g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, papi_display_printer_status, printer, papi_display_printer_status_done); +} + + +static GtkPrintCapabilities +papi_printer_get_capabilities (GtkPrinter *printer) +{ + return GTK_PRINT_CAPABILITY_COPIES | GTK_PRINT_CAPABILITY_PAGE_SET ; +} + diff --git a/modules/printbackends/papi/gtkprintbackendpapi.h b/modules/printbackends/papi/gtkprintbackendpapi.h new file mode 100644 index 000000000..4eba665e0 --- /dev/null +++ b/modules/printbackends/papi/gtkprintbackendpapi.h @@ -0,0 +1,44 @@ +/* GTK - The GIMP Toolkit + * gtkprintbackendpapi.h: Default implementation of GtkPrintBackend + * for printing to papi + * Copyright (C) 2003, Red Hat, Inc. + * Copyright (C) 2009, Sun Microsystems, 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. + */ + +#ifndef __GTK_PRINT_BACKEND_PAPI_H__ +#define __GTK_PRINT_BACKEND_PAPI_H__ + +#include <glib-object.h> +#include "gtkprintbackend.h" + +G_BEGIN_DECLS + +#define GTK_TYPE_PRINT_BACKEND_PAPI (gtk_print_backend_papi_get_type ()) +#define GTK_PRINT_BACKEND_PAPI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PRINT_BACKEND_PAPI, GtkPrintBackendPapi)) +#define GTK_IS_PRINT_BACKEND_PAPI(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PRINT_BACKEND_PAPI)) + +typedef struct _GtkPrintBackendPapi GtkPrintBackendPapi; + +GtkPrintBackend *gtk_print_backend_papi_new (void); +GType gtk_print_backend_papi_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __GTK_PRINT_BACKEND_PAPI_H__ */ + + diff --git a/modules/printbackends/papi/gtkprinterpapi.c b/modules/printbackends/papi/gtkprinterpapi.c new file mode 100644 index 000000000..387bc30be --- /dev/null +++ b/modules/printbackends/papi/gtkprinterpapi.c @@ -0,0 +1,116 @@ +/* GtkPrinterPapi + * Copyright (C) 2006 John (J5) Palmieri <johnp@redhat.com> + * Copyright (C) 2009 Ghee Teo <ghee.teo@sun.com> + * + * 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 "gtkprinterpapi.h" + +static void gtk_printer_papi_init (GtkPrinterPapi *printer); +static void gtk_printer_papi_class_init (GtkPrinterPapiClass *class); +static void gtk_printer_papi_finalize (GObject *object); + +static GtkPrinterClass *gtk_printer_papi_parent_class; +static GType gtk_printer_papi_type = 0; + +void +gtk_printer_papi_register_type (GTypeModule *module) +{ + static const GTypeInfo object_info = + { + sizeof (GtkPrinterPapiClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) gtk_printer_papi_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GtkPrinterPapi), + 0, /* n_preallocs */ + (GInstanceInitFunc) gtk_printer_papi_init, + }; + + gtk_printer_papi_type = g_type_module_register_type (module, + GTK_TYPE_PRINTER, + "GtkPrinterPapi", + &object_info, 0); +} + +GType +gtk_printer_papi_get_type (void) +{ + return gtk_printer_papi_type; +} + +static void +gtk_printer_papi_class_init (GtkPrinterPapiClass *class) +{ + GObjectClass *object_class = (GObjectClass *) class; + + gtk_printer_papi_parent_class = g_type_class_peek_parent (class); + + object_class->finalize = gtk_printer_papi_finalize; +} + +static void +gtk_printer_papi_init (GtkPrinterPapi *printer) +{ + printer->printer_name = NULL; +} + +static void +gtk_printer_papi_finalize (GObject *object) +{ + GtkPrinterPapi *printer; + + g_return_if_fail (object != NULL); + + printer = GTK_PRINTER_PAPI (object); + + g_free(printer->printer_name); + + G_OBJECT_CLASS (gtk_printer_papi_parent_class)->finalize (object); +} + +/** + * gtk_printer_papi_new: + * + * Creates a new #GtkPrinterPapi. + * + * Return value: a new #GtkPrinterPapi + * + * Since: 2.10 + **/ +GtkPrinterPapi * +gtk_printer_papi_new (const char *name, + GtkPrintBackend *backend) +{ + GObject *result; + GtkPrinterPapi *pp; + + result = g_object_new (GTK_TYPE_PRINTER_PAPI, + "name", name, + "backend", backend, + "is-virtual", TRUE, + NULL); + pp = GTK_PRINTER_PAPI(result); + + pp->printer_name = g_strdup (name); + + return (GtkPrinterPapi *) pp; +} + diff --git a/modules/printbackends/papi/gtkprinterpapi.h b/modules/printbackends/papi/gtkprinterpapi.h new file mode 100644 index 000000000..300cf1711 --- /dev/null +++ b/modules/printbackends/papi/gtkprinterpapi.h @@ -0,0 +1,61 @@ +/* GtkPrinterPapi + * Copyright (C) 2006 John (J5) Palmieri <johnp@redhat.com> + * Copyright (C) 2009 Ghee Teo <ghee.teo@sun.com> + * + * 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. + */ +#ifndef __GTK_PRINTER_PAPI_H__ +#define __GTK_PRINTER_PAPI_H__ + +#include <glib.h> +#include <glib-object.h> +#include <papi.h> + +#include "gtkunixprint.h" + +G_BEGIN_DECLS + +#define GTK_TYPE_PRINTER_PAPI (gtk_printer_papi_get_type ()) +#define GTK_PRINTER_PAPI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PRINTER_PAPI, GtkPrinterPapi)) +#define GTK_PRINTER_PAPI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PRINTER_PAPI, GtkPrinterPapiClass)) +#define GTK_IS_PRINTER_PAPI(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PRINTER_PAPI)) +#define GTK_IS_PRINTER_PAPI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PRINTER_PAPI)) +#define GTK_PRINTER_PAPI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PRINTER_PAPI, GtkPrinterPapiClass)) + +typedef struct _GtkPrinterPapi GtkPrinterPapi; +typedef struct _GtkPrinterPapiClass GtkPrinterPapiClass; +typedef struct _GtkPrinterPapiPrivate GtkPrinterPapiPrivate; + +struct _GtkPrinterPapi +{ + GtkPrinter parent_instance; + + gchar *printer_name; +}; + +struct _GtkPrinterPapiClass +{ + GtkPrinterClass parent_class; + +}; + +GType gtk_printer_papi_get_type (void) G_GNUC_CONST; +void gtk_printer_papi_register_type (GTypeModule *module); +GtkPrinterPapi *gtk_printer_papi_new (const char *name, GtkPrintBackend *backend); + +G_END_DECLS + +#endif /* __GTK_PRINTER_PAPI_H__ */ |