forked from AuroraMiddleware/gtk
wip: print op implementation
This does not work well
This commit is contained in:
parent
87a6033476
commit
2e95b13be5
@ -25,6 +25,9 @@
|
||||
#include "gtkdialogerror.h"
|
||||
#include "gtkprivate.h"
|
||||
|
||||
#include "gtkprintoperation.h"
|
||||
#include "gtkprintoperation-private.h"
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <gio/gfiledescriptorbased.h>
|
||||
#include <gio/gunixfdlist.h>
|
||||
@ -52,17 +55,18 @@ struct _GtkPrintDialog
|
||||
GtkPrintSettings *print_settings;
|
||||
GtkPageSetup *default_page_setup;
|
||||
|
||||
GDBusProxy *portal;
|
||||
|
||||
GtkWindow *exported_window;
|
||||
char *title;
|
||||
unsigned int modal : 1;
|
||||
|
||||
/* portal implementation */
|
||||
GDBusProxy *portal;
|
||||
char *portal_handle;
|
||||
unsigned int token;
|
||||
unsigned int response_signal_id;
|
||||
|
||||
char *title;
|
||||
|
||||
unsigned int modal : 1;
|
||||
/* print operation implementation */
|
||||
GtkPrintOperation *op;
|
||||
};
|
||||
|
||||
enum
|
||||
@ -97,6 +101,8 @@ gtk_print_dialog_finalize (GObject *object)
|
||||
g_clear_object (&self->default_page_setup);
|
||||
g_free (self->title);
|
||||
|
||||
g_clear_object (&self->op);
|
||||
|
||||
G_OBJECT_CLASS (gtk_print_dialog_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@ -378,7 +384,7 @@ gtk_print_dialog_set_title (GtkPrintDialog *self,
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ Async implementation */
|
||||
/* {{{ Async implementation, portal */
|
||||
|
||||
static void
|
||||
send_close (GTask *task)
|
||||
@ -409,9 +415,11 @@ send_close (GTask *task)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ensure_portal_proxy (GtkPrintDialog *self,
|
||||
GError **error)
|
||||
ensure_portal_proxy (GtkPrintDialog *self)
|
||||
{
|
||||
if (gdk_display_get_debug_flags (NULL) & GDK_DEBUG_NO_PORTALS)
|
||||
return FALSE;
|
||||
|
||||
if (!self->portal)
|
||||
self->portal = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
|
||||
G_DBUS_PROXY_FLAGS_NONE,
|
||||
@ -420,7 +428,7 @@ ensure_portal_proxy (GtkPrintDialog *self,
|
||||
PORTAL_OBJECT_PATH,
|
||||
PORTAL_PRINT_INTERFACE,
|
||||
NULL,
|
||||
error);
|
||||
NULL);
|
||||
|
||||
return self->portal != NULL;
|
||||
}
|
||||
@ -793,6 +801,54 @@ print_window_handle_exported (GtkWindow *window,
|
||||
g_free (token);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ Async implementation, op */
|
||||
|
||||
static void
|
||||
ensure_print_op (GtkPrintDialog *self)
|
||||
{
|
||||
if (!self->op)
|
||||
{
|
||||
self->op = gtk_print_operation_new ();
|
||||
gtk_print_operation_set_allow_async (self->op, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_pages (GtkPrintOperation *op,
|
||||
GtkWindow *parent,
|
||||
gboolean do_print,
|
||||
GtkPrintOperationResult result)
|
||||
{
|
||||
GtkPrintOperationPrivate *priv = op->priv;
|
||||
GTask *task = g_object_get_data (G_OBJECT (op), "task");
|
||||
GtkPrintDialog *self = GTK_PRINT_DIALOG (g_task_get_source_object (task));
|
||||
|
||||
g_print ("print_pages do_print == %d, result %d\n", do_print, result);
|
||||
g_print ("op refcount %d\n", G_OBJECT (self->op)->ref_count);
|
||||
if (!do_print)
|
||||
{
|
||||
if (priv->error)
|
||||
g_task_return_error (task, g_error_copy (priv->error));
|
||||
else if (priv->cancelled)
|
||||
g_task_return_new_error (task, GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_DISMISSED, "Dismissed by user");
|
||||
else
|
||||
{
|
||||
gtk_print_dialog_set_print_settings (self, gtk_print_operation_get_print_settings (op));
|
||||
gtk_print_dialog_set_default_page_setup (self, gtk_print_operation_get_default_page_setup (op));
|
||||
g_task_return_boolean (task, TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_print_dialog_set_print_settings (self, gtk_print_operation_get_print_settings (op));
|
||||
gtk_print_dialog_set_default_page_setup (self, gtk_print_operation_get_default_page_setup (op));
|
||||
g_task_return_boolean (task, TRUE);
|
||||
}
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ Async API */
|
||||
|
||||
@ -822,7 +878,6 @@ gtk_print_dialog_prepare_print (GtkPrintDialog *self,
|
||||
gpointer user_data)
|
||||
{
|
||||
GTask *task;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_if_fail (GTK_IS_PRINT_DIALOG (self));
|
||||
g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
|
||||
@ -833,10 +888,16 @@ gtk_print_dialog_prepare_print (GtkPrintDialog *self,
|
||||
g_task_set_check_cancellable (task, FALSE);
|
||||
g_task_set_source_tag (task, gtk_print_dialog_prepare_print);
|
||||
|
||||
if (!ensure_portal_proxy (self, &error))
|
||||
if (!ensure_portal_proxy (self))
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
ensure_print_op (self);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (self->op), "task", task, g_object_unref);
|
||||
g_print ("op refcount %d\n", G_OBJECT (self->op)->ref_count);
|
||||
_gtk_print_operation_platform_backend_run_dialog_async (self->op,
|
||||
TRUE,
|
||||
parent,
|
||||
print_pages);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -906,7 +967,6 @@ gtk_print_dialog_print_stream (GtkPrintDialog *self,
|
||||
gpointer user_data)
|
||||
{
|
||||
GTask *task;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_if_fail (GTK_IS_PRINT_DIALOG (self));
|
||||
g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
|
||||
@ -919,10 +979,33 @@ gtk_print_dialog_print_stream (GtkPrintDialog *self,
|
||||
g_task_set_source_tag (task, gtk_print_dialog_print_stream);
|
||||
g_task_set_task_data (task, g_object_ref (content), g_object_unref);
|
||||
|
||||
if (!ensure_portal_proxy (self, &error))
|
||||
if (!ensure_portal_proxy (self))
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
GError *error = NULL;
|
||||
int fd;
|
||||
|
||||
ensure_print_op (self);
|
||||
fd = get_content_fd (G_OBJECT (content), &error);
|
||||
if (fd == -1)
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
}
|
||||
else if (self->print_settings == NULL)
|
||||
{
|
||||
g_object_set_data (G_OBJECT (task), "fd", GINT_TO_POINTER (fd));
|
||||
g_object_set_data_full (G_OBJECT (self->op), "task", task, g_object_unref);
|
||||
_gtk_print_operation_platform_backend_run_dialog_async (self->op,
|
||||
TRUE,
|
||||
parent,
|
||||
print_pages);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_print_operation_platform_backend_print_file (self->op, "", self->title, fd, task);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1013,10 +1096,35 @@ gtk_print_dialog_print_file (GtkPrintDialog *self,
|
||||
|
||||
g_task_set_task_data (task, content, g_object_unref);
|
||||
|
||||
if (!ensure_portal_proxy (self, &error))
|
||||
if (!ensure_portal_proxy (self))
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
int fd;
|
||||
|
||||
ensure_print_op (self);
|
||||
fd = get_content_fd (G_OBJECT (content), &error);
|
||||
g_print ("print file, op, fd == %d\n", fd);
|
||||
if (fd == -1)
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
}
|
||||
else if (self->print_settings == NULL)
|
||||
{
|
||||
g_print ("show dialog first\n");
|
||||
g_print ("op refcount %d\n", G_OBJECT (self->op)->ref_count);
|
||||
g_object_set_data (G_OBJECT (task), "fd", GINT_TO_POINTER (fd));
|
||||
g_object_set_data_full (G_OBJECT (self->op), "task", task, g_object_unref);
|
||||
_gtk_print_operation_platform_backend_run_dialog_async (self->op,
|
||||
TRUE,
|
||||
parent,
|
||||
print_pages);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_print_operation_platform_backend_print_file (self->op, "", self->title, fd, task);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -172,36 +172,52 @@ print_file_done (GObject *source,
|
||||
GtkPrintOperationPortal *op_portal = op->priv->platform_data;
|
||||
GError *error = NULL;
|
||||
GVariant *ret;
|
||||
GTask *task;
|
||||
|
||||
task = g_object_get_data (G_OBJECT (op), "task");
|
||||
|
||||
ret = g_dbus_proxy_call_finish (op_portal->proxy,
|
||||
result,
|
||||
&error);
|
||||
if (ret == NULL)
|
||||
{
|
||||
if (op->priv->error == NULL)
|
||||
if (task)
|
||||
g_task_return_error (task, g_error_copy (error));
|
||||
else if (op->priv->error == NULL)
|
||||
op->priv->error = g_error_copy (error);
|
||||
g_warning ("Print file failed: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
else
|
||||
g_variant_unref (ret);
|
||||
{
|
||||
if (task)
|
||||
g_task_return_boolean (task, TRUE);
|
||||
g_variant_unref (ret);
|
||||
}
|
||||
|
||||
if (op_portal->loop)
|
||||
g_main_loop_quit (op_portal->loop);
|
||||
|
||||
g_object_set_data (G_OBJECT (op), "task", NULL);
|
||||
|
||||
g_object_unref (op);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_print_operation_portal_print_file (GtkPrintOperation *op,
|
||||
GtkWindow *parent,
|
||||
int fd)
|
||||
const char *window_handle,
|
||||
const char *title,
|
||||
int fd,
|
||||
GTask *task)
|
||||
{
|
||||
GtkPrintOperationPortal *op_portal = op->priv->platform_data;
|
||||
int idx;
|
||||
GVariantBuilder opt_builder;
|
||||
GUnixFDList *fd_list;
|
||||
|
||||
if (task)
|
||||
g_object_set_data_full (G_OBJECT (op), "task", g_object_ref (task), g_object_unref);
|
||||
|
||||
fd_list = g_unix_fd_list_new ();
|
||||
idx = g_unix_fd_list_append (fd_list, fd, NULL);
|
||||
|
||||
@ -211,8 +227,8 @@ gtk_print_operation_portal_print_file (GtkPrintOperation *op,
|
||||
g_dbus_proxy_call_with_unix_fd_list (op_portal->proxy,
|
||||
"Print",
|
||||
g_variant_new ("(ssh@a{sv})",
|
||||
"", /* window */
|
||||
_("Print"), /* title */
|
||||
window_handle,
|
||||
title,
|
||||
idx,
|
||||
g_variant_builder_end (&opt_builder)),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
@ -252,7 +268,7 @@ portal_job_complete (GtkPrintJob *job,
|
||||
fd = open (filename, O_RDONLY|O_CLOEXEC);
|
||||
g_free (filename);
|
||||
|
||||
gtk_print_operation_portal_print_file (op, NULL, fd);
|
||||
gtk_print_operation_portal_print_file (op, "", _("Print"), fd, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -36,8 +36,10 @@ void gtk_print_operation_portal_launch_preview (GtkPr
|
||||
const char *filename);
|
||||
|
||||
void gtk_print_operation_portal_print_file (GtkPrintOperation *op,
|
||||
GtkWindow *parent,
|
||||
int fd);
|
||||
const char *window_handle,
|
||||
const char *title,
|
||||
int fd,
|
||||
GTask *task);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -128,8 +128,10 @@ void _gtk_print_operation_platform_backend_preview_end_page
|
||||
cairo_t *cr);
|
||||
|
||||
void gtk_print_operation_platform_backend_print_file (GtkPrintOperation *op,
|
||||
GtkWindow *parent,
|
||||
int fd);
|
||||
const char *window_handle,
|
||||
const char *title,
|
||||
int fd,
|
||||
GTask *task);
|
||||
|
||||
void _gtk_print_operation_set_status (GtkPrintOperation *op,
|
||||
GtkPrintStatus status,
|
||||
|
@ -510,6 +510,7 @@ print_response_data_free (gpointer data)
|
||||
{
|
||||
PrintResponseData *rdata = data;
|
||||
|
||||
g_print ("free rdata: op refcount %d\n", G_OBJECT (rdata->op)->ref_count);
|
||||
g_object_unref (rdata->op);
|
||||
g_free (rdata);
|
||||
}
|
||||
@ -526,6 +527,7 @@ finish_print (PrintResponseData *rdata,
|
||||
GtkPrintJob *job;
|
||||
double top, bottom, left, right;
|
||||
|
||||
g_print ("finish_print: op refcount %d\n", G_OBJECT (rdata->op)->ref_count);
|
||||
if (rdata->do_print)
|
||||
{
|
||||
gtk_print_operation_set_print_settings (op, settings);
|
||||
@ -899,23 +901,88 @@ gtk_print_operation_unix_run_dialog (GtkPrintOperation *op,
|
||||
return rdata.result;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GtkPrintOperation *op;
|
||||
int fd;
|
||||
GTask *task;
|
||||
} PrintFileData;
|
||||
|
||||
static void
|
||||
free_print_file_data (gpointer data)
|
||||
{
|
||||
PrintFileData *f = data;
|
||||
|
||||
g_object_unref (f->op);
|
||||
g_clear_object (&f->task);
|
||||
g_free (f);
|
||||
}
|
||||
|
||||
static void
|
||||
complete_func (GtkPrintJob *job,
|
||||
gpointer data,
|
||||
const GError *error)
|
||||
{
|
||||
PrintFileData *f = data;
|
||||
GtkPrintOperationPrivate *priv = f->op->priv;
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (f->task)
|
||||
g_task_return_error (f->task, g_error_copy (error));
|
||||
else if (priv->error == NULL)
|
||||
priv->error = g_error_copy (error);
|
||||
}
|
||||
else if (f->task)
|
||||
g_task_return_boolean (f->task, TRUE);
|
||||
|
||||
free_print_file_data (data);
|
||||
}
|
||||
|
||||
static void
|
||||
print_file (GtkPrinter *printer,
|
||||
gpointer data)
|
||||
{
|
||||
PrintFileData *f = data;
|
||||
GtkPrintOperationPrivate *priv = f->op->priv;
|
||||
GtkPrintSettings *print_settings;
|
||||
GtkPageSetup *default_page_setup;
|
||||
GtkPrintJob *job;
|
||||
|
||||
if (priv->print_settings)
|
||||
print_settings = g_object_ref (priv->print_settings);
|
||||
else
|
||||
print_settings = gtk_print_settings_new ();
|
||||
|
||||
if (priv->default_page_setup)
|
||||
default_page_setup = g_object_ref (priv->default_page_setup);
|
||||
else
|
||||
default_page_setup = gtk_page_setup_new ();
|
||||
|
||||
job = gtk_print_job_new ("printjob", printer, print_settings, default_page_setup);
|
||||
gtk_print_job_set_source_fd (job, f->fd, NULL);
|
||||
gtk_print_job_send (job, complete_func, data, free_print_file_data);
|
||||
|
||||
g_object_unref (print_settings);
|
||||
g_object_unref (default_page_setup);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_print_operation_unix_print_file (GtkPrintOperation *op,
|
||||
GtkWindow *parent,
|
||||
int fd)
|
||||
int fd,
|
||||
GTask *task)
|
||||
{
|
||||
#if 0
|
||||
PrintFileData *data;
|
||||
const char *printer_name = NULL;
|
||||
|
||||
data = g_new (PrintFileData, 1);
|
||||
data->op = g_object_ref (op);
|
||||
data->fd = fd;
|
||||
data->task = task ? g_object_ref (task) : 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);
|
||||
|
||||
job = gtk_print_job_new (priv->job_name, printer, settings, page_setup);
|
||||
op_unix->job = job;
|
||||
gtk_print_job_set_track_print_status (job, priv->track_print_status);
|
||||
#endif
|
||||
find_printer (printer_name, (GFunc) print_file, data);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
@ -1291,13 +1358,15 @@ _gtk_print_operation_platform_backend_launch_preview (GtkPrintOperation *op,
|
||||
|
||||
void
|
||||
gtk_print_operation_platform_backend_print_file (GtkPrintOperation *op,
|
||||
GtkWindow *parent,
|
||||
int fd)
|
||||
const char *window_handle,
|
||||
const char *title,
|
||||
int fd,
|
||||
GTask *task)
|
||||
{
|
||||
if (gdk_should_use_portal ())
|
||||
gtk_print_operation_portal_print_file (op, parent, fd);
|
||||
if (gdk_display_get_debug_flags (NULL) & GDK_DEBUG_PORTALS)
|
||||
gtk_print_operation_portal_print_file (op, window_handle, title, fd, task);
|
||||
else
|
||||
gtk_print_operation_unix_print_file (op, parent, fd);
|
||||
gtk_print_operation_unix_print_file (op, fd, task);
|
||||
}
|
||||
|
||||
cairo_surface_t *
|
||||
|
Loading…
Reference in New Issue
Block a user