forked from AuroraMiddleware/gtk
Added new symbols
2006-05-04 Alexander Larsson <alexl@redhat.com> * gtk/gtk.symbols: Added new symbols * gtk/gtkpagesetupunixdialog.c: * gtk/gtkprintunixdialog.c: Destroy backends when finalizing dialogs. Fix printer leak in selected_printer_changed. * gtk/gtkprintbackend.[ch]: Convert from interface to baseclass. Move printer hashtable here so that the baseclass can handle the slightly complicated ownership model. Add gtk_print_backend_destroy which runs the dispose method, causing the ref-cycles between the backend and its printers to be broken. Add gtk_print_backend_unref_at_idle(). * gtk/gtkprinter.[ch]: GtkPrinter objects now ref their backend so that its always availible, since its needed for the printer object to work. This causes a reference-cycle that is broken using gtk_print_backend_destroy. Add gtk_printer_compare. * gtk/gtkprintoperation-private.h: * gtk/gtkprintoperation-unix.c: * gtk/gtkprintoperation.c: Implement !show_dialog for unix. Make sure the print data is fully spooled before returning from a sync run_dialog. * modules/printbackends/cups/gtkcupsutils.[ch]: Add gtk_cups_request_ipp_add_strings * modules/printbackends/cups/gtkprintbackendcups.c: * modules/printbackends/cups/gtkprintercups.c: * modules/printbackends/lpr/gtkprintbackendlpr.c: * modules/printbackends/pdf/gtkprintbackendpdf.c: Convert backends to derive instead of implementing interface. Move common code into baseclass. CUPS: Remove the printer polling in dispose, not finalize. In the cups watch, remove the backend at idle instead of immediately, since the unref can cause the module to be unloaded. Limit the number of printer attributes requested Get printer uri in initial printer listing so that we can use the printer object immediately. * tests/Makefile.am: * tests/testnouiprint.c: Add testcase for !show_dialog.
This commit is contained in:
parent
89b5cb6480
commit
c36d8f3cb3
55
ChangeLog
55
ChangeLog
@ -1,3 +1,58 @@
|
||||
2006-05-04 Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
* gtk/gtk.symbols:
|
||||
Added new symbols
|
||||
|
||||
* gtk/gtkpagesetupunixdialog.c:
|
||||
* gtk/gtkprintunixdialog.c:
|
||||
Destroy backends when finalizing dialogs.
|
||||
Fix printer leak in selected_printer_changed.
|
||||
|
||||
* gtk/gtkprintbackend.[ch]:
|
||||
Convert from interface to baseclass.
|
||||
Move printer hashtable here so that the baseclass can handle
|
||||
the slightly complicated ownership model.
|
||||
Add gtk_print_backend_destroy which runs the dispose method,
|
||||
causing the ref-cycles between the backend and its printers
|
||||
to be broken.
|
||||
Add gtk_print_backend_unref_at_idle().
|
||||
|
||||
* gtk/gtkprinter.[ch]:
|
||||
GtkPrinter objects now ref their backend so that its always
|
||||
availible, since its needed for the printer object to work.
|
||||
This causes a reference-cycle that is broken using
|
||||
gtk_print_backend_destroy.
|
||||
Add gtk_printer_compare.
|
||||
|
||||
* gtk/gtkprintoperation-private.h:
|
||||
* gtk/gtkprintoperation-unix.c:
|
||||
* gtk/gtkprintoperation.c:
|
||||
Implement !show_dialog for unix.
|
||||
Make sure the print data is fully spooled before returning
|
||||
from a sync run_dialog.
|
||||
|
||||
|
||||
* modules/printbackends/cups/gtkcupsutils.[ch]:
|
||||
Add gtk_cups_request_ipp_add_strings
|
||||
|
||||
* modules/printbackends/cups/gtkprintbackendcups.c:
|
||||
* modules/printbackends/cups/gtkprintercups.c:
|
||||
* modules/printbackends/lpr/gtkprintbackendlpr.c:
|
||||
* modules/printbackends/pdf/gtkprintbackendpdf.c:
|
||||
Convert backends to derive instead of implementing interface.
|
||||
Move common code into baseclass.
|
||||
CUPS:
|
||||
Remove the printer polling in dispose, not finalize.
|
||||
In the cups watch, remove the backend at idle instead of
|
||||
immediately, since the unref can cause the module to be unloaded.
|
||||
Limit the number of printer attributes requested
|
||||
Get printer uri in initial printer listing so that we can use
|
||||
the printer object immediately.
|
||||
|
||||
* tests/Makefile.am:
|
||||
* tests/testnouiprint.c:
|
||||
Add testcase for !show_dialog.
|
||||
|
||||
2006-05-04 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* gtk/gtk.symbols:
|
||||
|
@ -1,3 +1,58 @@
|
||||
2006-05-04 Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
* gtk/gtk.symbols:
|
||||
Added new symbols
|
||||
|
||||
* gtk/gtkpagesetupunixdialog.c:
|
||||
* gtk/gtkprintunixdialog.c:
|
||||
Destroy backends when finalizing dialogs.
|
||||
Fix printer leak in selected_printer_changed.
|
||||
|
||||
* gtk/gtkprintbackend.[ch]:
|
||||
Convert from interface to baseclass.
|
||||
Move printer hashtable here so that the baseclass can handle
|
||||
the slightly complicated ownership model.
|
||||
Add gtk_print_backend_destroy which runs the dispose method,
|
||||
causing the ref-cycles between the backend and its printers
|
||||
to be broken.
|
||||
Add gtk_print_backend_unref_at_idle().
|
||||
|
||||
* gtk/gtkprinter.[ch]:
|
||||
GtkPrinter objects now ref their backend so that its always
|
||||
availible, since its needed for the printer object to work.
|
||||
This causes a reference-cycle that is broken using
|
||||
gtk_print_backend_destroy.
|
||||
Add gtk_printer_compare.
|
||||
|
||||
* gtk/gtkprintoperation-private.h:
|
||||
* gtk/gtkprintoperation-unix.c:
|
||||
* gtk/gtkprintoperation.c:
|
||||
Implement !show_dialog for unix.
|
||||
Make sure the print data is fully spooled before returning
|
||||
from a sync run_dialog.
|
||||
|
||||
|
||||
* modules/printbackends/cups/gtkcupsutils.[ch]:
|
||||
Add gtk_cups_request_ipp_add_strings
|
||||
|
||||
* modules/printbackends/cups/gtkprintbackendcups.c:
|
||||
* modules/printbackends/cups/gtkprintercups.c:
|
||||
* modules/printbackends/lpr/gtkprintbackendlpr.c:
|
||||
* modules/printbackends/pdf/gtkprintbackendpdf.c:
|
||||
Convert backends to derive instead of implementing interface.
|
||||
Move common code into baseclass.
|
||||
CUPS:
|
||||
Remove the printer polling in dispose, not finalize.
|
||||
In the cups watch, remove the backend at idle instead of
|
||||
immediately, since the unref can cause the module to be unloaded.
|
||||
Limit the number of printer attributes requested
|
||||
Get printer uri in initial printer listing so that we can use
|
||||
the printer object immediately.
|
||||
|
||||
* tests/Makefile.am:
|
||||
* tests/testnouiprint.c:
|
||||
Add testcase for !show_dialog.
|
||||
|
||||
2006-05-04 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* gtk/gtk.symbols:
|
||||
|
@ -2550,9 +2550,11 @@ gtk_paper_size_get_default
|
||||
gtk_print_backend_error_quark
|
||||
gtk_print_backend_get_type G_GNUC_CONST
|
||||
gtk_print_backend_get_printer_list
|
||||
gtk_print_backend_printer_list_is_done
|
||||
gtk_print_backend_find_printer
|
||||
gtk_print_backend_print_stream
|
||||
gtk_print_backend_load_modules
|
||||
gtk_print_backend_unref_at_idle
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
@ -110,6 +110,17 @@ static void populate_dialog (GtkPageSetupUnixDialog *dialog
|
||||
static void fill_paper_sizes_from_printer (GtkPageSetupUnixDialog *dialog,
|
||||
GtkPrinter *printer);
|
||||
static void run_custom_paper_dialog (GtkPageSetupUnixDialog *dialog);
|
||||
static void printer_added_cb (GtkPrintBackend *backend,
|
||||
GtkPrinter *printer,
|
||||
GtkPageSetupUnixDialog *dialog);
|
||||
static void printer_removed_cb (GtkPrintBackend *backend,
|
||||
GtkPrinter *printer,
|
||||
GtkPageSetupUnixDialog *dialog);
|
||||
static void printer_status_cb (GtkPrintBackend *backend,
|
||||
GtkPrinter *printer,
|
||||
GtkPageSetupUnixDialog *dialog);
|
||||
|
||||
|
||||
|
||||
static const char * const common_paper_sizes[] = {
|
||||
"na_letter",
|
||||
@ -369,7 +380,9 @@ gtk_page_setup_unix_dialog_finalize (GObject *object)
|
||||
{
|
||||
GtkPageSetupUnixDialog *dialog = GTK_PAGE_SETUP_UNIX_DIALOG (object);
|
||||
GtkPageSetupUnixDialogPrivate *priv = dialog->priv;
|
||||
|
||||
GtkPrintBackend *backend;
|
||||
GList *node;
|
||||
|
||||
if (priv->request_details_tag)
|
||||
{
|
||||
g_source_remove (priv->request_details_tag);
|
||||
@ -397,6 +410,21 @@ gtk_page_setup_unix_dialog_finalize (GObject *object)
|
||||
g_free (priv->waiting_for_printer);
|
||||
priv->waiting_for_printer = NULL;
|
||||
|
||||
for (node = priv->print_backends; node != NULL; node = node->next)
|
||||
{
|
||||
backend = GTK_PRINT_BACKEND (node->data);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (backend, printer_added_cb, dialog);
|
||||
g_signal_handlers_disconnect_by_func (backend, printer_removed_cb, dialog);
|
||||
g_signal_handlers_disconnect_by_func (backend, printer_status_cb, dialog);
|
||||
|
||||
gtk_print_backend_destroy (backend);
|
||||
g_object_unref (backend);
|
||||
}
|
||||
|
||||
g_list_free (priv->print_backends);
|
||||
priv->print_backends = NULL;
|
||||
|
||||
G_OBJECT_CLASS (gtk_page_setup_unix_dialog_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,30 @@
|
||||
#include "gtkprintbackend.h"
|
||||
#include "gtkalias.h"
|
||||
|
||||
static void gtk_print_backend_base_init (gpointer g_class);
|
||||
#define GTK_PRINT_BACKEND_GET_PRIVATE(o) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_PRINT_BACKEND, GtkPrintBackendPrivate))
|
||||
|
||||
static void gtk_print_backend_dispose (GObject *object);
|
||||
|
||||
struct _GtkPrintBackendPrivate
|
||||
{
|
||||
GHashTable *printers;
|
||||
guint printer_list_requested : 1;
|
||||
guint printer_list_done : 1;
|
||||
};
|
||||
|
||||
enum {
|
||||
PRINTER_LIST_CHANGED,
|
||||
PRINTER_LIST_DONE,
|
||||
PRINTER_ADDED,
|
||||
PRINTER_REMOVED,
|
||||
PRINTER_STATUS_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static GObjectClass *backend_parent_class;
|
||||
|
||||
GQuark
|
||||
gtk_print_backend_error_quark (void)
|
||||
@ -142,7 +165,7 @@ _gtk_print_backend_module_class_init (GtkPrintBackendModuleClass *class)
|
||||
{
|
||||
GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
||||
|
||||
|
||||
module_class->load = gtk_print_backend_module_load;
|
||||
module_class->unload = gtk_print_backend_module_unload;
|
||||
|
||||
@ -272,107 +295,255 @@ gtk_print_backend_load_modules ()
|
||||
/*****************************************
|
||||
* GtkPrintBackend *
|
||||
*****************************************/
|
||||
GType
|
||||
gtk_print_backend_get_type (void)
|
||||
{
|
||||
static GType print_backend_type = 0;
|
||||
|
||||
if (!print_backend_type)
|
||||
{
|
||||
static const GTypeInfo print_backend_info =
|
||||
{
|
||||
sizeof (GtkPrintBackendIface), /* class_size */
|
||||
gtk_print_backend_base_init, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
};
|
||||
|
||||
print_backend_type = g_type_register_static (G_TYPE_INTERFACE,
|
||||
"GtkPrintBackend",
|
||||
&print_backend_info, 0);
|
||||
|
||||
g_type_interface_add_prerequisite (print_backend_type, G_TYPE_OBJECT);
|
||||
}
|
||||
|
||||
return print_backend_type;
|
||||
}
|
||||
G_DEFINE_TYPE (GtkPrintBackend, gtk_print_backend, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
gtk_print_backend_base_init (gpointer g_class)
|
||||
gtk_print_backend_class_init (GtkPrintBackendClass *class)
|
||||
{
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
GType iface_type = G_TYPE_FROM_INTERFACE (g_class);
|
||||
GObjectClass *object_class;
|
||||
object_class = (GObjectClass *) class;
|
||||
|
||||
g_signal_new ("printer-list-changed",
|
||||
iface_type,
|
||||
backend_parent_class = g_type_class_peek_parent (class);
|
||||
|
||||
object_class->dispose = gtk_print_backend_dispose;
|
||||
|
||||
g_type_class_add_private (class, sizeof (GtkPrintBackendPrivate));
|
||||
|
||||
|
||||
signals[PRINTER_LIST_CHANGED] =
|
||||
g_signal_new ("printer-list-changed",
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkPrintBackendClass, printer_list_changed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
signals[PRINTER_LIST_DONE] =
|
||||
g_signal_new ("printer-list-done",
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkPrintBackendIface, printer_list_changed),
|
||||
G_STRUCT_OFFSET (GtkPrintBackendClass, printer_list_done),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
g_signal_new ("printer-added",
|
||||
iface_type,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkPrintBackendIface, printer_added),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1, G_TYPE_OBJECT);
|
||||
g_signal_new ("printer-removed",
|
||||
iface_type,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkPrintBackendIface, printer_removed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1, G_TYPE_OBJECT);
|
||||
g_signal_new ("printer-status-changed",
|
||||
iface_type,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkPrintBackendIface, printer_status_changed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1, G_TYPE_OBJECT);
|
||||
signals[PRINTER_ADDED] =
|
||||
g_signal_new ("printer-added",
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkPrintBackendClass, printer_added),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1, GTK_TYPE_PRINTER);
|
||||
signals[PRINTER_REMOVED] =
|
||||
g_signal_new ("printer-removed",
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkPrintBackendClass, printer_removed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1, GTK_TYPE_PRINTER);
|
||||
signals[PRINTER_STATUS_CHANGED] =
|
||||
g_signal_new ("printer-status-changed",
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkPrintBackendClass, printer_status_changed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1, GTK_TYPE_PRINTER);
|
||||
}
|
||||
|
||||
initialized = TRUE;
|
||||
static void
|
||||
gtk_print_backend_init (GtkPrintBackend *backend)
|
||||
{
|
||||
GtkPrintBackendPrivate *priv;
|
||||
|
||||
priv = backend->priv = GTK_PRINT_BACKEND_GET_PRIVATE (backend);
|
||||
|
||||
priv->printers = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
(GDestroyNotify) g_free,
|
||||
(GDestroyNotify) g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_print_backend_dispose (GObject *object)
|
||||
{
|
||||
GtkPrintBackend *backend;
|
||||
GtkPrintBackendPrivate *priv;
|
||||
|
||||
backend = GTK_PRINT_BACKEND (object);
|
||||
priv = backend->priv;
|
||||
|
||||
/* We unref the printers in dispose, not in finalize so that
|
||||
we can break refcount cycles with gtk_print_backend_destroy */
|
||||
if (priv->printers)
|
||||
{
|
||||
g_hash_table_destroy (priv->printers);
|
||||
priv->printers = NULL;
|
||||
}
|
||||
|
||||
backend_parent_class->dispose (object);
|
||||
}
|
||||
|
||||
GList *
|
||||
gtk_print_backend_get_printer_list (GtkPrintBackend *print_backend)
|
||||
|
||||
static void
|
||||
printer_hash_to_sorted_active_list (const gchar *key,
|
||||
gpointer value,
|
||||
GList **out_list)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_PRINT_BACKEND (print_backend), NULL);
|
||||
GtkPrinter *printer;
|
||||
|
||||
return GTK_PRINT_BACKEND_GET_IFACE (print_backend)->get_printer_list (print_backend);
|
||||
printer = GTK_PRINTER (value);
|
||||
|
||||
if (gtk_printer_get_name (printer) == NULL)
|
||||
return;
|
||||
|
||||
if (!gtk_printer_is_active (printer))
|
||||
return;
|
||||
|
||||
*out_list = g_list_insert_sorted (*out_list, value, (GCompareFunc) gtk_printer_compare);
|
||||
}
|
||||
|
||||
GtkPrinter *
|
||||
gtk_print_backend_find_printer (GtkPrintBackend *print_backend,
|
||||
const gchar *printer_name)
|
||||
|
||||
void
|
||||
gtk_print_backend_add_printer (GtkPrintBackend *backend,
|
||||
GtkPrinter *printer)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_PRINT_BACKEND (print_backend), NULL);
|
||||
GtkPrintBackendPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_PRINT_BACKEND (backend));
|
||||
|
||||
return GTK_PRINT_BACKEND_GET_IFACE (print_backend)->find_printer (print_backend, printer_name);
|
||||
priv = backend->priv;
|
||||
|
||||
if (!priv->printers)
|
||||
return;
|
||||
|
||||
g_hash_table_insert (priv->printers,
|
||||
g_strdup (gtk_printer_get_name (printer)),
|
||||
g_object_ref (printer));
|
||||
}
|
||||
|
||||
void
|
||||
gtk_print_backend_print_stream (GtkPrintBackend *print_backend,
|
||||
gtk_print_backend_remove_printer (GtkPrintBackend *backend,
|
||||
GtkPrinter *printer)
|
||||
{
|
||||
GtkPrintBackendPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_PRINT_BACKEND (backend));
|
||||
priv = backend->priv;
|
||||
|
||||
if (!priv->printers)
|
||||
return;
|
||||
|
||||
g_hash_table_remove (priv->printers,
|
||||
gtk_printer_get_name (printer));
|
||||
}
|
||||
|
||||
void
|
||||
gtk_print_backend_set_list_done (GtkPrintBackend *backend)
|
||||
{
|
||||
if (!backend->priv->printer_list_done)
|
||||
{
|
||||
backend->priv->printer_list_done = TRUE;
|
||||
g_signal_emit (backend, signals[PRINTER_LIST_DONE], 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GList *
|
||||
gtk_print_backend_get_printer_list (GtkPrintBackend *backend)
|
||||
{
|
||||
GtkPrintBackendPrivate *priv;
|
||||
GList *result;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_PRINT_BACKEND (backend), NULL);
|
||||
|
||||
priv = backend->priv;
|
||||
|
||||
result = NULL;
|
||||
if (priv->printers != NULL)
|
||||
g_hash_table_foreach (priv->printers,
|
||||
(GHFunc) printer_hash_to_sorted_active_list,
|
||||
&result);
|
||||
|
||||
if (!priv->printer_list_requested && priv->printers != NULL)
|
||||
{
|
||||
if (GTK_PRINT_BACKEND_GET_CLASS (backend)->request_printer_list)
|
||||
GTK_PRINT_BACKEND_GET_CLASS (backend)->request_printer_list (backend);
|
||||
priv->printer_list_requested = TRUE;
|
||||
}
|
||||
|
||||
return result;;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_print_backend_printer_list_is_done (GtkPrintBackend *print_backend)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_PRINT_BACKEND (print_backend), TRUE);
|
||||
|
||||
return print_backend->priv->printer_list_done;
|
||||
}
|
||||
|
||||
GtkPrinter *
|
||||
gtk_print_backend_find_printer (GtkPrintBackend *backend,
|
||||
const gchar *printer_name)
|
||||
{
|
||||
GtkPrintBackendPrivate *priv;
|
||||
GtkPrinter *printer;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_PRINT_BACKEND (backend), NULL);
|
||||
|
||||
priv = backend->priv;
|
||||
|
||||
if (priv->printers)
|
||||
printer = g_hash_table_lookup (priv->printers, printer_name);
|
||||
else
|
||||
printer = NULL;
|
||||
|
||||
return printer;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_print_backend_print_stream (GtkPrintBackend *backend,
|
||||
GtkPrintJob *job,
|
||||
gint data_fd,
|
||||
GtkPrintJobCompleteFunc callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify dnotify)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_PRINT_BACKEND (print_backend));
|
||||
g_return_if_fail (GTK_IS_PRINT_BACKEND (backend));
|
||||
|
||||
GTK_PRINT_BACKEND_GET_IFACE (print_backend)->print_stream (print_backend,
|
||||
job,
|
||||
data_fd,
|
||||
callback,
|
||||
user_data,
|
||||
dnotify);
|
||||
GTK_PRINT_BACKEND_GET_CLASS (backend)->print_stream (backend,
|
||||
job,
|
||||
data_fd,
|
||||
callback,
|
||||
user_data,
|
||||
dnotify);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
unref_at_idle_cb (gpointer data)
|
||||
{
|
||||
g_object_unref (data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_print_backend_unref_at_idle (GtkPrintBackend *print_backend)
|
||||
{
|
||||
g_idle_add (unref_at_idle_cb, print_backend);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_print_backend_destroy (GtkPrintBackend *print_backend)
|
||||
{
|
||||
/* The lifecycle of print backends and printers are tied, such that
|
||||
the backend owns the printers, but the printers also ref the backend.
|
||||
This is so that if the app has a reference to a printer its backend
|
||||
will be around. However, this results in a cycle, which we break
|
||||
with this call, which causes the print backend to release its printers.
|
||||
*/
|
||||
g_object_run_dispose (G_OBJECT (print_backend));
|
||||
}
|
||||
|
||||
#define __GTK_PRINT_BACKEND_C__
|
||||
|
@ -39,7 +39,8 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkPrintBackendIface GtkPrintBackendIface;
|
||||
typedef struct _GtkPrintBackendClass GtkPrintBackendClass;
|
||||
typedef struct _GtkPrintBackendPrivate GtkPrintBackendPrivate;
|
||||
|
||||
#define GTK_PRINT_BACKEND_ERROR (gtk_print_backend_error_quark ())
|
||||
|
||||
@ -51,22 +52,28 @@ typedef enum
|
||||
|
||||
GQuark gtk_print_backend_error_quark (void);
|
||||
|
||||
#define GTK_TYPE_PRINT_BACKEND (gtk_print_backend_get_type ())
|
||||
#define GTK_PRINT_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PRINT_BACKEND, GtkPrintBackend))
|
||||
#define GTK_IS_PRINT_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PRINT_BACKEND))
|
||||
#define GTK_PRINT_BACKEND_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GTK_TYPE_PRINT_BACKEND, GtkPrintBackendIface))
|
||||
#define GTK_TYPE_PRINT_BACKEND (gtk_print_backend_get_type ())
|
||||
#define GTK_PRINT_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PRINT_BACKEND, GtkPrintBackend))
|
||||
#define GTK_PRINT_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PRINT_BACKEND, GtkPrintBackendClass))
|
||||
#define GTK_IS_PRINT_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PRINT_BACKEND))
|
||||
#define GTK_IS_PRINT_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PRINT_BACKEND))
|
||||
#define GTK_PRINT_BACKEND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PRINT_BACKEND, GtkPrintBackendClass))
|
||||
|
||||
struct _GtkPrintBackendIface
|
||||
struct _GtkPrintBackend
|
||||
{
|
||||
GTypeInterface base_iface;
|
||||
GObject parent_instance;
|
||||
|
||||
GtkPrintBackendPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkPrintBackendClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* Global backend methods: */
|
||||
GList * (*get_printer_list) (GtkPrintBackend *printer_backend);
|
||||
|
||||
GtkPrinter * (*find_printer) (GtkPrintBackend *print_backend,
|
||||
const gchar *printer_name);
|
||||
void (*print_stream) (GtkPrintBackend *print_backend,
|
||||
GtkPrintJob *job,
|
||||
void (*request_printer_list) (GtkPrintBackend *backend);
|
||||
void (*print_stream) (GtkPrintBackend *backend,
|
||||
GtkPrintJob *job,
|
||||
gint data_fd,
|
||||
GtkPrintJobCompleteFunc callback,
|
||||
gpointer user_data,
|
||||
@ -97,26 +104,49 @@ struct _GtkPrintBackendIface
|
||||
double *left,
|
||||
double *right);
|
||||
|
||||
/* Signals
|
||||
*/
|
||||
void (*printer_list_changed) (void);
|
||||
void (*printer_added) (GtkPrinter *printer);
|
||||
void (*printer_removed) (GtkPrinter *printer);
|
||||
void (*printer_status_changed) (GtkPrinter *printer);
|
||||
/* Signals */
|
||||
void (*printer_list_changed) (GtkPrintBackend *backend);
|
||||
void (*printer_list_done) (GtkPrintBackend *backend);
|
||||
void (*printer_added) (GtkPrintBackend *backend,
|
||||
GtkPrinter *printer);
|
||||
void (*printer_removed) (GtkPrintBackend *backend,
|
||||
GtkPrinter *printer);
|
||||
void (*printer_status_changed) (GtkPrintBackend *backend,
|
||||
GtkPrinter *printer);
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_gtk_reserved1) (void);
|
||||
void (*_gtk_reserved2) (void);
|
||||
void (*_gtk_reserved3) (void);
|
||||
void (*_gtk_reserved4) (void);
|
||||
void (*_gtk_reserved5) (void);
|
||||
void (*_gtk_reserved6) (void);
|
||||
void (*_gtk_reserved7) (void);
|
||||
};
|
||||
|
||||
GType gtk_print_backend_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GList *gtk_print_backend_get_printer_list (GtkPrintBackend *print_backend);
|
||||
GtkPrinter *gtk_print_backend_find_printer (GtkPrintBackend *print_backend,
|
||||
const gchar *printer_name);
|
||||
void gtk_print_backend_print_stream (GtkPrintBackend *print_backend,
|
||||
GtkPrintJob *job,
|
||||
gint data_fd,
|
||||
GtkPrintJobCompleteFunc callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify dnotify);
|
||||
GList * gtk_print_backend_load_modules (void);
|
||||
GList *gtk_print_backend_get_printer_list (GtkPrintBackend *print_backend);
|
||||
gboolean gtk_print_backend_printer_list_is_done (GtkPrintBackend *print_backend);
|
||||
GtkPrinter *gtk_print_backend_find_printer (GtkPrintBackend *print_backend,
|
||||
const gchar *printer_name);
|
||||
void gtk_print_backend_print_stream (GtkPrintBackend *print_backend,
|
||||
GtkPrintJob *job,
|
||||
gint data_fd,
|
||||
GtkPrintJobCompleteFunc callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify dnotify);
|
||||
GList * gtk_print_backend_load_modules (void);
|
||||
void gtk_print_backend_unref_at_idle (GtkPrintBackend *print_backend);
|
||||
void gtk_print_backend_destroy (GtkPrintBackend *print_backend);
|
||||
|
||||
/* Backend-only functions for GtkPrintBackend */
|
||||
|
||||
void gtk_print_backend_add_printer (GtkPrintBackend *print_backend,
|
||||
GtkPrinter *printer);
|
||||
void gtk_print_backend_remove_printer (GtkPrintBackend *print_backend,
|
||||
GtkPrinter *printer);
|
||||
void gtk_print_backend_set_list_done (GtkPrintBackend *backend);
|
||||
|
||||
|
||||
/* Backend-only functions for GtkPrinter */
|
||||
|
@ -52,7 +52,6 @@ struct _GtkPrinterPrivate
|
||||
gchar *state_message;
|
||||
gint job_count;
|
||||
|
||||
/* Not ref:ed, backend owns printer. */
|
||||
GtkPrintBackend *backend;
|
||||
};
|
||||
|
||||
@ -215,6 +214,9 @@ gtk_printer_finalize (GObject *object)
|
||||
g_free (priv->state_message);
|
||||
g_free (priv->icon_name);
|
||||
|
||||
if (priv->backend)
|
||||
g_object_unref (priv->backend);
|
||||
|
||||
G_OBJECT_CLASS (gtk_printer_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@ -234,7 +236,7 @@ gtk_printer_set_property (GObject *object,
|
||||
break;
|
||||
|
||||
case PROP_BACKEND:
|
||||
priv->backend = GTK_PRINT_BACKEND (g_value_get_object (value));
|
||||
priv->backend = GTK_PRINT_BACKEND (g_value_dup_object (value));
|
||||
break;
|
||||
|
||||
case PROP_IS_VIRTUAL:
|
||||
@ -340,16 +342,6 @@ gtk_printer_get_backend (GtkPrinter *printer)
|
||||
return printer->priv->backend;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_printer_set_backend (GtkPrinter *printer,
|
||||
GtkPrintBackend *backend)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_PRINTER (printer));
|
||||
g_return_if_fail (GTK_IS_PRINT_BACKEND (backend));
|
||||
|
||||
printer->priv->backend = backend;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_printer_get_name:
|
||||
* @printer: a #GtkPrinter
|
||||
@ -663,8 +655,8 @@ gtk_printer_set_is_default (GtkPrinter *printer,
|
||||
void
|
||||
_gtk_printer_request_details (GtkPrinter *printer)
|
||||
{
|
||||
GtkPrintBackendIface *backend_iface = GTK_PRINT_BACKEND_GET_IFACE (printer->priv->backend);
|
||||
return backend_iface->printer_request_details (printer);
|
||||
GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
|
||||
return backend_class->printer_request_details (printer);
|
||||
}
|
||||
|
||||
GtkPrinterOptionSet *
|
||||
@ -672,16 +664,16 @@ _gtk_printer_get_options (GtkPrinter *printer,
|
||||
GtkPrintSettings *settings,
|
||||
GtkPageSetup *page_setup)
|
||||
{
|
||||
GtkPrintBackendIface *backend_iface = GTK_PRINT_BACKEND_GET_IFACE (printer->priv->backend);
|
||||
return backend_iface->printer_get_options (printer, settings, page_setup);
|
||||
GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
|
||||
return backend_class->printer_get_options (printer, settings, page_setup);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_printer_mark_conflicts (GtkPrinter *printer,
|
||||
GtkPrinterOptionSet *options)
|
||||
{
|
||||
GtkPrintBackendIface *backend_iface = GTK_PRINT_BACKEND_GET_IFACE (printer->priv->backend);
|
||||
return backend_iface->printer_mark_conflicts (printer, options);
|
||||
GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
|
||||
return backend_class->printer_mark_conflicts (printer, options);
|
||||
}
|
||||
|
||||
void
|
||||
@ -689,8 +681,8 @@ _gtk_printer_get_settings_from_options (GtkPrinter *printer,
|
||||
GtkPrinterOptionSet *options,
|
||||
GtkPrintSettings *settings)
|
||||
{
|
||||
GtkPrintBackendIface *backend_iface = GTK_PRINT_BACKEND_GET_IFACE (printer->priv->backend);
|
||||
return backend_iface->printer_get_settings_from_options (printer, options, settings);
|
||||
GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
|
||||
return backend_class->printer_get_settings_from_options (printer, options, settings);
|
||||
}
|
||||
|
||||
void
|
||||
@ -699,8 +691,8 @@ _gtk_printer_prepare_for_print (GtkPrinter *printer,
|
||||
GtkPrintSettings *settings,
|
||||
GtkPageSetup *page_setup)
|
||||
{
|
||||
GtkPrintBackendIface *backend_iface = GTK_PRINT_BACKEND_GET_IFACE (printer->priv->backend);
|
||||
return backend_iface->printer_prepare_for_print (printer, print_job, settings, page_setup);
|
||||
GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
|
||||
return backend_class->printer_prepare_for_print (printer, print_job, settings, page_setup);
|
||||
}
|
||||
|
||||
cairo_surface_t *
|
||||
@ -709,17 +701,17 @@ _gtk_printer_create_cairo_surface (GtkPrinter *printer,
|
||||
gdouble height,
|
||||
gint cache_fd)
|
||||
{
|
||||
GtkPrintBackendIface *backend_iface = GTK_PRINT_BACKEND_GET_IFACE (printer->priv->backend);
|
||||
GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
|
||||
|
||||
return backend_iface->printer_create_cairo_surface (printer, width, height, cache_fd);
|
||||
return backend_class->printer_create_cairo_surface (printer, width, height, cache_fd);
|
||||
}
|
||||
|
||||
GList *
|
||||
_gtk_printer_list_papers (GtkPrinter *printer)
|
||||
{
|
||||
GtkPrintBackendIface *backend_iface = GTK_PRINT_BACKEND_GET_IFACE (printer->priv->backend);
|
||||
GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
|
||||
|
||||
return backend_iface->printer_list_papers (printer);
|
||||
return backend_class->printer_list_papers (printer);
|
||||
}
|
||||
|
||||
void
|
||||
@ -729,9 +721,28 @@ _gtk_printer_get_hard_margins (GtkPrinter *printer,
|
||||
gdouble *left,
|
||||
gdouble *right)
|
||||
{
|
||||
GtkPrintBackendIface *backend_iface = GTK_PRINT_BACKEND_GET_IFACE (printer->priv->backend);
|
||||
GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
|
||||
|
||||
backend_iface->printer_get_hard_margins (printer, top, bottom, left, right);
|
||||
backend_class->printer_get_hard_margins (printer, top, bottom, left, right);
|
||||
}
|
||||
|
||||
gint
|
||||
gtk_printer_compare (GtkPrinter *a, GtkPrinter *b)
|
||||
{
|
||||
const char *name_a, *name_b;
|
||||
|
||||
g_assert (GTK_IS_PRINTER (a) && GTK_IS_PRINTER (b));
|
||||
|
||||
name_a = gtk_printer_get_name (a);
|
||||
name_b = gtk_printer_get_name (b);
|
||||
if (name_a == NULL && name_b == NULL)
|
||||
return 0;
|
||||
else if (name_a == NULL)
|
||||
return G_MAXINT;
|
||||
else if (name_b == NULL)
|
||||
return G_MININT;
|
||||
else
|
||||
return g_ascii_strcasecmp (name_a, name_b);
|
||||
}
|
||||
|
||||
#define __GTK_PRINTER_C__
|
||||
|
@ -78,6 +78,8 @@ gboolean gtk_printer_is_active (GtkPrinter *printer
|
||||
gboolean gtk_printer_is_virtual (GtkPrinter *printer);
|
||||
gboolean gtk_printer_is_default (GtkPrinter *printer);
|
||||
|
||||
gint gtk_printer_compare (GtkPrinter *a,
|
||||
GtkPrinter *b);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -61,7 +61,8 @@ struct _GtkPrintOperationPrivate
|
||||
GtkPageSetup *page_setup);
|
||||
void (*end_page) (GtkPrintOperation *operation,
|
||||
GtkPrintContext *print_context);
|
||||
void (*end_run) (GtkPrintOperation *operation);
|
||||
void (*end_run) (GtkPrintOperation *operation,
|
||||
gboolean wait);
|
||||
GDestroyNotify free_platform_data;
|
||||
};
|
||||
|
||||
@ -70,7 +71,8 @@ GtkPrintOperationResult _gtk_print_operation_platform_backend_run_dialog (GtkPri
|
||||
gboolean *do_print,
|
||||
GError **error);
|
||||
|
||||
typedef void (* GtkPrintOperationPrintFunc) (GtkPrintOperation *op);
|
||||
typedef void (* GtkPrintOperationPrintFunc) (GtkPrintOperation *op,
|
||||
gboolean wait);
|
||||
|
||||
void _gtk_print_operation_platform_backend_run_dialog_async (GtkPrintOperation *op,
|
||||
GtkWindow *parent,
|
||||
|
@ -42,8 +42,17 @@ typedef struct {
|
||||
GtkPrintJob *job; /* the job we are sending to the printer */
|
||||
gulong job_status_changed_tag;
|
||||
GtkWindow *parent; /* just in case we need to throw error dialogs */
|
||||
GMainLoop *loop;
|
||||
gboolean data_sent;
|
||||
} GtkPrintOperationUnix;
|
||||
|
||||
typedef struct _PrinterFinder PrinterFinder;
|
||||
|
||||
static void printer_finder_free (PrinterFinder *finder);
|
||||
static void find_printer (const char *printer,
|
||||
GFunc func,
|
||||
gpointer data);
|
||||
|
||||
static void
|
||||
unix_start_page (GtkPrintOperation *op,
|
||||
GtkPrintContext *print_context,
|
||||
@ -100,18 +109,37 @@ unix_finish_send (GtkPrintJob *job,
|
||||
|
||||
gtk_window_present (GTK_WINDOW (edialog));
|
||||
}
|
||||
|
||||
op_unix->data_sent = TRUE;
|
||||
if (op_unix->loop)
|
||||
g_main_loop_quit (op_unix->loop);
|
||||
}
|
||||
|
||||
static void
|
||||
unix_end_run (GtkPrintOperation *op)
|
||||
unix_end_run (GtkPrintOperation *op,
|
||||
gboolean wait)
|
||||
{
|
||||
GtkPrintOperationUnix *op_unix = op->priv->platform_data;
|
||||
|
||||
|
||||
if (wait)
|
||||
op_unix->loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
/* TODO: Check for error */
|
||||
gtk_print_job_send (op_unix->job,
|
||||
unix_finish_send,
|
||||
op_unix, NULL,
|
||||
NULL);
|
||||
|
||||
if (wait)
|
||||
{
|
||||
if (!op_unix->data_sent)
|
||||
{
|
||||
GDK_THREADS_LEAVE ();
|
||||
g_main_loop_run (op_unix->loop);
|
||||
GDK_THREADS_ENTER ();
|
||||
}
|
||||
g_main_loop_unref (op_unix->loop);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -154,6 +182,8 @@ typedef struct {
|
||||
GtkPrintOperationResult result;
|
||||
GtkPrintOperationPrintFunc print_cb;
|
||||
GDestroyNotify destroy;
|
||||
GtkWindow *parent;
|
||||
GMainLoop *loop;
|
||||
} PrintResponseData;
|
||||
|
||||
static void
|
||||
@ -166,41 +196,29 @@ print_response_data_free (gpointer data)
|
||||
}
|
||||
|
||||
static void
|
||||
handle_print_response (GtkWidget *dialog,
|
||||
gint response,
|
||||
gpointer data)
|
||||
finish_print (PrintResponseData *rdata,
|
||||
GtkPrinter *printer,
|
||||
GtkPageSetup *page_setup,
|
||||
GtkPrintSettings *settings)
|
||||
{
|
||||
GtkPrintUnixDialog *pd = GTK_PRINT_UNIX_DIALOG (dialog);
|
||||
PrintResponseData *rdata = data;
|
||||
GtkPrintOperation *op = rdata->op;
|
||||
GtkPrintOperationPrivate *priv = op->priv;
|
||||
|
||||
if (response == GTK_RESPONSE_OK)
|
||||
priv->start_page = unix_start_page;
|
||||
priv->end_page = unix_end_page;
|
||||
priv->end_run = unix_end_run;
|
||||
|
||||
if (rdata->do_print)
|
||||
{
|
||||
GtkPrintOperationUnix *op_unix;
|
||||
GtkPrinter *printer;
|
||||
GtkPrintSettings *settings;
|
||||
GtkPageSetup *page_setup;
|
||||
|
||||
rdata->result = GTK_PRINT_OPERATION_RESULT_APPLY;
|
||||
|
||||
printer = gtk_print_unix_dialog_get_selected_printer (GTK_PRINT_UNIX_DIALOG (pd));
|
||||
if (printer == NULL)
|
||||
goto out;
|
||||
|
||||
rdata->do_print = TRUE;
|
||||
|
||||
settings = gtk_print_unix_dialog_get_settings (GTK_PRINT_UNIX_DIALOG (pd));
|
||||
page_setup = gtk_print_unix_dialog_get_page_setup (GTK_PRINT_UNIX_DIALOG (pd));
|
||||
|
||||
gtk_print_operation_set_print_settings (op, settings);
|
||||
|
||||
|
||||
op_unix = g_new0 (GtkPrintOperationUnix, 1);
|
||||
op_unix->job = gtk_print_job_new (priv->job_name,
|
||||
printer,
|
||||
settings,
|
||||
page_setup);
|
||||
g_object_unref (settings);
|
||||
|
||||
rdata->op->priv->surface = gtk_print_job_get_surface (op_unix->job, rdata->error);
|
||||
if (op->priv->surface == NULL)
|
||||
@ -216,7 +234,7 @@ handle_print_response (GtkWidget *dialog,
|
||||
g_signal_connect (op_unix->job, "status_changed",
|
||||
G_CALLBACK (job_status_changed_cb), op);
|
||||
|
||||
op_unix->parent = gtk_window_get_transient_for (GTK_WINDOW (pd));
|
||||
op_unix->parent = rdata->parent;
|
||||
|
||||
priv->dpi_x = 72;
|
||||
priv->dpi_y = 72;
|
||||
@ -236,17 +254,11 @@ handle_print_response (GtkWidget *dialog,
|
||||
priv->manual_orientation = op_unix->job->rotate_to_orientation;
|
||||
}
|
||||
|
||||
priv->start_page = unix_start_page;
|
||||
priv->end_page = unix_end_page;
|
||||
priv->end_run = unix_end_run;
|
||||
|
||||
out:
|
||||
gtk_widget_destroy (GTK_WIDGET (pd));
|
||||
|
||||
if (rdata->print_cb)
|
||||
{
|
||||
if (rdata->do_print)
|
||||
rdata->print_cb (op);
|
||||
rdata->print_cb (op, FALSE);
|
||||
else
|
||||
_gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
|
||||
}
|
||||
@ -255,6 +267,81 @@ handle_print_response (GtkWidget *dialog,
|
||||
rdata->destroy (rdata);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_print_response (GtkWidget *dialog,
|
||||
gint response,
|
||||
gpointer data)
|
||||
{
|
||||
GtkPrintUnixDialog *pd = GTK_PRINT_UNIX_DIALOG (dialog);
|
||||
PrintResponseData *rdata = data;
|
||||
GtkPrintSettings *settings = NULL;
|
||||
GtkPageSetup *page_setup = NULL;
|
||||
GtkPrinter *printer = NULL;
|
||||
|
||||
if (response == GTK_RESPONSE_OK)
|
||||
{
|
||||
rdata->result = GTK_PRINT_OPERATION_RESULT_APPLY;
|
||||
|
||||
printer = gtk_print_unix_dialog_get_selected_printer (GTK_PRINT_UNIX_DIALOG (pd));
|
||||
if (printer == NULL)
|
||||
goto out;
|
||||
|
||||
rdata->do_print = TRUE;
|
||||
|
||||
settings = gtk_print_unix_dialog_get_settings (GTK_PRINT_UNIX_DIALOG (pd));
|
||||
page_setup = gtk_print_unix_dialog_get_page_setup (GTK_PRINT_UNIX_DIALOG (pd));
|
||||
}
|
||||
|
||||
out:
|
||||
finish_print (rdata, printer, page_setup, settings);
|
||||
|
||||
if (settings)
|
||||
g_object_unref (settings);
|
||||
|
||||
gtk_widget_destroy (GTK_WIDGET (pd));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
found_printer (GtkPrinter *printer,
|
||||
PrintResponseData *rdata)
|
||||
{
|
||||
GtkPrintOperation *op = rdata->op;
|
||||
GtkPrintOperationPrivate *priv = op->priv;
|
||||
GtkPrintSettings *settings = NULL;
|
||||
GtkPageSetup *page_setup = NULL;
|
||||
|
||||
if (rdata->loop)
|
||||
g_main_loop_quit (rdata->loop);
|
||||
|
||||
if (printer != NULL) {
|
||||
rdata->result = GTK_PRINT_OPERATION_RESULT_APPLY;
|
||||
|
||||
rdata->do_print = TRUE;
|
||||
|
||||
if (priv->print_settings)
|
||||
settings = gtk_print_settings_copy (priv->print_settings);
|
||||
else
|
||||
settings = gtk_print_settings_new ();
|
||||
|
||||
gtk_print_settings_set_printer (settings,
|
||||
gtk_printer_get_name (printer));
|
||||
|
||||
if (priv->default_page_setup)
|
||||
page_setup = gtk_page_setup_copy (priv->default_page_setup);
|
||||
else
|
||||
page_setup = gtk_page_setup_new ();
|
||||
}
|
||||
|
||||
finish_print (rdata, printer, page_setup, settings);
|
||||
|
||||
if (settings)
|
||||
g_object_unref (settings);
|
||||
|
||||
if (page_setup)
|
||||
g_object_unref (page_setup);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_print_operation_platform_backend_run_dialog_async (GtkPrintOperation *op,
|
||||
GtkWindow *parent,
|
||||
@ -262,6 +349,7 @@ _gtk_print_operation_platform_backend_run_dialog_async (GtkPrintOperation
|
||||
{
|
||||
GtkWidget *pd;
|
||||
PrintResponseData *rdata;
|
||||
const char *printer_name;
|
||||
|
||||
rdata = g_new (PrintResponseData, 1);
|
||||
rdata->op = g_object_ref (op);
|
||||
@ -269,15 +357,29 @@ _gtk_print_operation_platform_backend_run_dialog_async (GtkPrintOperation
|
||||
rdata->result = GTK_PRINT_OPERATION_RESULT_CANCEL;
|
||||
rdata->error = NULL;
|
||||
rdata->print_cb = print_cb;
|
||||
rdata->parent = parent;
|
||||
rdata->loop = NULL;
|
||||
rdata->destroy = print_response_data_free;
|
||||
|
||||
pd = get_print_dialog (op, parent);
|
||||
gtk_window_set_modal (GTK_WINDOW (pd), TRUE);
|
||||
if (op->priv->show_dialog)
|
||||
{
|
||||
pd = get_print_dialog (op, parent);
|
||||
gtk_window_set_modal (GTK_WINDOW (pd), TRUE);
|
||||
|
||||
g_signal_connect (pd, "response",
|
||||
G_CALLBACK (handle_print_response), rdata);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (pd));
|
||||
g_signal_connect (pd, "response",
|
||||
G_CALLBACK (handle_print_response), rdata);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (pd));
|
||||
}
|
||||
else
|
||||
{
|
||||
printer_name = NULL;
|
||||
if (op->priv->print_settings)
|
||||
printer_name = gtk_print_settings_get_printer (op->priv->print_settings);
|
||||
|
||||
find_printer (printer_name,
|
||||
(GFunc) found_printer, rdata);
|
||||
}
|
||||
}
|
||||
|
||||
GtkPrintOperationResult
|
||||
@ -289,6 +391,7 @@ _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
|
||||
GtkWidget *pd;
|
||||
PrintResponseData rdata;
|
||||
gint response;
|
||||
const char *printer_name;
|
||||
|
||||
rdata.op = op;
|
||||
rdata.do_print = FALSE;
|
||||
@ -296,14 +399,34 @@ _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
|
||||
rdata.error = error;
|
||||
rdata.print_cb = NULL;
|
||||
rdata.destroy = NULL;
|
||||
rdata.parent = parent;
|
||||
rdata.loop = NULL;
|
||||
|
||||
pd = get_print_dialog (op, parent);
|
||||
if (op->priv->show_dialog)
|
||||
{
|
||||
pd = get_print_dialog (op, parent);
|
||||
response = gtk_dialog_run (GTK_DIALOG (pd));
|
||||
handle_print_response (pd, response, &rdata);
|
||||
}
|
||||
else
|
||||
{
|
||||
printer_name = NULL;
|
||||
if (op->priv->print_settings)
|
||||
printer_name = gtk_print_settings_get_printer (op->priv->print_settings);
|
||||
|
||||
rdata.loop = g_main_loop_new (NULL, FALSE);
|
||||
find_printer (printer_name,
|
||||
(GFunc) found_printer, &rdata);
|
||||
|
||||
response = gtk_dialog_run (GTK_DIALOG (pd));
|
||||
handle_print_response (pd, response, &rdata);
|
||||
GDK_THREADS_LEAVE ();
|
||||
g_main_loop_run (rdata.loop);
|
||||
GDK_THREADS_ENTER ();
|
||||
|
||||
g_main_loop_unref (rdata.loop);
|
||||
}
|
||||
|
||||
*do_print = rdata.do_print;
|
||||
|
||||
|
||||
return rdata.result;
|
||||
}
|
||||
|
||||
@ -448,6 +571,184 @@ gtk_print_run_page_setup_dialog_async (GtkWindow *parent,
|
||||
gtk_window_present (GTK_WINDOW (dialog));
|
||||
}
|
||||
|
||||
struct _PrinterFinder {
|
||||
gboolean found_printer;
|
||||
GFunc func;
|
||||
gpointer data;
|
||||
char *printer_name;
|
||||
GList *backends;
|
||||
guint timeout_tag;
|
||||
GtkPrinter *printer;
|
||||
GtkPrinter *default_printer;
|
||||
GtkPrinter *first_printer;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
find_printer_idle (gpointer data)
|
||||
{
|
||||
PrinterFinder *finder = data;
|
||||
GtkPrinter *printer;
|
||||
|
||||
if (finder->printer != NULL)
|
||||
printer = finder->printer;
|
||||
else if (finder->default_printer != NULL)
|
||||
printer = finder->default_printer;
|
||||
else if (finder->first_printer != NULL)
|
||||
printer = finder->first_printer;
|
||||
else
|
||||
printer = NULL;
|
||||
|
||||
finder->func (printer, finder->data);
|
||||
|
||||
printer_finder_free (finder);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
printer_added_cb (GtkPrintBackend *backend,
|
||||
GtkPrinter *printer,
|
||||
PrinterFinder *finder)
|
||||
{
|
||||
if (gtk_printer_is_virtual (printer) ||
|
||||
finder->found_printer)
|
||||
return;
|
||||
|
||||
if (finder->printer_name != NULL &&
|
||||
strcmp (gtk_printer_get_name (printer), finder->printer_name) == 0)
|
||||
{
|
||||
finder->printer = g_object_ref (printer);
|
||||
finder->found_printer = TRUE;
|
||||
}
|
||||
else if (finder->default_printer == NULL &&
|
||||
gtk_printer_is_default (printer))
|
||||
{
|
||||
finder->default_printer = g_object_ref (printer);
|
||||
if (finder->printer_name == NULL)
|
||||
finder->found_printer = TRUE;
|
||||
}
|
||||
else
|
||||
if (finder->first_printer == NULL)
|
||||
finder->first_printer = g_object_ref (printer);
|
||||
|
||||
if (finder->found_printer)
|
||||
g_idle_add (find_printer_idle, finder);
|
||||
}
|
||||
|
||||
static void
|
||||
printer_list_done_cb (GtkPrintBackend *backend,
|
||||
PrinterFinder *finder)
|
||||
{
|
||||
finder->backends = g_list_remove (finder->backends, backend);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (backend, printer_added_cb, finder);
|
||||
g_signal_handlers_disconnect_by_func (backend, printer_list_done_cb, finder);
|
||||
|
||||
gtk_print_backend_destroy (backend);
|
||||
g_object_unref (backend);
|
||||
|
||||
if (finder->backends == NULL && !finder->found_printer)
|
||||
g_idle_add (find_printer_idle, finder);
|
||||
}
|
||||
|
||||
static void
|
||||
find_printer_init (PrinterFinder *finder,
|
||||
GtkPrintBackend *backend)
|
||||
{
|
||||
GList *list;
|
||||
GList *node;
|
||||
|
||||
list = gtk_print_backend_get_printer_list (backend);
|
||||
|
||||
node = list;
|
||||
while (node != NULL)
|
||||
{
|
||||
printer_added_cb (backend, node->data, finder);
|
||||
node = node->next;
|
||||
|
||||
if (finder->found_printer)
|
||||
break;
|
||||
}
|
||||
|
||||
g_list_free (list);
|
||||
|
||||
if (gtk_print_backend_printer_list_is_done (backend))
|
||||
{
|
||||
finder->backends = g_list_remove (finder->backends, backend);
|
||||
gtk_print_backend_destroy (backend);
|
||||
g_object_unref (backend);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_signal_connect (backend,
|
||||
"printer-added",
|
||||
(GCallback) printer_added_cb,
|
||||
finder);
|
||||
g_signal_connect (backend,
|
||||
"printer-list-done",
|
||||
(GCallback) printer_list_done_cb,
|
||||
finder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
printer_finder_free (PrinterFinder *finder)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
g_free (finder->printer_name);
|
||||
|
||||
if (finder->printer)
|
||||
g_object_unref (finder->printer);
|
||||
|
||||
if (finder->default_printer)
|
||||
g_object_unref (finder->default_printer);
|
||||
|
||||
if (finder->first_printer)
|
||||
g_object_unref (finder->first_printer);
|
||||
|
||||
for (l = finder->backends; l != NULL; l = l->next)
|
||||
{
|
||||
GtkPrintBackend *backend = l->data;
|
||||
g_signal_handlers_disconnect_by_func (backend, printer_added_cb, finder);
|
||||
g_signal_handlers_disconnect_by_func (backend, printer_list_done_cb, finder);
|
||||
gtk_print_backend_destroy (backend);
|
||||
g_object_unref (backend);
|
||||
}
|
||||
|
||||
g_list_free (finder->backends);
|
||||
|
||||
g_free (finder);
|
||||
}
|
||||
|
||||
static void
|
||||
find_printer (const char *printer,
|
||||
GFunc func,
|
||||
gpointer data)
|
||||
{
|
||||
GList *node, *next;
|
||||
PrinterFinder *finder;
|
||||
|
||||
finder = g_new0 (PrinterFinder, 1);
|
||||
|
||||
finder->printer_name = g_strdup (printer);
|
||||
finder->func = func;
|
||||
finder->data = data;
|
||||
|
||||
finder->backends = NULL;
|
||||
if (g_module_supported ())
|
||||
finder->backends = gtk_print_backend_load_modules ();
|
||||
|
||||
for (node = finder->backends; !finder->found_printer && node != NULL; node = next)
|
||||
{
|
||||
next = node->next;
|
||||
find_printer_init (finder, GTK_PRINT_BACKEND (node->data));
|
||||
}
|
||||
|
||||
if (finder->backends == NULL && !finder->found_printer)
|
||||
g_idle_add (find_printer_idle, finder);
|
||||
}
|
||||
|
||||
#define __GTK_PRINT_OPERATION_UNIX_C__
|
||||
#include "gtkaliasdef.c"
|
||||
|
@ -1115,7 +1115,8 @@ pdf_end_page (GtkPrintOperation *op,
|
||||
}
|
||||
|
||||
static void
|
||||
pdf_end_run (GtkPrintOperation *op)
|
||||
pdf_end_run (GtkPrintOperation *op,
|
||||
gboolean wait)
|
||||
{
|
||||
GtkPrintOperationPrivate *priv = op->priv;
|
||||
|
||||
@ -1161,7 +1162,8 @@ run_pdf (GtkPrintOperation *op,
|
||||
}
|
||||
|
||||
static void
|
||||
print_pages (GtkPrintOperation *op)
|
||||
print_pages (GtkPrintOperation *op,
|
||||
gboolean wait)
|
||||
{
|
||||
GtkPrintOperationPrivate *priv = op->priv;
|
||||
int page, range;
|
||||
@ -1289,8 +1291,7 @@ print_pages (GtkPrintOperation *op)
|
||||
g_object_unref (initial_page_setup);
|
||||
|
||||
cairo_surface_finish (priv->surface);
|
||||
priv->end_run (op);
|
||||
|
||||
priv->end_run (op, wait);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1343,7 +1344,7 @@ gtk_print_operation_run (GtkPrintOperation *op,
|
||||
&do_print,
|
||||
error);
|
||||
if (do_print)
|
||||
print_pages (op);
|
||||
print_pages (op, TRUE);
|
||||
else
|
||||
_gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
|
||||
|
||||
@ -1384,7 +1385,7 @@ gtk_print_operation_run_async (GtkPrintOperation *op,
|
||||
{
|
||||
run_pdf (op, parent, &do_print, NULL);
|
||||
if (do_print)
|
||||
print_pages (op);
|
||||
print_pages (op, FALSE);
|
||||
else
|
||||
_gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
|
||||
}
|
||||
|
@ -73,6 +73,15 @@ static void unschedule_idle_mark_conflicts (GtkPrintUnixDialog *dialog);
|
||||
static void selected_printer_changed (GtkTreeSelection *selection,
|
||||
GtkPrintUnixDialog *dialog);
|
||||
static void clear_per_printer_ui (GtkPrintUnixDialog *dialog);
|
||||
static void printer_added_cb (GtkPrintBackend *backend,
|
||||
GtkPrinter *printer,
|
||||
GtkPrintUnixDialog *dialog);
|
||||
static void printer_removed_cb (GtkPrintBackend *backend,
|
||||
GtkPrinter *printer,
|
||||
GtkPrintUnixDialog *dialog);
|
||||
static void printer_status_cb (GtkPrintBackend *backend,
|
||||
GtkPrinter *printer,
|
||||
GtkPrintUnixDialog *dialog);
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
@ -281,6 +290,8 @@ gtk_print_unix_dialog_finalize (GObject *object)
|
||||
{
|
||||
GtkPrintUnixDialog *dialog = GTK_PRINT_UNIX_DIALOG (object);
|
||||
GtkPrintUnixDialogPrivate *priv = dialog->priv;
|
||||
GtkPrintBackend *backend;
|
||||
GList *node;
|
||||
|
||||
unschedule_idle_mark_conflicts (dialog);
|
||||
|
||||
@ -339,6 +350,21 @@ gtk_print_unix_dialog_finalize (GObject *object)
|
||||
g_free (priv->format_for_printer);
|
||||
priv->format_for_printer = NULL;
|
||||
|
||||
for (node = priv->print_backends; node != NULL; node = node->next)
|
||||
{
|
||||
backend = GTK_PRINT_BACKEND (node->data);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (backend, printer_added_cb, dialog);
|
||||
g_signal_handlers_disconnect_by_func (backend, printer_removed_cb, dialog);
|
||||
g_signal_handlers_disconnect_by_func (backend, printer_status_cb, dialog);
|
||||
|
||||
gtk_print_backend_destroy (backend);
|
||||
g_object_unref (backend);
|
||||
}
|
||||
|
||||
g_list_free (priv->print_backends);
|
||||
priv->print_backends = NULL;
|
||||
|
||||
G_OBJECT_CLASS (gtk_print_unix_dialog_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@ -1164,6 +1190,7 @@ selected_printer_changed (GtkTreeSelection *selection,
|
||||
g_signal_connect (printer, "details-acquired",
|
||||
G_CALLBACK (printer_details_acquired), dialog);
|
||||
_gtk_printer_request_details (printer);
|
||||
g_object_unref (printer);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -242,6 +242,26 @@ gtk_cups_request_ipp_add_string (GtkCupsRequest *request,
|
||||
value);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_cups_request_ipp_add_strings (GtkCupsRequest *request,
|
||||
ipp_tag_t group,
|
||||
ipp_tag_t tag,
|
||||
const char *name,
|
||||
int num_values,
|
||||
const char *charset,
|
||||
const char * const *values)
|
||||
{
|
||||
ippAddStrings (request->ipp_request,
|
||||
group,
|
||||
tag,
|
||||
name,
|
||||
num_values,
|
||||
charset,
|
||||
values);
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *name;
|
||||
|
@ -109,6 +109,13 @@ void gtk_cups_request_ipp_add_string (GtkCupsRequest *request,
|
||||
const char *name,
|
||||
const char *charset,
|
||||
const char *value);
|
||||
void gtk_cups_request_ipp_add_strings (GtkCupsRequest *request,
|
||||
ipp_tag_t group,
|
||||
ipp_tag_t tag,
|
||||
const char *name,
|
||||
int num_values,
|
||||
const char *charset,
|
||||
const char * const *values);
|
||||
gboolean gtk_cups_request_read_write (GtkCupsRequest *request);
|
||||
GtkCupsPollState gtk_cups_request_get_poll_state (GtkCupsRequest *request);
|
||||
void gtk_cups_request_free (GtkCupsRequest *request);
|
||||
|
@ -89,14 +89,12 @@ typedef struct
|
||||
|
||||
struct _GtkPrintBackendCupsClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
GtkPrintBackendClass parent_class;
|
||||
};
|
||||
|
||||
struct _GtkPrintBackendCups
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GHashTable *printers;
|
||||
GtkPrintBackend parent_instance;
|
||||
|
||||
char *default_printer;
|
||||
|
||||
@ -108,10 +106,10 @@ struct _GtkPrintBackendCups
|
||||
static GObjectClass *backend_parent_class;
|
||||
|
||||
static void gtk_print_backend_cups_class_init (GtkPrintBackendCupsClass *class);
|
||||
static void gtk_print_backend_cups_iface_init (GtkPrintBackendIface *iface);
|
||||
static void gtk_print_backend_cups_init (GtkPrintBackendCups *impl);
|
||||
static void gtk_print_backend_cups_finalize (GObject *object);
|
||||
static GList * cups_get_printer_list (GtkPrintBackend *print_backend);
|
||||
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,
|
||||
@ -145,6 +143,17 @@ static void cups_begin_polling_info (GtkPrintBack
|
||||
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,
|
||||
gint data_fd,
|
||||
GtkPrintJobCompleteFunc callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify dnotify);
|
||||
static cairo_surface_t * cups_printer_create_cairo_surface (GtkPrinter *printer,
|
||||
gdouble width,
|
||||
gdouble height,
|
||||
gint cache_fd);
|
||||
|
||||
|
||||
static void
|
||||
gtk_print_backend_cups_register_type (GTypeModule *module)
|
||||
@ -164,21 +173,10 @@ gtk_print_backend_cups_register_type (GTypeModule *module)
|
||||
(GInstanceInitFunc) gtk_print_backend_cups_init
|
||||
};
|
||||
|
||||
static const GInterfaceInfo print_backend_info =
|
||||
{
|
||||
(GInterfaceInitFunc) gtk_print_backend_cups_iface_init, /* interface_init */
|
||||
NULL, /* interface_finalize */
|
||||
NULL /* interface_data */
|
||||
};
|
||||
|
||||
print_backend_cups_type = g_type_module_register_type (module,
|
||||
G_TYPE_OBJECT,
|
||||
GTK_TYPE_PRINT_BACKEND,
|
||||
"GtkPrintBackendCups",
|
||||
&print_backend_cups_info, 0);
|
||||
g_type_module_add_interface (module,
|
||||
print_backend_cups_type,
|
||||
GTK_TYPE_PRINT_BACKEND,
|
||||
&print_backend_info);
|
||||
}
|
||||
}
|
||||
|
||||
@ -229,10 +227,23 @@ static void
|
||||
gtk_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;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -272,18 +283,6 @@ cups_printer_create_cairo_surface (GtkPrinter *printer,
|
||||
return surface;
|
||||
}
|
||||
|
||||
static GtkPrinter *
|
||||
gtk_print_backend_cups_find_printer (GtkPrintBackend *print_backend,
|
||||
const gchar *printer_name)
|
||||
{
|
||||
GtkPrintBackendCups *cups_print_backend;
|
||||
|
||||
cups_print_backend = GTK_PRINT_BACKEND_CUPS (print_backend);
|
||||
|
||||
return (GtkPrinter *) g_hash_table_lookup (cups_print_backend->printers,
|
||||
printer_name);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GtkPrintJobCompleteFunc callback;
|
||||
GtkPrintJob *job;
|
||||
@ -416,31 +415,11 @@ gtk_print_backend_cups_print_stream (GtkPrintBackend *print_backend,
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gtk_print_backend_cups_iface_init (GtkPrintBackendIface *iface)
|
||||
{
|
||||
iface->get_printer_list = cups_get_printer_list;
|
||||
iface->find_printer = gtk_print_backend_cups_find_printer;
|
||||
iface->print_stream = gtk_print_backend_cups_print_stream;
|
||||
iface->printer_request_details = cups_printer_request_details;
|
||||
iface->printer_create_cairo_surface = cups_printer_create_cairo_surface;
|
||||
iface->printer_get_options = cups_printer_get_options;
|
||||
iface->printer_mark_conflicts = cups_printer_mark_conflicts;
|
||||
iface->printer_get_settings_from_options = cups_printer_get_settings_from_options;
|
||||
iface->printer_prepare_for_print = cups_printer_prepare_for_print;
|
||||
iface->printer_list_papers = cups_printer_list_papers;
|
||||
iface->printer_get_hard_margins = cups_printer_get_hard_margins;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_print_backend_cups_init (GtkPrintBackendCups *backend_cups)
|
||||
{
|
||||
backend_cups->list_printers_poll = 0;
|
||||
backend_cups->list_printers_pending = FALSE;
|
||||
backend_cups->printers = g_hash_table_new_full (g_str_hash,
|
||||
g_str_equal,
|
||||
(GDestroyNotify) g_free,
|
||||
(GDestroyNotify) g_object_unref);
|
||||
|
||||
cups_request_default_printer (backend_cups);
|
||||
}
|
||||
@ -452,18 +431,27 @@ gtk_print_backend_cups_finalize (GObject *object)
|
||||
|
||||
backend_cups = GTK_PRINT_BACKEND_CUPS (object);
|
||||
|
||||
if (backend_cups->list_printers_poll > 0)
|
||||
g_source_remove (backend_cups->list_printers_poll);
|
||||
|
||||
if (backend_cups->printers)
|
||||
g_hash_table_unref (backend_cups->printers);
|
||||
|
||||
g_free (backend_cups->default_printer);
|
||||
backend_cups->default_printer = NULL;
|
||||
|
||||
backend_parent_class->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_print_backend_cups_dispose (GObject *object)
|
||||
{
|
||||
GtkPrintBackendCups *backend_cups;
|
||||
|
||||
backend_cups = GTK_PRINT_BACKEND_CUPS (object);
|
||||
|
||||
if (backend_cups->list_printers_poll > 0)
|
||||
g_source_remove (backend_cups->list_printers_poll);
|
||||
backend_cups->list_printers_poll = 0;
|
||||
|
||||
backend_parent_class->dispose (object);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
cups_dispatch_watch_check (GSource *source)
|
||||
{
|
||||
@ -514,13 +502,12 @@ cups_dispatch_watch_check (GSource *source)
|
||||
|
||||
static gboolean
|
||||
cups_dispatch_watch_prepare (GSource *source,
|
||||
gint *timeout_)
|
||||
gint *timeout_)
|
||||
{
|
||||
GtkPrintCupsDispatchWatch *dispatch;
|
||||
|
||||
dispatch = (GtkPrintCupsDispatchWatch *) source;
|
||||
|
||||
|
||||
*timeout_ = -1;
|
||||
|
||||
return gtk_cups_request_read_write (dispatch->request);
|
||||
@ -528,8 +515,8 @@ cups_dispatch_watch_prepare (GSource *source,
|
||||
|
||||
static gboolean
|
||||
cups_dispatch_watch_dispatch (GSource *source,
|
||||
GSourceFunc callback,
|
||||
gpointer user_data)
|
||||
GSourceFunc callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkPrintCupsDispatchWatch *dispatch;
|
||||
GtkPrintCupsResponseCallbackFunc ep_callback;
|
||||
@ -548,7 +535,6 @@ cups_dispatch_watch_dispatch (GSource *source,
|
||||
|
||||
ep_callback (GTK_PRINT_BACKEND (dispatch->backend), result, user_data);
|
||||
|
||||
g_source_unref (source);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -563,7 +549,11 @@ cups_dispatch_watch_finalize (GSource *source)
|
||||
|
||||
if (dispatch->backend)
|
||||
{
|
||||
g_object_unref (dispatch->backend);
|
||||
/* We need to unref this at idle time, because it might be the
|
||||
last reference to this module causing the code to be
|
||||
unloaded (including this particular function!)
|
||||
*/
|
||||
gtk_print_backend_unref_at_idle (GTK_PRINT_BACKEND (dispatch->backend));
|
||||
dispatch->backend = NULL;
|
||||
}
|
||||
|
||||
@ -588,7 +578,7 @@ cups_request_execute (GtkPrintBackendCups *print_backend,
|
||||
GError **err)
|
||||
{
|
||||
GtkPrintCupsDispatchWatch *dispatch;
|
||||
|
||||
|
||||
dispatch = (GtkPrintCupsDispatchWatch *) g_source_new (&_cups_dispatch_watch_funcs,
|
||||
sizeof (GtkPrintCupsDispatchWatch));
|
||||
|
||||
@ -599,10 +589,11 @@ cups_request_execute (GtkPrintBackendCups *print_backend,
|
||||
g_source_set_callback ((GSource *) dispatch, (GSourceFunc) callback, user_data, notify);
|
||||
|
||||
g_source_attach ((GSource *) dispatch, NULL);
|
||||
g_source_unref ((GSource *) dispatch);
|
||||
}
|
||||
|
||||
static void
|
||||
cups_request_printer_info_cb (GtkPrintBackendCups *print_backend,
|
||||
cups_request_printer_info_cb (GtkPrintBackendCups *backend,
|
||||
GtkCupsResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
@ -611,40 +602,29 @@ cups_request_printer_info_cb (GtkPrintBackendCups *print_backend,
|
||||
gchar *printer_name;
|
||||
GtkPrinterCups *cups_printer;
|
||||
GtkPrinter *printer;
|
||||
gchar *printer_uri;
|
||||
gchar *member_printer_uri;
|
||||
gchar *loc;
|
||||
gchar *desc;
|
||||
gchar *state_msg;
|
||||
int job_count;
|
||||
|
||||
char uri[HTTP_MAX_URI], /* Printer URI */
|
||||
method[HTTP_MAX_URI], /* Method/scheme name */
|
||||
username[HTTP_MAX_URI], /* Username:password */
|
||||
hostname[HTTP_MAX_URI], /* Hostname */
|
||||
resource[HTTP_MAX_URI]; /* Resource name */
|
||||
int port; /* Port number */
|
||||
gboolean status_changed;
|
||||
|
||||
g_assert (GTK_IS_PRINT_BACKEND_CUPS (print_backend));
|
||||
|
||||
printer_uri = NULL;
|
||||
member_printer_uri = NULL;
|
||||
g_assert (GTK_IS_PRINT_BACKEND_CUPS (backend));
|
||||
|
||||
printer_name = (gchar *)user_data;
|
||||
cups_printer = (GtkPrinterCups *) g_hash_table_lookup (print_backend->printers, printer_name);
|
||||
printer = gtk_print_backend_find_printer (GTK_PRINT_BACKEND (backend),
|
||||
printer_name);
|
||||
|
||||
if (!cups_printer)
|
||||
if (!printer)
|
||||
return;
|
||||
|
||||
printer = GTK_PRINTER (cups_printer);
|
||||
cups_printer = GTK_PRINTER_CUPS (printer);
|
||||
|
||||
if (gtk_cups_result_is_error (result))
|
||||
{
|
||||
if (gtk_printer_is_new (printer))
|
||||
{
|
||||
g_hash_table_remove (print_backend->printers,
|
||||
printer_name);
|
||||
gtk_print_backend_remove_printer (GTK_PRINT_BACKEND (backend),
|
||||
printer);
|
||||
return;
|
||||
}
|
||||
else
|
||||
@ -656,8 +636,6 @@ cups_request_printer_info_cb (GtkPrintBackendCups *print_backend,
|
||||
/* TODO: determine printer type and use correct icon */
|
||||
gtk_printer_set_icon_name (printer, "printer");
|
||||
|
||||
cups_printer->device_uri = g_strdup_printf ("/printers/%s", printer_name);
|
||||
|
||||
state_msg = "";
|
||||
loc = "";
|
||||
desc = "";
|
||||
@ -670,8 +648,6 @@ cups_request_printer_info_cb (GtkPrintBackendCups *print_backend,
|
||||
_CUPS_MAP_ATTR_STR (attr, loc, "printer-location");
|
||||
_CUPS_MAP_ATTR_STR (attr, desc, "printer-info");
|
||||
_CUPS_MAP_ATTR_STR (attr, state_msg, "printer-state-message");
|
||||
_CUPS_MAP_ATTR_STR (attr, printer_uri, "printer-uri-supported");
|
||||
_CUPS_MAP_ATTR_STR (attr, member_printer_uri, "member-uris");
|
||||
_CUPS_MAP_ATTR_INT (attr, cups_printer->state, "printer-state");
|
||||
_CUPS_MAP_ATTR_INT (attr, job_count, "queued-job-count");
|
||||
}
|
||||
@ -679,53 +655,15 @@ cups_request_printer_info_cb (GtkPrintBackendCups *print_backend,
|
||||
/* if we got a member_printer_uri then this printer is part of a class
|
||||
so use member_printer_uri, else user printer_uri */
|
||||
|
||||
if (cups_printer->printer_uri)
|
||||
g_free (cups_printer->printer_uri);
|
||||
|
||||
if (member_printer_uri)
|
||||
{
|
||||
g_free (printer_uri);
|
||||
cups_printer->printer_uri = member_printer_uri;
|
||||
}
|
||||
else
|
||||
cups_printer->printer_uri = printer_uri;
|
||||
|
||||
status_changed = gtk_printer_set_job_count (printer, job_count);
|
||||
|
||||
status_changed |= gtk_printer_set_location (printer, loc);
|
||||
status_changed |= gtk_printer_set_description (printer, desc);
|
||||
status_changed |= gtk_printer_set_state_message (printer, state_msg);
|
||||
|
||||
#if (CUPS_VERSION_MAJOR == 1 && CUPS_VERSION_MINOR >= 2) || CUPS_VERSION_MAJOR > 1
|
||||
httpSeparateURI (HTTP_URI_CODING_ALL, cups_printer->printer_uri,
|
||||
method, sizeof (method),
|
||||
username, sizeof (username),
|
||||
hostname, sizeof (hostname),
|
||||
&port,
|
||||
resource, sizeof (resource));
|
||||
|
||||
#else
|
||||
httpSeparate (cups_printer->printer_uri,
|
||||
method,
|
||||
username,
|
||||
hostname,
|
||||
&port,
|
||||
resource);
|
||||
#endif
|
||||
|
||||
gethostname(uri, sizeof(uri));
|
||||
|
||||
if (strcasecmp(uri, hostname) == 0)
|
||||
strcpy(hostname, "localhost");
|
||||
|
||||
if (cups_printer->hostname)
|
||||
g_free (cups_printer->hostname);
|
||||
|
||||
cups_printer->hostname = g_strdup (hostname);
|
||||
cups_printer->port = port;
|
||||
|
||||
if (status_changed)
|
||||
g_signal_emit_by_name (GTK_PRINT_BACKEND (print_backend), "printer-status-changed", printer);
|
||||
g_signal_emit_by_name (GTK_PRINT_BACKEND (backend),
|
||||
"printer-status-changed", printer);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -735,6 +673,14 @@ cups_request_printer_info (GtkPrintBackendCups *print_backend,
|
||||
GError *error;
|
||||
GtkCupsRequest *request;
|
||||
gchar *printer_uri;
|
||||
static const char * const pattrs[] = /* Attributes we're interested in */
|
||||
{
|
||||
"printer-location",
|
||||
"printer-info",
|
||||
"printer-state-message",
|
||||
"printer-state",
|
||||
"queued-job-count"
|
||||
};
|
||||
|
||||
error = NULL;
|
||||
|
||||
@ -752,6 +698,10 @@ cups_request_printer_info (GtkPrintBackendCups *print_backend,
|
||||
|
||||
g_free (printer_uri);
|
||||
|
||||
gtk_cups_request_ipp_add_strings (request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
|
||||
"requested-attributes", G_N_ELEMENTS (pattrs),
|
||||
NULL, pattrs);
|
||||
|
||||
cups_request_execute (print_backend,
|
||||
request,
|
||||
(GtkPrintCupsResponseCallbackFunc) cups_request_printer_info_cb,
|
||||
@ -922,82 +872,22 @@ cups_begin_polling_info (GtkPrintBackendCups *print_backend,
|
||||
cups_request_job_info (data);
|
||||
}
|
||||
|
||||
static gint
|
||||
printer_cmp (GtkPrinter *a, GtkPrinter *b)
|
||||
{
|
||||
const char *name_a, *name_b;
|
||||
g_assert (GTK_IS_PRINTER (a) && GTK_IS_PRINTER (b));
|
||||
|
||||
name_a = gtk_printer_get_name (a);
|
||||
name_b = gtk_printer_get_name (b);
|
||||
if (name_a == NULL && name_b == NULL)
|
||||
return 0;
|
||||
else if (name_a == NULL)
|
||||
return G_MAXINT;
|
||||
else if (name_b == NULL)
|
||||
return G_MININT;
|
||||
else
|
||||
return g_ascii_strcasecmp (name_a, name_b);
|
||||
}
|
||||
|
||||
static void
|
||||
printer_hash_to_sorted_active_list (const gchar *key,
|
||||
gpointer value,
|
||||
GList **out_list)
|
||||
mark_printer_inactive (GtkPrinter *printer,
|
||||
GtkPrintBackend *backend)
|
||||
{
|
||||
GtkPrinter *printer;
|
||||
|
||||
printer = GTK_PRINTER (value);
|
||||
|
||||
if (gtk_printer_get_name (printer) == NULL)
|
||||
return;
|
||||
|
||||
if (!gtk_printer_is_active (printer))
|
||||
return;
|
||||
|
||||
*out_list = g_list_insert_sorted (*out_list, value, (GCompareFunc) printer_cmp);
|
||||
}
|
||||
|
||||
static void
|
||||
printer_hash_to_sorted_active_name_list (const gchar *key,
|
||||
gpointer value,
|
||||
GList **out_list)
|
||||
{
|
||||
GtkPrinter *printer;
|
||||
|
||||
printer = GTK_PRINTER (value);
|
||||
|
||||
|
||||
if (gtk_printer_get_name (printer) == NULL)
|
||||
return;
|
||||
|
||||
if (!gtk_printer_is_active (printer))
|
||||
return;
|
||||
|
||||
if (gtk_printer_is_active (printer))
|
||||
*out_list = g_list_insert_sorted (*out_list,
|
||||
(char *)gtk_printer_get_name (printer),
|
||||
g_str_equal);
|
||||
}
|
||||
|
||||
static void
|
||||
mark_printer_inactive (const gchar *printer_name,
|
||||
GtkPrintBackendCups *cups_backend)
|
||||
{
|
||||
GtkPrinter *printer;
|
||||
GHashTable *printer_hash;
|
||||
|
||||
printer_hash = cups_backend->printers;
|
||||
|
||||
printer = (GtkPrinter *) g_hash_table_lookup (printer_hash,
|
||||
printer_name);
|
||||
|
||||
if (printer == NULL)
|
||||
return;
|
||||
|
||||
gtk_printer_set_is_active (printer, FALSE);
|
||||
g_signal_emit_by_name (backend,
|
||||
"printer-removed", printer);
|
||||
}
|
||||
|
||||
g_signal_emit_by_name (GTK_PRINT_BACKEND (cups_backend), "printer-removed", printer);
|
||||
static gint
|
||||
find_printer (GtkPrinter *printer, const char *find_name)
|
||||
{
|
||||
const char *printer_name;
|
||||
|
||||
printer_name = gtk_printer_get_name (printer);
|
||||
return g_ascii_strcasecmp (printer_name, find_name);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1021,51 +911,122 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend,
|
||||
g_warning ("Error getting printer list: %s", gtk_cups_result_get_error_string (result));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* gether the names of the printers in the current queue
|
||||
so we may check to see if they were removed */
|
||||
removed_printer_checklist = NULL;
|
||||
if (cups_backend->printers != NULL)
|
||||
g_hash_table_foreach (cups_backend->printers,
|
||||
(GHFunc) printer_hash_to_sorted_active_name_list,
|
||||
&removed_printer_checklist);
|
||||
|
||||
removed_printer_checklist = gtk_print_backend_get_printer_list (GTK_PRINT_BACKEND (cups_backend));
|
||||
|
||||
response = gtk_cups_result_get_response (result);
|
||||
|
||||
attr = ippFindAttribute (response, "printer-name", IPP_TAG_NAME);
|
||||
|
||||
while (attr)
|
||||
for (attr = response->attrs; attr != NULL; attr = attr->next)
|
||||
{
|
||||
GtkPrinterCups *cups_printer;
|
||||
GtkPrinter *printer;
|
||||
const gchar *printer_name;
|
||||
const char *printer_uri;
|
||||
const char *member_uris;
|
||||
GList *node;
|
||||
|
||||
/*
|
||||
* Skip leading attributes until we hit a printer...
|
||||
*/
|
||||
while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
|
||||
attr = attr->next;
|
||||
|
||||
printer_name = attr->values[0].string.text;
|
||||
if (attr == NULL)
|
||||
break;
|
||||
|
||||
printer_name = NULL;
|
||||
printer_uri = NULL;
|
||||
member_uris = NULL;
|
||||
while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
|
||||
{
|
||||
if (!strcmp(attr->name, "printer-name") &&
|
||||
attr->value_tag == IPP_TAG_NAME)
|
||||
printer_name = attr->values[0].string.text;
|
||||
else if (!strcmp(attr->name, "printer-uri-supported") &&
|
||||
attr->value_tag == IPP_TAG_URI)
|
||||
printer_uri = attr->values[0].string.text;
|
||||
else if (!strcmp(attr->name, "member-uris") &&
|
||||
attr->value_tag == IPP_TAG_URI)
|
||||
member_uris = attr->values[0].string.text;
|
||||
|
||||
attr = attr->next;
|
||||
}
|
||||
|
||||
if (printer_name == NULL ||
|
||||
(printer_uri == NULL && member_uris == NULL))
|
||||
{
|
||||
if (attr == NULL)
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
/* remove name from checklist if it was found */
|
||||
node = g_list_find_custom (removed_printer_checklist, printer_name, (GCompareFunc) g_ascii_strcasecmp);
|
||||
node = g_list_find_custom (removed_printer_checklist, printer_name, (GCompareFunc) find_printer);
|
||||
removed_printer_checklist = g_list_delete_link (removed_printer_checklist, node);
|
||||
|
||||
cups_printer = (GtkPrinterCups *) g_hash_table_lookup (cups_backend->printers,
|
||||
printer_name);
|
||||
printer = cups_printer ? GTK_PRINTER (cups_printer) : NULL;
|
||||
|
||||
if (!cups_printer)
|
||||
printer = gtk_print_backend_find_printer (GTK_PRINT_BACKEND (cups_backend), printer_name);
|
||||
if (!printer)
|
||||
{
|
||||
GtkPrinterCups *cups_printer;
|
||||
char uri[HTTP_MAX_URI], /* Printer URI */
|
||||
method[HTTP_MAX_URI], /* Method/scheme name */
|
||||
username[HTTP_MAX_URI], /* Username:password */
|
||||
hostname[HTTP_MAX_URI], /* Hostname */
|
||||
resource[HTTP_MAX_URI]; /* Resource name */
|
||||
int port; /* Port number */
|
||||
|
||||
list_has_changed = TRUE;
|
||||
cups_printer = gtk_printer_cups_new (attr->values[0].string.text,
|
||||
cups_printer = gtk_printer_cups_new (printer_name,
|
||||
GTK_PRINT_BACKEND (cups_backend));
|
||||
printer = GTK_PRINTER (cups_printer);
|
||||
|
||||
cups_printer->device_uri = g_strdup_printf ("/printers/%s", printer_name);
|
||||
|
||||
if (member_uris)
|
||||
{
|
||||
cups_printer->printer_uri = g_strdup (member_uris);
|
||||
}
|
||||
else
|
||||
cups_printer->printer_uri = g_strdup (printer_uri);
|
||||
|
||||
#if (CUPS_VERSION_MAJOR == 1 && CUPS_VERSION_MINOR >= 2) || CUPS_VERSION_MAJOR > 1
|
||||
httpSeparateURI (HTTP_URI_CODING_ALL, cups_printer->printer_uri,
|
||||
method, sizeof (method),
|
||||
username, sizeof (username),
|
||||
hostname, sizeof (hostname),
|
||||
&port,
|
||||
resource, sizeof (resource));
|
||||
|
||||
#else
|
||||
httpSeparate (cups_printer->printer_uri,
|
||||
method,
|
||||
username,
|
||||
hostname,
|
||||
&port,
|
||||
resource);
|
||||
#endif
|
||||
|
||||
gethostname(uri, sizeof(uri));
|
||||
if (strcasecmp(uri, hostname) == 0)
|
||||
strcpy(hostname, "localhost");
|
||||
|
||||
cups_printer->hostname = g_strdup (hostname);
|
||||
cups_printer->port = port;
|
||||
|
||||
printer = GTK_PRINTER (cups_printer);
|
||||
|
||||
if (cups_backend->default_printer != NULL &&
|
||||
strcmp (cups_backend->default_printer, gtk_printer_get_name (printer)) == 0)
|
||||
gtk_printer_set_is_default (printer, TRUE);
|
||||
|
||||
g_hash_table_insert (cups_backend->printers,
|
||||
g_strdup (gtk_printer_get_name (printer)),
|
||||
cups_printer);
|
||||
|
||||
gtk_print_backend_add_printer (GTK_PRINT_BACKEND (cups_backend), printer);
|
||||
}
|
||||
|
||||
else
|
||||
g_object_ref (printer);
|
||||
|
||||
if (!gtk_printer_is_active (printer))
|
||||
{
|
||||
gtk_printer_set_is_active (printer, TRUE);
|
||||
@ -1083,25 +1044,29 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend,
|
||||
}
|
||||
|
||||
cups_request_printer_info (cups_backend, gtk_printer_get_name (printer));
|
||||
|
||||
/* The ref is held by GtkPrintBackend, in add_printer() */
|
||||
g_object_unref (printer);
|
||||
|
||||
|
||||
attr = ippFindNextAttribute (response,
|
||||
"printer-name",
|
||||
IPP_TAG_NAME);
|
||||
if (attr == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
/* look at the removed printers checklist and mark any printer
|
||||
as inactive if it is in the list, emitting a printer_removed signal */
|
||||
|
||||
if (removed_printer_checklist != NULL)
|
||||
{
|
||||
g_list_foreach (removed_printer_checklist, (GFunc) mark_printer_inactive, cups_backend);
|
||||
g_list_free (removed_printer_checklist);
|
||||
list_has_changed = TRUE;
|
||||
}
|
||||
|
||||
if (list_has_changed)
|
||||
g_signal_emit_by_name (GTK_PRINT_BACKEND (cups_backend), "printer-list-changed");
|
||||
|
||||
/* look at the removed printers checklist and mark any printer
|
||||
as inactive if it is in the list, emitting a printer_removed signal */
|
||||
if (removed_printer_checklist != NULL)
|
||||
{
|
||||
g_list_foreach (removed_printer_checklist, (GFunc) mark_printer_inactive,
|
||||
GTK_PRINT_BACKEND (cups_backend));
|
||||
g_list_free (removed_printer_checklist);
|
||||
list_has_changed = TRUE;
|
||||
}
|
||||
|
||||
if (list_has_changed)
|
||||
g_signal_emit_by_name (GTK_PRINT_BACKEND (cups_backend), "printer-list-changed");
|
||||
|
||||
gtk_print_backend_set_list_done (GTK_PRINT_BACKEND (cups_backend));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -1109,7 +1074,13 @@ cups_request_printer_list (GtkPrintBackendCups *cups_backend)
|
||||
{
|
||||
GError *error;
|
||||
GtkCupsRequest *request;
|
||||
|
||||
static const char * const pattrs[] = /* Attributes we're interested in */
|
||||
{
|
||||
"printer-name",
|
||||
"printer-uri-supported",
|
||||
"member-uris"
|
||||
};
|
||||
|
||||
if (cups_backend->list_printers_pending ||
|
||||
!cups_backend->got_default_printer)
|
||||
return TRUE;
|
||||
@ -1125,6 +1096,10 @@ cups_request_printer_list (GtkPrintBackendCups *cups_backend)
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
gtk_cups_request_ipp_add_strings (request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
|
||||
"requested-attributes", G_N_ELEMENTS (pattrs),
|
||||
NULL, pattrs);
|
||||
|
||||
cups_request_execute (cups_backend,
|
||||
request,
|
||||
(GtkPrintCupsResponseCallbackFunc) cups_request_printer_list_cb,
|
||||
@ -1136,29 +1111,19 @@ cups_request_printer_list (GtkPrintBackendCups *cups_backend)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GList *
|
||||
cups_get_printer_list (GtkPrintBackend *print_backend)
|
||||
static void
|
||||
cups_get_printer_list (GtkPrintBackend *backend)
|
||||
{
|
||||
GtkPrintBackendCups *cups_backend;
|
||||
GList *result;
|
||||
|
||||
cups_backend = GTK_PRINT_BACKEND_CUPS (print_backend);
|
||||
|
||||
result = NULL;
|
||||
if (cups_backend->printers != NULL)
|
||||
g_hash_table_foreach (cups_backend->printers,
|
||||
(GHFunc) printer_hash_to_sorted_active_list,
|
||||
&result);
|
||||
|
||||
cups_backend = GTK_PRINT_BACKEND_CUPS (backend);
|
||||
if (cups_backend->list_printers_poll == 0)
|
||||
{
|
||||
cups_request_printer_list (cups_backend);
|
||||
cups_backend->list_printers_poll = g_timeout_add (3000,
|
||||
cups_backend->list_printers_poll = g_timeout_add (3000 * 100000,
|
||||
(GSourceFunc) cups_request_printer_list,
|
||||
print_backend);
|
||||
backend);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
@ -90,8 +90,7 @@ gtk_printer_cups_finalize (GObject *object)
|
||||
if (printer->ppd_file)
|
||||
ppdClose (printer->ppd_file);
|
||||
|
||||
if (G_OBJECT_CLASS (gtk_printer_cups_parent_class)->finalize)
|
||||
G_OBJECT_CLASS (gtk_printer_cups_parent_class)->finalize (object);
|
||||
G_OBJECT_CLASS (gtk_printer_cups_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -51,25 +51,18 @@ static GType print_backend_lpr_type = 0;
|
||||
|
||||
struct _GtkPrintBackendLprClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
GtkPrintBackendClass parent_class;
|
||||
};
|
||||
|
||||
struct _GtkPrintBackendLpr
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GtkPrinter *printer;
|
||||
|
||||
GHashTable *printers;
|
||||
GtkPrintBackend parent_instance;
|
||||
};
|
||||
|
||||
static GObjectClass *backend_parent_class;
|
||||
|
||||
static void gtk_print_backend_lpr_class_init (GtkPrintBackendLprClass *class);
|
||||
static void gtk_print_backend_lpr_iface_init (GtkPrintBackendIface *iface);
|
||||
static void gtk_print_backend_lpr_init (GtkPrintBackendLpr *impl);
|
||||
static void gtk_print_backend_lpr_finalize (GObject *object);
|
||||
static GList * lpr_request_printer_list (GtkPrintBackend *print_backend);
|
||||
static void lpr_printer_get_settings_from_options (GtkPrinter *printer,
|
||||
GtkPrinterOptionSet *options,
|
||||
GtkPrintSettings *settings);
|
||||
@ -89,6 +82,16 @@ static void lpr_printer_get_hard_margins (GtkPrinter
|
||||
double *right);
|
||||
static void lpr_printer_request_details (GtkPrinter *printer);
|
||||
static GList * lpr_printer_list_papers (GtkPrinter *printer);
|
||||
static cairo_surface_t * lpr_printer_create_cairo_surface (GtkPrinter *printer,
|
||||
gdouble width,
|
||||
gdouble height,
|
||||
gint cache_fd);
|
||||
static void gtk_print_backend_lpr_print_stream (GtkPrintBackend *print_backend,
|
||||
GtkPrintJob *job,
|
||||
gint data_fd,
|
||||
GtkPrintJobCompleteFunc callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify dnotify);
|
||||
|
||||
static void
|
||||
gtk_print_backend_lpr_register_type (GTypeModule *module)
|
||||
@ -108,24 +111,11 @@ gtk_print_backend_lpr_register_type (GTypeModule *module)
|
||||
(GInstanceInitFunc) gtk_print_backend_lpr_init,
|
||||
};
|
||||
|
||||
static const GInterfaceInfo print_backend_info =
|
||||
{
|
||||
(GInterfaceInitFunc) gtk_print_backend_lpr_iface_init, /* interface_init */
|
||||
NULL, /* interface_finalize */
|
||||
NULL /* interface_data */
|
||||
};
|
||||
|
||||
print_backend_lpr_type = g_type_module_register_type (module,
|
||||
G_TYPE_OBJECT,
|
||||
"GtkPrintBackendLpr",
|
||||
&print_backend_lpr_info, 0);
|
||||
g_type_module_add_interface (module,
|
||||
print_backend_lpr_type,
|
||||
GTK_TYPE_PRINT_BACKEND,
|
||||
&print_backend_info);
|
||||
GTK_TYPE_PRINT_BACKEND,
|
||||
"GtkPrintBackendLpr",
|
||||
&print_backend_lpr_info, 0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT void
|
||||
@ -173,11 +163,19 @@ gtk_print_backend_lpr_new (void)
|
||||
static void
|
||||
gtk_print_backend_lpr_class_init (GtkPrintBackendLprClass *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_lpr_finalize;
|
||||
backend_class->print_stream = gtk_print_backend_lpr_print_stream;
|
||||
backend_class->printer_request_details = lpr_printer_request_details;
|
||||
backend_class->printer_create_cairo_surface = lpr_printer_create_cairo_surface;
|
||||
backend_class->printer_get_options = lpr_printer_get_options;
|
||||
backend_class->printer_mark_conflicts = lpr_printer_mark_conflicts;
|
||||
backend_class->printer_get_settings_from_options = lpr_printer_get_settings_from_options;
|
||||
backend_class->printer_prepare_for_print = lpr_printer_prepare_for_print;
|
||||
backend_class->printer_list_papers = lpr_printer_list_papers;
|
||||
backend_class->printer_get_hard_margins = lpr_printer_get_hard_margins;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -215,22 +213,6 @@ lpr_printer_create_cairo_surface (GtkPrinter *printer,
|
||||
return surface;
|
||||
}
|
||||
|
||||
static GtkPrinter *
|
||||
gtk_print_backend_lpr_find_printer (GtkPrintBackend *print_backend,
|
||||
const gchar *printer_name)
|
||||
{
|
||||
GtkPrintBackendLpr *lpr_print_backend;
|
||||
GtkPrinter *printer;
|
||||
|
||||
lpr_print_backend = GTK_PRINT_BACKEND_LPR (print_backend);
|
||||
|
||||
printer = NULL;
|
||||
if (strcmp (gtk_printer_get_name (lpr_print_backend->printer), printer_name) == 0)
|
||||
printer = lpr_print_backend->printer;
|
||||
|
||||
return printer;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GtkPrintBackend *backend;
|
||||
GtkPrintJobCompleteFunc callback;
|
||||
@ -398,64 +380,21 @@ gtk_print_backend_lpr_print_stream (GtkPrintBackend *print_backend,
|
||||
g_strfreev (argv);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gtk_print_backend_lpr_iface_init (GtkPrintBackendIface *iface)
|
||||
{
|
||||
iface->get_printer_list = lpr_request_printer_list;
|
||||
iface->find_printer = gtk_print_backend_lpr_find_printer;
|
||||
iface->print_stream = gtk_print_backend_lpr_print_stream;
|
||||
iface->printer_request_details = lpr_printer_request_details;
|
||||
iface->printer_create_cairo_surface = lpr_printer_create_cairo_surface;
|
||||
iface->printer_get_options = lpr_printer_get_options;
|
||||
iface->printer_mark_conflicts = lpr_printer_mark_conflicts;
|
||||
iface->printer_get_settings_from_options = lpr_printer_get_settings_from_options;
|
||||
iface->printer_prepare_for_print = lpr_printer_prepare_for_print;
|
||||
iface->printer_list_papers = lpr_printer_list_papers;
|
||||
iface->printer_get_hard_margins = lpr_printer_get_hard_margins;
|
||||
}
|
||||
|
||||
static GList *
|
||||
lpr_request_printer_list (GtkPrintBackend *backend)
|
||||
{
|
||||
GList *l;
|
||||
GtkPrintBackendLpr *lpr_backend;
|
||||
|
||||
l = NULL;
|
||||
|
||||
lpr_backend = GTK_PRINT_BACKEND_LPR (backend);
|
||||
|
||||
if (lpr_backend->printer)
|
||||
l = g_list_append (l, lpr_backend->printer);
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_print_backend_lpr_init (GtkPrintBackendLpr *backend_lpr)
|
||||
gtk_print_backend_lpr_init (GtkPrintBackendLpr *backend)
|
||||
{
|
||||
GtkPrinter *printer;
|
||||
|
||||
printer = gtk_printer_new (_("Print to LPR"),
|
||||
GTK_PRINT_BACKEND (backend_lpr),
|
||||
GTK_PRINT_BACKEND (backend),
|
||||
TRUE);
|
||||
gtk_printer_set_has_details (printer, TRUE);
|
||||
gtk_printer_set_icon_name (printer, "printer");
|
||||
gtk_printer_set_is_active (printer, TRUE);
|
||||
|
||||
backend_lpr->printer = printer;
|
||||
}
|
||||
gtk_printer_set_is_default (printer, TRUE);
|
||||
|
||||
static void
|
||||
gtk_print_backend_lpr_finalize (GObject *object)
|
||||
{
|
||||
GtkPrintBackendLpr *backend_lpr;
|
||||
|
||||
backend_lpr = GTK_PRINT_BACKEND_LPR (object);
|
||||
|
||||
g_object_unref (backend_lpr->printer);
|
||||
|
||||
backend_parent_class->finalize (object);
|
||||
gtk_print_backend_add_printer (GTK_PRINT_BACKEND (backend), printer);
|
||||
g_object_unref (printer);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -52,25 +52,18 @@ static GType print_backend_pdf_type = 0;
|
||||
|
||||
struct _GtkPrintBackendPdfClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
GtkPrintBackendClass parent_class;
|
||||
};
|
||||
|
||||
struct _GtkPrintBackendPdf
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GtkPrinter *printer;
|
||||
|
||||
GHashTable *printers;
|
||||
GtkPrintBackend parent_instance;
|
||||
};
|
||||
|
||||
static GObjectClass *backend_parent_class;
|
||||
|
||||
static void gtk_print_backend_pdf_class_init (GtkPrintBackendPdfClass *class);
|
||||
static void gtk_print_backend_pdf_iface_init (GtkPrintBackendIface *iface);
|
||||
static void gtk_print_backend_pdf_init (GtkPrintBackendPdf *impl);
|
||||
static void gtk_print_backend_pdf_finalize (GObject *object);
|
||||
static GList * pdf_request_printer_list (GtkPrintBackend *print_backend);
|
||||
static void pdf_printer_get_settings_from_options (GtkPrinter *printer,
|
||||
GtkPrinterOptionSet *options,
|
||||
GtkPrintSettings *settings);
|
||||
@ -90,6 +83,16 @@ static void pdf_printer_get_hard_margins (GtkPrinter
|
||||
double *right);
|
||||
static void pdf_printer_request_details (GtkPrinter *printer);
|
||||
static GList * pdf_printer_list_papers (GtkPrinter *printer);
|
||||
static void gtk_print_backend_pdf_print_stream (GtkPrintBackend *print_backend,
|
||||
GtkPrintJob *job,
|
||||
gint data_fd,
|
||||
GtkPrintJobCompleteFunc callback,
|
||||
gpointer user_data,
|
||||
GDestroyNotify dnotify);
|
||||
static cairo_surface_t * pdf_printer_create_cairo_surface (GtkPrinter *printer,
|
||||
gdouble width,
|
||||
gdouble height,
|
||||
gint cache_fd);
|
||||
|
||||
static void
|
||||
gtk_print_backend_pdf_register_type (GTypeModule *module)
|
||||
@ -109,24 +112,11 @@ gtk_print_backend_pdf_register_type (GTypeModule *module)
|
||||
(GInstanceInitFunc) gtk_print_backend_pdf_init,
|
||||
};
|
||||
|
||||
static const GInterfaceInfo print_backend_info =
|
||||
{
|
||||
(GInterfaceInitFunc) gtk_print_backend_pdf_iface_init, /* interface_init */
|
||||
NULL, /* interface_finalize */
|
||||
NULL /* interface_data */
|
||||
};
|
||||
|
||||
print_backend_pdf_type = g_type_module_register_type (module,
|
||||
G_TYPE_OBJECT,
|
||||
"GtkPrintBackendPdf",
|
||||
&print_backend_pdf_info, 0);
|
||||
g_type_module_add_interface (module,
|
||||
print_backend_pdf_type,
|
||||
GTK_TYPE_PRINT_BACKEND,
|
||||
&print_backend_info);
|
||||
GTK_TYPE_PRINT_BACKEND,
|
||||
"GtkPrintBackendPdf",
|
||||
&print_backend_pdf_info, 0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT void
|
||||
@ -174,11 +164,19 @@ gtk_print_backend_pdf_new (void)
|
||||
static void
|
||||
gtk_print_backend_pdf_class_init (GtkPrintBackendPdfClass *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_pdf_finalize;
|
||||
backend_class->print_stream = gtk_print_backend_pdf_print_stream;
|
||||
backend_class->printer_request_details = pdf_printer_request_details;
|
||||
backend_class->printer_create_cairo_surface = pdf_printer_create_cairo_surface;
|
||||
backend_class->printer_get_options = pdf_printer_get_options;
|
||||
backend_class->printer_mark_conflicts = pdf_printer_mark_conflicts;
|
||||
backend_class->printer_get_settings_from_options = pdf_printer_get_settings_from_options;
|
||||
backend_class->printer_prepare_for_print = pdf_printer_prepare_for_print;
|
||||
backend_class->printer_list_papers = pdf_printer_list_papers;
|
||||
backend_class->printer_get_hard_margins = pdf_printer_get_hard_margins;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -216,22 +214,6 @@ pdf_printer_create_cairo_surface (GtkPrinter *printer,
|
||||
return surface;
|
||||
}
|
||||
|
||||
static GtkPrinter *
|
||||
gtk_print_backend_pdf_find_printer (GtkPrintBackend *print_backend,
|
||||
const gchar *printer_name)
|
||||
{
|
||||
GtkPrintBackendPdf *pdf_print_backend;
|
||||
GtkPrinter *printer;
|
||||
|
||||
pdf_print_backend = GTK_PRINT_BACKEND_PDF (print_backend);
|
||||
|
||||
printer = NULL;
|
||||
if (strcmp (gtk_printer_get_name (pdf_print_backend->printer), printer_name) == 0)
|
||||
printer = pdf_print_backend->printer;
|
||||
|
||||
return printer;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GtkPrintBackend *backend;
|
||||
GtkPrintJobCompleteFunc callback;
|
||||
@ -366,64 +348,23 @@ gtk_print_backend_pdf_print_stream (GtkPrintBackend *print_backend,
|
||||
ps);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gtk_print_backend_pdf_iface_init (GtkPrintBackendIface *iface)
|
||||
{
|
||||
iface->get_printer_list = pdf_request_printer_list;
|
||||
iface->find_printer = gtk_print_backend_pdf_find_printer;
|
||||
iface->print_stream = gtk_print_backend_pdf_print_stream;
|
||||
iface->printer_request_details = pdf_printer_request_details;
|
||||
iface->printer_create_cairo_surface = pdf_printer_create_cairo_surface;
|
||||
iface->printer_get_options = pdf_printer_get_options;
|
||||
iface->printer_mark_conflicts = pdf_printer_mark_conflicts;
|
||||
iface->printer_get_settings_from_options = pdf_printer_get_settings_from_options;
|
||||
iface->printer_prepare_for_print = pdf_printer_prepare_for_print;
|
||||
iface->printer_list_papers = pdf_printer_list_papers;
|
||||
iface->printer_get_hard_margins = pdf_printer_get_hard_margins;
|
||||
}
|
||||
|
||||
static GList *
|
||||
pdf_request_printer_list (GtkPrintBackend *backend)
|
||||
{
|
||||
GList *l;
|
||||
GtkPrintBackendPdf *pdf_backend;
|
||||
|
||||
l = NULL;
|
||||
|
||||
pdf_backend = GTK_PRINT_BACKEND_PDF (backend);
|
||||
|
||||
if (pdf_backend->printer)
|
||||
l = g_list_append (l, pdf_backend->printer);
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_print_backend_pdf_init (GtkPrintBackendPdf *backend_pdf)
|
||||
gtk_print_backend_pdf_init (GtkPrintBackendPdf *backend)
|
||||
{
|
||||
GtkPrinter *printer;
|
||||
|
||||
backend_pdf->printer = gtk_printer_new (_("Print to PDF"),
|
||||
GTK_PRINT_BACKEND (backend_pdf),
|
||||
TRUE);
|
||||
printer = gtk_printer_new (_("Print to PDF"),
|
||||
GTK_PRINT_BACKEND (backend),
|
||||
TRUE);
|
||||
|
||||
printer = backend_pdf->printer;
|
||||
gtk_printer_set_has_details (printer, TRUE);
|
||||
gtk_printer_set_icon_name (printer, "floppy");
|
||||
gtk_printer_set_is_active (printer, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_print_backend_pdf_finalize (GObject *object)
|
||||
{
|
||||
GtkPrintBackendPdf *backend_pdf;
|
||||
gtk_print_backend_add_printer (GTK_PRINT_BACKEND (backend), printer);
|
||||
g_object_unref (printer);
|
||||
|
||||
backend_pdf = GTK_PRINT_BACKEND_PDF (object);
|
||||
|
||||
g_object_unref (backend_pdf->printer);
|
||||
|
||||
backend_parent_class->finalize (object);
|
||||
gtk_print_backend_set_list_done (GTK_PRINT_BACKEND (backend));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -53,6 +53,7 @@ noinst_PROGRAMS = \
|
||||
testmultidisplay \
|
||||
testmultiscreen \
|
||||
testnotebookdnd \
|
||||
testnouiprint \
|
||||
testrgb \
|
||||
testrecentchooser \
|
||||
testselection \
|
||||
@ -107,6 +108,7 @@ testmenubars_DEPENDENCIES = $(TEST_DEPS)
|
||||
testmultidisplay_DEPENDENCIES = $(TEST_DEPS)
|
||||
testmultiscreen_DEPENDENCIES = $(TEST_DEPS)
|
||||
testnotebookdnd_DEPENDENCIES = $(TEST_DEPS)
|
||||
testnouiprint_DEPENDENCIES = $(TEST_DEPS)
|
||||
testrecentchooser_DEPENDENCIES = $(TEST_DEPS)
|
||||
testrgb_DEPENDENCIES = $(TEST_DEPS)
|
||||
testselection_DEPENDENCIES = $(TEST_DEPS)
|
||||
@ -155,6 +157,7 @@ testmenubars_LDADD = $(LDADDS)
|
||||
testmultidisplay_LDADD = $(LDADDS)
|
||||
testmultiscreen_LDADD = $(LDADDS)
|
||||
testnotebookdnd_LDADD = $(LDADDS)
|
||||
testnouiprint_LDADD = $(LDADDS)
|
||||
testrecentchooser_LDADD = $(LDADDS)
|
||||
testrgb_LDADD = $(LDADDS)
|
||||
testselection_LDADD = $(LDADDS)
|
||||
|
107
tests/testnouiprint.c
Normal file
107
tests/testnouiprint.c
Normal file
@ -0,0 +1,107 @@
|
||||
/* -*- Mode: C; c-basic-offset: 2; -*- */
|
||||
/* Gtk+ - non-ui printing
|
||||
*
|
||||
* Copyright (C) 2006 Alexander Larsson <alexl@redhat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "gtk/gtkprintoperation.h"
|
||||
#include <math.h>
|
||||
|
||||
static void
|
||||
draw_page (GtkPrintOperation *operation,
|
||||
GtkPrintContext *context,
|
||||
int page_nr)
|
||||
{
|
||||
cairo_t *cr;
|
||||
PangoLayout *layout;
|
||||
PangoFontDescription *desc;
|
||||
|
||||
cr = gtk_print_context_get_cairo (context);
|
||||
|
||||
/* Draw a red rectangle, as wide as the paper (inside the margins) */
|
||||
cairo_set_source_rgb (cr, 1.0, 0, 0);
|
||||
cairo_rectangle (cr, 0, 0, gtk_print_context_get_width (context), 50);
|
||||
|
||||
cairo_fill (cr);
|
||||
|
||||
/* Draw some lines */
|
||||
cairo_move_to (cr, 20, 10);
|
||||
cairo_line_to (cr, 40, 20);
|
||||
cairo_arc (cr, 60, 60, 20, 0, M_PI);
|
||||
cairo_line_to (cr, 80, 20);
|
||||
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
cairo_set_line_width (cr, 5);
|
||||
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
|
||||
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
|
||||
|
||||
cairo_stroke (cr);
|
||||
|
||||
/* Draw some text */
|
||||
|
||||
layout = gtk_print_context_create_layout (context);
|
||||
pango_layout_set_text (layout, "Hello World! Printing is easy", -1);
|
||||
desc = pango_font_description_from_string ("sans 28");
|
||||
pango_layout_set_font_description (layout, desc);
|
||||
pango_font_description_free (desc);
|
||||
|
||||
cairo_move_to (cr, 30, 20);
|
||||
pango_cairo_layout_path (cr, layout);
|
||||
|
||||
/* Font Outline */
|
||||
cairo_set_source_rgb (cr, 0.93, 1.0, 0.47);
|
||||
cairo_set_line_width (cr, 0.5);
|
||||
cairo_stroke_preserve (cr);
|
||||
|
||||
/* Font Fill */
|
||||
cairo_set_source_rgb (cr, 0, 0.0, 1.0);
|
||||
cairo_fill (cr);
|
||||
|
||||
g_object_unref (layout);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
GMainLoop *loop;
|
||||
GtkPrintOperation *print;
|
||||
GtkPrintOperationResult res;
|
||||
GtkPrintSettings *settings;
|
||||
|
||||
|
||||
/* Unfortunately we need a display for the XSettings to get the
|
||||
list of backends... */
|
||||
/* gtk_parse_args (&argc, &argv); */
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
loop = g_main_loop_new (NULL, TRUE);
|
||||
|
||||
settings = gtk_print_settings_new ();
|
||||
/* gtk_print_settings_set_printer (settings, "printer"); */
|
||||
|
||||
print = gtk_print_operation_new ();
|
||||
gtk_print_operation_set_print_settings (print, settings);
|
||||
gtk_print_operation_set_nr_of_pages (print, 1);
|
||||
gtk_print_operation_set_unit (print, GTK_UNIT_MM);
|
||||
gtk_print_operation_set_show_dialog (print, FALSE);
|
||||
g_signal_connect (print, "draw_page", G_CALLBACK (draw_page), NULL);
|
||||
res = gtk_print_operation_run (print, NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user