From 9cb421f32dd6f7041dedf210089e6fe1ca5bb27b Mon Sep 17 00:00:00 2001 From: thierry1970 Date: Tue, 21 Dec 2021 18:54:01 +0100 Subject: [PATCH 01/19] Fix the mozilla print event. Fix build dependency. Refactoring of the MR to sandbox dangerous code Fix printing Update test.yml Force install deps Fix build Fix the print quality Test if the file is a pdf and finish the print job properly --- .github/workflows/test.yml | 1 + configure.ac | 6 +- src/Makefile.am.inc | 12 ++ src/pdftoraw.c | 189 ++++++++++++++++++++++ src/print.c | 311 ++++++++++++++++++++++++++++++------- 5 files changed, 460 insertions(+), 59 deletions(-) create mode 100644 src/pdftoraw.c diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a7a45d53..e71a9ff8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,6 +15,7 @@ jobs: apt-get update apt-get upgrade -y apt-get build-dep -y xdg-desktop-portal-gtk + apt-get install -y libpoppler-glib-dev - uses: actions/checkout@v2 diff --git a/configure.ac b/configure.ac index 694844e2..3b8779be 100644 --- a/configure.ac +++ b/configure.ac @@ -109,10 +109,14 @@ if test x$enable_lockdown = xyes; then fi AM_CONDITIONAL([BUILD_LOCKDOWN],[test "$enable_lockdown" = "yes"]) -PKG_CHECK_MODULES(GTK, [xdg-desktop-portal >= 1.5 glib-2.0 >= 2.44 gio-unix-2.0 gtk+-3.0 >= 3.14 gtk+-unix-print-3.0]) +PKG_CHECK_MODULES(GTK, [xdg-desktop-portal >= 1.5 glib-2.0 >= 2.44 gio-unix-2.0 gtk+-3.0 >= 3.14 gtk+-unix-print-3.0 ]) AC_SUBST(GTK_CFLAGS) AC_SUBST(GTK_LIBS) +PKG_CHECK_MODULES(POPPLER, [ gtk+-3.0 >= 3.14 gio-unix-2.0 poppler >= 0.16.7 poppler-glib >= 0.16.7 ]) +AC_SUBST(POPPLER_CFLAGS) +AC_SUBST(POPPLER_LIBS) + PKG_CHECK_MODULES(GTK_X11, gtk+-x11-3.0, have_gtk_x11=yes, have_gtk_x11=no) if test "$have_gtk_x11" = "yes"; then diff --git a/src/Makefile.am.inc b/src/Makefile.am.inc index 097ebe78..bfd1a2f0 100644 --- a/src/Makefile.am.inc +++ b/src/Makefile.am.inc @@ -112,6 +112,7 @@ EXTRA_DIST += \ libexec_PROGRAMS = \ xdg-desktop-portal-gtk \ + pdftoraw \ $(NULL) xdg_desktop_portal_gtk_SOURCES = \ @@ -285,3 +286,14 @@ testappchooser_SOURCES = \ nodist_testappchooser_SOURCES = \ src/resources.c \ $(NULL) + +pdftoraw_SOURCES = \ + src/pdftoraw.c \ + $(NULL) + +pdftoraw_LDADD = $(BASE_LIBS) $(POPPLER_LIBS) -lm +pdftoraw_CFLAGS = $(BASE_CFLAGS) $(POPPLER_CFLAGS) +pdftoraw_CPPFLAGS = \ + -I$(top_srcdir)/src \ + -I$(top_builddir)/src \ + $(NULL) diff --git a/src/pdftoraw.c b/src/pdftoraw.c new file mode 100644 index 00000000..1cb22333 --- /dev/null +++ b/src/pdftoraw.c @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2021 Thierry HUCHARD + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DPI 150.0 + +static struct option long_options[] = { + {"file", required_argument, 0, 'f' }, + {"pages", no_argument, 0, 'p' }, + {"test", no_argument, 0, 't' }, + {"width", required_argument, 0, 'w' }, + {"height", required_argument, 0, 'W' }, + {"raw", required_argument, 0, 'r' }, + {"help", no_argument, 0, 'h' }, + {0, 0, 0, 0 } +}; + +static void +print_usage(void) { + printf("Usage:\tpdftoraw --filename= --raw=\n"); + printf("\tpdftoraw --filename= --pages\n"); + printf("\tpdftoraw --filename= --width=\n"); + printf("\tpdftoraw --filename= --height=\n"); + printf("\tpdftoraw --help\n"); +} + +static int +pdf_number_pages_get(PopplerDocument *doc) +{ + return poppler_document_get_n_pages(doc); +} + +static unsigned char* +pdf_page_raw_get(PopplerDocument *doc, + int page_nr) +{ + cairo_surface_t *s = NULL; + cairo_t *cr = NULL; + unsigned char *data = NULL; + GdkPixbuf *pix = NULL; + double width = 0; + double height = 0; + int w = 0; + int h = 0; + + PopplerPage *page = poppler_document_get_page(doc, page_nr); + poppler_page_get_size(page, &width, &height); + width = DPI * width / 72.0; + height = DPI * height / 72.0; + w = (int)ceil(width); + h = (int)ceil(height); + s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); + cr = cairo_create(s); + cairo_scale (cr, DPI/72.0, DPI/72.0); + cairo_save (cr); + poppler_page_render_for_printing(page, cr); + cairo_restore (cr); + pix = gdk_pixbuf_get_from_surface(s, 0, 0, w, h); + g_object_unref(page); + data = gdk_pixbuf_get_pixels (pix); + fwrite(data, 1, (w * h * 4), stdout); + return data; +} + +static int +pdf_page_width_get(PopplerDocument *doc, + int page_nr) +{ + double width = 0; + int w = 0; + + PopplerPage *page = poppler_document_get_page(doc, page_nr); + poppler_page_get_size(page, &width, NULL); + width = DPI * width / 72.0; + w = (int)ceil(width); + g_object_unref(page); + return w; +} + +static int +pdf_page_height_get(PopplerDocument *doc, + int page_nr) +{ + double height = 0; + int h = 0; + + PopplerPage *page = poppler_document_get_page(doc, page_nr); + poppler_page_get_size(page, NULL, &height); + height = DPI * height / 72.0; + h = (int)ceil(height); + g_object_unref(page); + return h; +} + +int +main(int argc, char **argv) +{ + PopplerDocument *doc = NULL; + GError *err = NULL; + GFile *in = NULL; + char *filename = NULL; + int long_index =0; + int page = 0; + int opt= 0; + int test = 0, raw = 0, npages = 0, width = 0, height = 0; + + while ((opt = getopt_long(argc, argv,"f:tpw:W:r:h", + long_options, &long_index )) != -1) { + switch (opt) { + case 'f' : + filename = strdup(optarg); + break; + case 't' : + test = 1; + break; + case 'p' : + npages = 1; + break; + case 'w' : page = atoi(optarg); + width = 1; + break; + case 'W' : page = atoi(optarg); + height = 1; + break; + case 'r' : page = atoi(optarg); + raw = 1; + break; + default: print_usage(); + exit(EXIT_FAILURE); + } + } + if (filename == NULL) { + print_usage(); + exit(EXIT_FAILURE); + } + in = g_file_new_for_path(filename); + doc = poppler_document_new_from_gfile(in, NULL, NULL, &err); + if (err) + { + g_error_free(err); + g_object_unref(in); + exit(EXIT_FAILURE); + } + + if (test == 1) { + printf("1"); + } + else if (raw == 1) { + pdf_page_raw_get(doc, page); + } + else if (npages == 1) { + printf("%d", pdf_number_pages_get(doc)); + } + else if (width == 1) { + printf("%d", pdf_page_width_get(doc, page)); + } + else if (height == 1) { + printf("%d", pdf_page_height_get(doc, page)); + } + else { + print_usage(); + exit(EXIT_FAILURE); + } + g_object_unref(doc); + return 0; +} + diff --git a/src/print.c b/src/print.c index df6a3579..7774d0ab 100644 --- a/src/print.c +++ b/src/print.c @@ -23,6 +23,7 @@ #include "config.h" #include +#include #include #include @@ -42,6 +43,15 @@ #include "gtkbackports.h" +#define DPI 150.0 + +typedef enum { + PDF_TEST = 0, + PDF_NUM_PAGES, + PDF_WIDTH, + PDF_HEIGHT +} PDF_ACTIONS; + typedef struct { char *app_id; GtkPageSetup *page_setup; @@ -245,6 +255,190 @@ launch_preview (const char *filename, return retval; } +static int +pdf_get_actions_page (char *filename, + PDF_ACTIONS act, + int page) +{ + GSubprocess *process; + GInputStream *stream; + char *option1 = NULL; + char *option2 = NULL; + char buffer[50] = { 0 }; + + option1 = g_strconcat ("--file=", filename, NULL); + switch(act) + { + case PDF_TEST : + (void)page; + option2 = g_strdup ("--test"); + break; + case PDF_NUM_PAGES : + (void)page; + option2 = g_strdup ("--pages"); + break; + case PDF_WIDTH : + option2 = g_strdup_printf ("--width=%d", page); + break; + case PDF_HEIGHT : + option2 = g_strdup_printf ("--height=%d", page); + break; + default: + return 0; + } + process = g_subprocess_new(G_SUBPROCESS_FLAGS_STDOUT_PIPE, NULL, "/usr/libexec/pdftoraw", option1, option2, NULL); + + if (process) + { + stream = g_subprocess_get_stdout_pipe(process); + if (stream) + { + g_input_stream_read(stream, buffer, sizeof(buffer), NULL, NULL); + if (buffer[0]) + return atoi(buffer); + } + } + return 0; +} + +static unsigned char * +pdf_get_data_page (char *filename, + int w, + int h, + int page) +{ + GSubprocess *process; + GInputStream *stream; + unsigned char *data = NULL; + char *option1 = NULL; + char *option2 = NULL; + int read = 0; + gsize total_read = 0; + + option1 = g_strconcat ("--file=", filename, NULL); + option2 = g_strdup_printf ("--raw=%d", page); + process = g_subprocess_new(G_SUBPROCESS_FLAGS_STDOUT_PIPE, NULL, "/usr/libexec/pdftoraw", option1, option2, NULL); + + if (process) + { + stream = g_subprocess_get_stdout_pipe(process); + if (stream) + { + data = (unsigned char *) g_malloc( w * h * 4); + while ((read = g_input_stream_read(stream, data + total_read, 1024, NULL, NULL)) > 0) + { + total_read += read; + } + } + } + return data; +} + +static void +pdf_begin_print(GtkPrintOperation *op, + GtkPrintContext *ctx, + char *filename) +{ + (void)ctx; + gtk_print_operation_set_n_pages(op, pdf_get_actions_page(filename, PDF_NUM_PAGES, 0)); +} + +static void +pdf_draw_page(GtkPrintOperation *op, + GtkPrintContext *ctx, + gint page_nr, + char *filename) +{ + cairo_t *cr = NULL; + cairo_surface_t *surface = NULL; + int width = 0, height = 0; + unsigned char *data = NULL; + int stride = 0; + (void)op; + + width = pdf_get_actions_page (filename, PDF_WIDTH, page_nr); + height = pdf_get_actions_page (filename, PDF_HEIGHT, page_nr); + cr = gtk_print_context_get_cairo_context(ctx); + stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width); + data = pdf_get_data_page (filename, width, height, page_nr); + if (data) + { + GdkPixbuf *pix = gdk_pixbuf_new_from_data (data, GDK_COLORSPACE_RGB, TRUE, 8, width, height, stride, NULL, g_free); + cairo_scale(cr, (72.0 / DPI), (72.0 / DPI)); + gdk_cairo_set_source_pixbuf(cr, pix, 0, 0); + cairo_paint(cr); + cairo_fill (cr); + cairo_surface_destroy (surface); + } +} + +static void +pdf_end_print (GtkPrintOperation *operation, + GtkPrintContext *context, + char *filename) +{ + (void)operation; + (void)context; + + if (filename) + unlink(filename); +} + +static gboolean +print_pdf(int fd, + XdpImplPrint *object, + GDBusMethodInvocation *invocation) +{ + g_autofree char *filename = NULL; + g_autoptr(GUnixInputStream) istream = NULL; + g_autoptr(GUnixOutputStream) ostream = NULL; + GtkPrintSettings *settings = NULL; + GtkPrintOperation *print = NULL; + GError *err = NULL; + GVariantBuilder opt_builder; + int fd2; + + istream = (GUnixInputStream *)g_unix_input_stream_new (fd, FALSE); + + if ((fd2 = g_file_open_tmp (PACKAGE_NAME "XXXXXX", &filename, &err)) == -1) + return FALSE; + + ostream = (GUnixOutputStream *)g_unix_output_stream_new (fd2, TRUE); + + if (g_output_stream_splice (G_OUTPUT_STREAM (ostream), + G_INPUT_STREAM (istream), + G_OUTPUT_STREAM_SPLICE_NONE, + NULL, + &err) == -1) + return FALSE; + if (pdf_get_actions_page (filename, PDF_TEST, -1) == 0) + { + unlink(filename); + return FALSE; + } + + print = gtk_print_operation_new(); + gtk_print_operation_set_use_full_page (print, TRUE); + gtk_print_operation_set_unit (print, GTK_UNIT_POINTS); + gtk_print_operation_set_embed_page_setup (print, TRUE); + settings = gtk_print_settings_new(); + g_signal_connect(print, "begin-print", G_CALLBACK(pdf_begin_print), filename); + g_signal_connect(print, "draw-page", G_CALLBACK(pdf_draw_page), filename); + g_signal_connect(print, "end-print", G_CALLBACK(pdf_end_print), filename); + gtk_print_operation_set_print_settings(print, settings); + + (void)gtk_print_operation_run(print, GTK_PRINT_OPERATION_ACTION_PRINT, NULL, &err); + g_object_unref (print); + g_object_unref (settings); + g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT); + xdp_impl_print_complete_print (object, + invocation, + NULL, + 0, + g_variant_builder_end (&opt_builder)); + return TRUE; +} + static gboolean print_file (int fd, const char *app_id, @@ -476,66 +670,67 @@ handle_print (XdpImplPrint *object, g_variant_builder_end (&opt_builder)); return TRUE; } - - sender = g_dbus_method_invocation_get_sender (invocation); - request = request_new (sender, arg_app_id, arg_handle); - - if (arg_parent_window) + else if (print_pdf(fd, object, invocation) == FALSE) { - external_parent = create_external_window_from_handle (arg_parent_window); - if (!external_parent) - g_warning ("Failed to associate portal window with parent window %s", - arg_parent_window); + sender = g_dbus_method_invocation_get_sender (invocation); + request = request_new (sender, arg_app_id, arg_handle); + + if (arg_parent_window) + { + external_parent = create_external_window_from_handle (arg_parent_window); + if (!external_parent) + g_warning ("Failed to associate portal window with parent window %s", + arg_parent_window); + } + + if (external_parent) + display = external_window_get_display (external_parent); + else + display = gdk_display_get_default (); + screen = gdk_display_get_default_screen (display); + + fake_parent = g_object_new (GTK_TYPE_WINDOW, + "type", GTK_WINDOW_TOPLEVEL, + "screen", screen, + NULL); + g_object_ref_sink (fake_parent); + + if (!g_variant_lookup (arg_options, "modal", "b", &modal)) + modal = TRUE; + + dialog = gtk_print_unix_dialog_new (arg_title, NULL); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (fake_parent)); + gtk_window_set_modal (GTK_WINDOW (dialog), modal); + gtk_print_unix_dialog_set_manual_capabilities (GTK_PRINT_UNIX_DIALOG (dialog), + can_preview () ? GTK_PRINT_CAPABILITY_PREVIEW : 0 | + GTK_PRINT_CAPABILITY_PAGE_SET | + GTK_PRINT_CAPABILITY_COPIES | + GTK_PRINT_CAPABILITY_COLLATE | + GTK_PRINT_CAPABILITY_REVERSE | + GTK_PRINT_CAPABILITY_SCALE | + GTK_PRINT_CAPABILITY_NUMBER_UP + ); + handle = g_new0 (PrintDialogHandle, 1); + handle->impl = object; + handle->invocation = invocation; + handle->request = g_object_ref (request); + handle->dialog = g_object_ref (dialog); + handle->external_parent = external_parent; + handle->fd = fd; + + g_signal_connect (request, "handle-close", G_CALLBACK (handle_close), handle); + + g_signal_connect (dialog, "response", G_CALLBACK (handle_print_response), handle); + + gtk_widget_realize (dialog); + + if (external_parent) + external_window_set_parent_of (external_parent, gtk_widget_get_window (dialog)); + + request_export (request, g_dbus_method_invocation_get_connection (invocation)); + + gtk_widget_show (dialog); } - - if (external_parent) - display = external_window_get_display (external_parent); - else - display = gdk_display_get_default (); - screen = gdk_display_get_default_screen (display); - - fake_parent = g_object_new (GTK_TYPE_WINDOW, - "type", GTK_WINDOW_TOPLEVEL, - "screen", screen, - NULL); - g_object_ref_sink (fake_parent); - - if (!g_variant_lookup (arg_options, "modal", "b", &modal)) - modal = TRUE; - - dialog = gtk_print_unix_dialog_new (arg_title, NULL); - gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (fake_parent)); - gtk_window_set_modal (GTK_WINDOW (dialog), modal); - gtk_print_unix_dialog_set_manual_capabilities (GTK_PRINT_UNIX_DIALOG (dialog), - can_preview () ? GTK_PRINT_CAPABILITY_PREVIEW : 0 | - GTK_PRINT_CAPABILITY_PAGE_SET | - GTK_PRINT_CAPABILITY_COPIES | - GTK_PRINT_CAPABILITY_COLLATE | - GTK_PRINT_CAPABILITY_REVERSE | - GTK_PRINT_CAPABILITY_SCALE | - GTK_PRINT_CAPABILITY_NUMBER_UP - ); - handle = g_new0 (PrintDialogHandle, 1); - handle->impl = object; - handle->invocation = invocation; - handle->request = g_object_ref (request); - handle->dialog = g_object_ref (dialog); - handle->external_parent = external_parent; - handle->fd = fd; - - g_signal_connect (request, "handle-close", G_CALLBACK (handle_close), handle); - - g_signal_connect (dialog, "response", G_CALLBACK (handle_print_response), handle); - - gtk_widget_realize (dialog); - - if (external_parent) - external_window_set_parent_of (external_parent, gtk_widget_get_window (dialog)); - - request_export (request, g_dbus_method_invocation_get_connection (invocation)); - - gtk_widget_show (dialog); - return TRUE; } From 3a6cd1e912004c2cb16f83f479f209196c4fb8fc Mon Sep 17 00:00:00 2001 From: Ordissimo Date: Fri, 31 Dec 2021 22:36:04 +0100 Subject: [PATCH 02/19] Fix formating and documents --- src/pdftoraw.c | 59 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/src/pdftoraw.c b/src/pdftoraw.c index 1cb22333..a4fd35ab 100644 --- a/src/pdftoraw.c +++ b/src/pdftoraw.c @@ -24,6 +24,11 @@ #include #include + +// 1 inch = 72 points +#define PTS 72.0 + +// Resolution for the printer, 150 my choice #define DPI 150.0 static struct option long_options[] = { @@ -38,8 +43,10 @@ static struct option long_options[] = { }; static void -print_usage(void) { +print_usage (void) +{ printf("Usage:\tpdftoraw --filename= --raw=\n"); + printf("\tpdftoraw --filename= --test\n"); printf("\tpdftoraw --filename= --pages\n"); printf("\tpdftoraw --filename= --width=\n"); printf("\tpdftoraw --filename= --height=\n"); @@ -47,33 +54,34 @@ print_usage(void) { } static int -pdf_number_pages_get(PopplerDocument *doc) +pdf_number_pages_get (PopplerDocument *doc) { return poppler_document_get_n_pages(doc); } static unsigned char* -pdf_page_raw_get(PopplerDocument *doc, +pdf_page_raw_get (PopplerDocument *doc, int page_nr) { cairo_surface_t *s = NULL; cairo_t *cr = NULL; unsigned char *data = NULL; + PopplerPage *page = NULL; GdkPixbuf *pix = NULL; double width = 0; double height = 0; int w = 0; int h = 0; - PopplerPage *page = poppler_document_get_page(doc, page_nr); + page = poppler_document_get_page(doc, page_nr); poppler_page_get_size(page, &width, &height); - width = DPI * width / 72.0; - height = DPI * height / 72.0; + width = DPI * width / PTS; + height = DPI * height / PTS; w = (int)ceil(width); h = (int)ceil(height); s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); cr = cairo_create(s); - cairo_scale (cr, DPI/72.0, DPI/72.0); + cairo_scale (cr, DPI / PTS, DPI / PTS); cairo_save (cr); poppler_page_render_for_printing(page, cr); cairo_restore (cr); @@ -85,7 +93,7 @@ pdf_page_raw_get(PopplerDocument *doc, } static int -pdf_page_width_get(PopplerDocument *doc, +pdf_page_width_get (PopplerDocument *doc, int page_nr) { double width = 0; @@ -93,14 +101,14 @@ pdf_page_width_get(PopplerDocument *doc, PopplerPage *page = poppler_document_get_page(doc, page_nr); poppler_page_get_size(page, &width, NULL); - width = DPI * width / 72.0; + width = DPI * width / PTS; w = (int)ceil(width); g_object_unref(page); return w; } static int -pdf_page_height_get(PopplerDocument *doc, +pdf_page_height_get (PopplerDocument *doc, int page_nr) { double height = 0; @@ -108,14 +116,14 @@ pdf_page_height_get(PopplerDocument *doc, PopplerPage *page = poppler_document_get_page(doc, page_nr); poppler_page_get_size(page, NULL, &height); - height = DPI * height / 72.0; + height = DPI * height / PTS; h = (int)ceil(height); g_object_unref(page); return h; } int -main(int argc, char **argv) +main (int argc, char **argv) { PopplerDocument *doc = NULL; GError *err = NULL; @@ -127,8 +135,10 @@ main(int argc, char **argv) int test = 0, raw = 0, npages = 0, width = 0, height = 0; while ((opt = getopt_long(argc, argv,"f:tpw:W:r:h", - long_options, &long_index )) != -1) { - switch (opt) { + long_options, &long_index )) != -1) + { + switch (opt) + { case 'f' : filename = strdup(optarg); break; @@ -151,7 +161,8 @@ main(int argc, char **argv) exit(EXIT_FAILURE); } } - if (filename == NULL) { + if (filename == NULL) + { print_usage(); exit(EXIT_FAILURE); } @@ -164,22 +175,28 @@ main(int argc, char **argv) exit(EXIT_FAILURE); } - if (test == 1) { + if (test == 1) + { printf("1"); } - else if (raw == 1) { + else if (raw == 1) + { pdf_page_raw_get(doc, page); } - else if (npages == 1) { + else if (npages == 1) + { printf("%d", pdf_number_pages_get(doc)); } - else if (width == 1) { + else if (width == 1) + { printf("%d", pdf_page_width_get(doc, page)); } - else if (height == 1) { + else if (height == 1) + { printf("%d", pdf_page_height_get(doc, page)); } - else { + else + { print_usage(); exit(EXIT_FAILURE); } From 7ec9062903cce65e916d4607339f1c4961395407 Mon Sep 17 00:00:00 2001 From: Ordissimo Date: Fri, 31 Dec 2021 23:13:03 +0100 Subject: [PATCH 03/19] Fix Don't hardcode /usr/libexec and Documents --- src/Makefile.am.inc | 3 ++- src/print.c | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Makefile.am.inc b/src/Makefile.am.inc index bfd1a2f0..0b3f1aa9 100644 --- a/src/Makefile.am.inc +++ b/src/Makefile.am.inc @@ -294,6 +294,7 @@ pdftoraw_SOURCES = \ pdftoraw_LDADD = $(BASE_LIBS) $(POPPLER_LIBS) -lm pdftoraw_CFLAGS = $(BASE_CFLAGS) $(POPPLER_CFLAGS) pdftoraw_CPPFLAGS = \ - -I$(top_srcdir)/src \ + -I$(top_srcdir)/src \ -I$(top_builddir)/src \ + -DLIBEXECDIR=\"$(libexecdir)\" \ $(NULL) diff --git a/src/print.c b/src/print.c index 7774d0ab..44ad3a2e 100644 --- a/src/print.c +++ b/src/print.c @@ -43,6 +43,10 @@ #include "gtkbackports.h" +// 1 inch = 72 points +#define PTS 72.0 + +// Resolution for the printer, 150 my choice #define DPI 150.0 typedef enum { @@ -286,7 +290,7 @@ pdf_get_actions_page (char *filename, default: return 0; } - process = g_subprocess_new(G_SUBPROCESS_FLAGS_STDOUT_PIPE, NULL, "/usr/libexec/pdftoraw", option1, option2, NULL); + process = g_subprocess_new(G_SUBPROCESS_FLAGS_STDOUT_PIPE, NULL, LIBEXECDIR "/pdftoraw", option1, option2, NULL); if (process) { @@ -317,7 +321,7 @@ pdf_get_data_page (char *filename, option1 = g_strconcat ("--file=", filename, NULL); option2 = g_strdup_printf ("--raw=%d", page); - process = g_subprocess_new(G_SUBPROCESS_FLAGS_STDOUT_PIPE, NULL, "/usr/libexec/pdftoraw", option1, option2, NULL); + process = g_subprocess_new(G_SUBPROCESS_FLAGS_STDOUT_PIPE, NULL, LIBEXECDIR "/pdftoraw", option1, option2, NULL); if (process) { @@ -364,7 +368,7 @@ pdf_draw_page(GtkPrintOperation *op, if (data) { GdkPixbuf *pix = gdk_pixbuf_new_from_data (data, GDK_COLORSPACE_RGB, TRUE, 8, width, height, stride, NULL, g_free); - cairo_scale(cr, (72.0 / DPI), (72.0 / DPI)); + cairo_scale(cr, (PTS / DPI), (PTS / DPI)); gdk_cairo_set_source_pixbuf(cr, pix, 0, 0); cairo_paint(cr); cairo_fill (cr); From 50373adf16ccd178bb89160af9bec9ff785321f5 Mon Sep 17 00:00:00 2001 From: Ordissimo Date: Fri, 31 Dec 2021 23:40:26 +0100 Subject: [PATCH 04/19] Fix build --- src/Makefile.am.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am.inc b/src/Makefile.am.inc index 0b3f1aa9..4cb2e704 100644 --- a/src/Makefile.am.inc +++ b/src/Makefile.am.inc @@ -261,6 +261,7 @@ xdg_desktop_portal_gtk_CPPFLAGS = \ -DLOCALEDIR=\"$(localedir)\" \ -I$(top_srcdir)/src \ -I$(top_builddir)/src \ + -DLIBEXECDIR=\"$(libexecdir)\" \ $(NULL) noinst_PROGRAMS = \ @@ -296,5 +297,4 @@ pdftoraw_CFLAGS = $(BASE_CFLAGS) $(POPPLER_CFLAGS) pdftoraw_CPPFLAGS = \ -I$(top_srcdir)/src \ -I$(top_builddir)/src \ - -DLIBEXECDIR=\"$(libexecdir)\" \ $(NULL) From 007bd452e1ebb4b72baf62d35fefc0f31d6a87d0 Mon Sep 17 00:00:00 2001 From: Ordissimo Date: Sat, 1 Jan 2022 00:34:30 +0100 Subject: [PATCH 05/19] Fix invalide pointer and Leak --- src/pdftoraw.c | 7 +++++-- src/print.c | 43 ++++++++++++++++++++----------------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/pdftoraw.c b/src/pdftoraw.c index a4fd35ab..a507f9de 100644 --- a/src/pdftoraw.c +++ b/src/pdftoraw.c @@ -65,9 +65,9 @@ pdf_page_raw_get (PopplerDocument *doc, { cairo_surface_t *s = NULL; cairo_t *cr = NULL; - unsigned char *data = NULL; + g_autofree unsigned char *data = NULL; PopplerPage *page = NULL; - GdkPixbuf *pix = NULL; + g_autoptr(GdkPixbuf) *pix = NULL; double width = 0; double height = 0; int w = 0; @@ -89,6 +89,9 @@ pdf_page_raw_get (PopplerDocument *doc, g_object_unref(page); data = gdk_pixbuf_get_pixels (pix); fwrite(data, 1, (w * h * 4), stdout); + cairo_destroy(cr); + if(s) + cairo_surface_destroy(s); return data; } diff --git a/src/print.c b/src/print.c index 44ad3a2e..8b675ea6 100644 --- a/src/print.c +++ b/src/print.c @@ -266,31 +266,30 @@ pdf_get_actions_page (char *filename, { GSubprocess *process; GInputStream *stream; - char *option1 = NULL; - char *option2 = NULL; + GPtrArray *args = g_ptr_array_new_full(8, g_free); char buffer[50] = { 0 }; - option1 = g_strconcat ("--file=", filename, NULL); + g_ptr_array_add(args, LIBEXECDIR "/pdftoraw"); + g_ptr_array_add(args, g_strconcat ("--file=", filename, NULL)); switch(act) { case PDF_TEST : - (void)page; - option2 = g_strdup ("--test"); + g_ptr_array_add(args, "--test"); break; case PDF_NUM_PAGES : - (void)page; - option2 = g_strdup ("--pages"); + g_ptr_array_add(args, "--pages"); break; case PDF_WIDTH : - option2 = g_strdup_printf ("--width=%d", page); + g_ptr_array_add(args, g_strdup_printf ("--width=%d", page)); break; case PDF_HEIGHT : - option2 = g_strdup_printf ("--height=%d", page); + g_ptr_array_add(args, g_strdup_printf ("--height=%d", page)); break; default: return 0; } - process = g_subprocess_new(G_SUBPROCESS_FLAGS_STDOUT_PIPE, NULL, LIBEXECDIR "/pdftoraw", option1, option2, NULL); + + process = g_subprocess_newv((const gchar * const *)args->pdata, G_SUBPROCESS_FLAGS_STDOUT_PIPE, NULL); if (process) { @@ -314,14 +313,14 @@ pdf_get_data_page (char *filename, GSubprocess *process; GInputStream *stream; unsigned char *data = NULL; - char *option1 = NULL; - char *option2 = NULL; + GPtrArray *args = g_ptr_array_new_full(8, g_free); int read = 0; gsize total_read = 0; - option1 = g_strconcat ("--file=", filename, NULL); - option2 = g_strdup_printf ("--raw=%d", page); - process = g_subprocess_new(G_SUBPROCESS_FLAGS_STDOUT_PIPE, NULL, LIBEXECDIR "/pdftoraw", option1, option2, NULL); + g_ptr_array_add(args, LIBEXECDIR "/pdftoraw"); + g_ptr_array_add(args, g_strconcat ("--file=", filename, NULL)); + g_ptr_array_add(args, g_strdup_printf ("--raw=%d", page)); + process = g_subprocess_newv((const gchar * const *)args->pdata, G_SUBPROCESS_FLAGS_STDOUT_PIPE, NULL); if (process) { @@ -343,7 +342,6 @@ pdf_begin_print(GtkPrintOperation *op, GtkPrintContext *ctx, char *filename) { - (void)ctx; gtk_print_operation_set_n_pages(op, pdf_get_actions_page(filename, PDF_NUM_PAGES, 0)); } @@ -358,7 +356,6 @@ pdf_draw_page(GtkPrintOperation *op, int width = 0, height = 0; unsigned char *data = NULL; int stride = 0; - (void)op; width = pdf_get_actions_page (filename, PDF_WIDTH, page_nr); height = pdf_get_actions_page (filename, PDF_HEIGHT, page_nr); @@ -381,11 +378,11 @@ pdf_end_print (GtkPrintOperation *operation, GtkPrintContext *context, char *filename) { - (void)operation; - (void)context; - if (filename) - unlink(filename); + { + unlink (filename); + g_free (filename); + } } static gboolean @@ -393,7 +390,7 @@ print_pdf(int fd, XdpImplPrint *object, GDBusMethodInvocation *invocation) { - g_autofree char *filename = NULL; + char *filename = NULL; g_autoptr(GUnixInputStream) istream = NULL; g_autoptr(GUnixOutputStream) ostream = NULL; GtkPrintSettings *settings = NULL; @@ -431,7 +428,7 @@ print_pdf(int fd, g_signal_connect(print, "end-print", G_CALLBACK(pdf_end_print), filename); gtk_print_operation_set_print_settings(print, settings); - (void)gtk_print_operation_run(print, GTK_PRINT_OPERATION_ACTION_PRINT, NULL, &err); + gtk_print_operation_run(print, GTK_PRINT_OPERATION_ACTION_PRINT, NULL, &err); g_object_unref (print); g_object_unref (settings); g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT); From 10e290f54402d7944e67d9421c76db6d1a9e1771 Mon Sep 17 00:00:00 2001 From: Ordissimo Date: Sat, 1 Jan 2022 11:48:38 +0100 Subject: [PATCH 06/19] Correct multiple feedbacks. --- src/pdftoraw.c | 124 ++++++++++++++++++++++++------------------------- src/print.c | 10 ++-- 2 files changed, 65 insertions(+), 69 deletions(-) diff --git a/src/pdftoraw.c b/src/pdftoraw.c index a507f9de..07b02a43 100644 --- a/src/pdftoraw.c +++ b/src/pdftoraw.c @@ -31,15 +31,21 @@ // Resolution for the printer, 150 my choice #define DPI 150.0 -static struct option long_options[] = { - {"file", required_argument, 0, 'f' }, - {"pages", no_argument, 0, 'p' }, - {"test", no_argument, 0, 't' }, - {"width", required_argument, 0, 'w' }, - {"height", required_argument, 0, 'W' }, - {"raw", required_argument, 0, 'r' }, - {"help", no_argument, 0, 'h' }, - {0, 0, 0, 0 } +static gchar *filename = ""; +static gboolean opt_test = FALSE; +static gboolean opt_pages = FALSE; +static int opt_raw = -1; +static int opt_width = -1; +static int opt_height = -1; + +static GOptionEntry entries[] = { + { "file", 'f', 0, G_OPTION_ARG_STRING, &filename, "PDF file path", NULL }, + { "test", 't', 0, G_OPTION_ARG_NONE, &opt_test, "Test if the file is a PDF file", NULL }, + { "pages", 'p', 0, G_OPTION_ARG_NONE, &opt_pages, "Returns the number of pages in the PDF file", NULL }, + { "width", 'w', 0, G_OPTION_ARG_INT, &opt_width, "Give the size of the page provided in arguments", NULL}, + { "height", 'W', 0, G_OPTION_ARG_INT, &opt_height, "Gives the height of the page provided in arguments", NULL}, + { "raw", 'r', 0, G_OPTION_ARG_INT, &opt_raw, "Retrieves data in pixels from the page provided as arguments", NULL}, + { NULL } }; static void @@ -59,54 +65,64 @@ pdf_number_pages_get (PopplerDocument *doc) return poppler_document_get_n_pages(doc); } -static unsigned char* +static void pdf_page_raw_get (PopplerDocument *doc, int page_nr) { cairo_surface_t *s = NULL; cairo_t *cr = NULL; - g_autofree unsigned char *data = NULL; + unsigned char *data = NULL; PopplerPage *page = NULL; - g_autoptr(GdkPixbuf) *pix = NULL; + g_autoptr(GdkPixbuf) pix = NULL; double width = 0; double height = 0; int w = 0; int h = 0; page = poppler_document_get_page(doc, page_nr); + if (page == NULL) + return; poppler_page_get_size(page, &width, &height); width = DPI * width / PTS; height = DPI * height / PTS; w = (int)ceil(width); h = (int)ceil(height); s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); + if (s == NULL) + return; cr = cairo_create(s); + if (cr == NULL) + { + cairo_surface_destroy (s); + return; + } cairo_scale (cr, DPI / PTS, DPI / PTS); cairo_save (cr); poppler_page_render_for_printing(page, cr); cairo_restore (cr); - pix = gdk_pixbuf_get_from_surface(s, 0, 0, w, h); g_object_unref(page); + pix = gdk_pixbuf_get_from_surface(s, 0, 0, w, h); + cairo_surface_destroy (s); data = gdk_pixbuf_get_pixels (pix); fwrite(data, 1, (w * h * 4), stdout); cairo_destroy(cr); - if(s) - cairo_surface_destroy(s); - return data; } static int pdf_page_width_get (PopplerDocument *doc, int page_nr) { + PopplerPage *page = NULL; double width = 0; int w = 0; - PopplerPage *page = poppler_document_get_page(doc, page_nr); + page = poppler_document_get_page(doc, page_nr); + if (page == NULL) + return -1; poppler_page_get_size(page, &width, NULL); + g_object_unref(page); width = DPI * width / PTS; w = (int)ceil(width); - g_object_unref(page); return w; } @@ -114,14 +130,17 @@ static int pdf_page_height_get (PopplerDocument *doc, int page_nr) { + PopplerPage *page = NULL; double height = 0; int h = 0; - PopplerPage *page = poppler_document_get_page(doc, page_nr); + page = poppler_document_get_page(doc, page_nr); + if (page == NULL) + return -1; poppler_page_get_size(page, NULL, &height); + g_object_unref(page); height = DPI * height / PTS; h = (int)ceil(height); - g_object_unref(page); return h; } @@ -130,43 +149,25 @@ main (int argc, char **argv) { PopplerDocument *doc = NULL; GError *err = NULL; - GFile *in = NULL; - char *filename = NULL; - int long_index =0; - int page = 0; - int opt= 0; - int test = 0, raw = 0, npages = 0, width = 0, height = 0; - - while ((opt = getopt_long(argc, argv,"f:tpw:W:r:h", - long_options, &long_index )) != -1) + g_autoptr(GFile) in = NULL; + + GOptionContext *context; + + context = g_option_context_new ("- PDF utility for portal backends"); + g_option_context_add_main_entries (context, entries, NULL); + if (!g_option_context_parse (context, &argc, &argv, &err)) { - switch (opt) - { - case 'f' : - filename = strdup(optarg); - break; - case 't' : - test = 1; - break; - case 'p' : - npages = 1; - break; - case 'w' : page = atoi(optarg); - width = 1; - break; - case 'W' : page = atoi(optarg); - height = 1; - break; - case 'r' : page = atoi(optarg); - raw = 1; - break; - default: print_usage(); - exit(EXIT_FAILURE); - } + g_printerr ("%s: %s", g_get_application_name (), err->message); + g_printerr ("\n"); + g_printerr ("Try \"%s --help\" for more information.", + g_get_prgname ()); + g_printerr ("\n"); + exit(EXIT_FAILURE); + return 1; } + if (filename == NULL) { - print_usage(); exit(EXIT_FAILURE); } in = g_file_new_for_path(filename); @@ -174,29 +175,28 @@ main (int argc, char **argv) if (err) { g_error_free(err); - g_object_unref(in); exit(EXIT_FAILURE); } - if (test == 1) + if (opt_test) { printf("1"); } - else if (raw == 1) + else if (opt_raw > -1) { - pdf_page_raw_get(doc, page); + pdf_page_raw_get(doc, opt_raw); } - else if (npages == 1) + else if (opt_pages) { printf("%d", pdf_number_pages_get(doc)); } - else if (width == 1) + else if (opt_width > -1) { - printf("%d", pdf_page_width_get(doc, page)); + printf("%d", pdf_page_width_get(doc, opt_width)); } - else if (height == 1) + else if (opt_height > -1) { - printf("%d", pdf_page_height_get(doc, page)); + printf("%d", pdf_page_height_get(doc, opt_height)); } else { diff --git a/src/print.c b/src/print.c index 8b675ea6..db6f8c65 100644 --- a/src/print.c +++ b/src/print.c @@ -352,7 +352,6 @@ pdf_draw_page(GtkPrintOperation *op, char *filename) { cairo_t *cr = NULL; - cairo_surface_t *surface = NULL; int width = 0, height = 0; unsigned char *data = NULL; int stride = 0; @@ -364,12 +363,11 @@ pdf_draw_page(GtkPrintOperation *op, data = pdf_get_data_page (filename, width, height, page_nr); if (data) { - GdkPixbuf *pix = gdk_pixbuf_new_from_data (data, GDK_COLORSPACE_RGB, TRUE, 8, width, height, stride, NULL, g_free); + g_autoptr(GdkPixbuf) pix = gdk_pixbuf_new_from_data (data, GDK_COLORSPACE_RGB, TRUE, 8, width, height, stride, NULL, g_free); cairo_scale(cr, (PTS / DPI), (PTS / DPI)); gdk_cairo_set_source_pixbuf(cr, pix, 0, 0); cairo_paint(cr); cairo_fill (cr); - cairo_surface_destroy (surface); } } @@ -393,8 +391,8 @@ print_pdf(int fd, char *filename = NULL; g_autoptr(GUnixInputStream) istream = NULL; g_autoptr(GUnixOutputStream) ostream = NULL; - GtkPrintSettings *settings = NULL; - GtkPrintOperation *print = NULL; + g_autoptr(GtkPrintSettings) settings = NULL; + g_autoptr(GtkPrintOperation) print = NULL; GError *err = NULL; GVariantBuilder opt_builder; int fd2; @@ -429,8 +427,6 @@ print_pdf(int fd, gtk_print_operation_set_print_settings(print, settings); gtk_print_operation_run(print, GTK_PRINT_OPERATION_ACTION_PRINT, NULL, &err); - g_object_unref (print); - g_object_unref (settings); g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT); xdp_impl_print_complete_print (object, invocation, From b351b312b10cc9f14191812ac815d667ec6f34f5 Mon Sep 17 00:00:00 2001 From: Ordissimo Date: Sat, 1 Jan 2022 12:12:21 +0100 Subject: [PATCH 07/19] Fix cast --- src/print.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/print.c b/src/print.c index db6f8c65..d103dccb 100644 --- a/src/print.c +++ b/src/print.c @@ -389,23 +389,23 @@ print_pdf(int fd, GDBusMethodInvocation *invocation) { char *filename = NULL; - g_autoptr(GUnixInputStream) istream = NULL; - g_autoptr(GUnixOutputStream) ostream = NULL; + g_autoptr(GInputStream) istream = NULL; + g_autoptr(GOutputStream) ostream = NULL; g_autoptr(GtkPrintSettings) settings = NULL; g_autoptr(GtkPrintOperation) print = NULL; GError *err = NULL; GVariantBuilder opt_builder; int fd2; - istream = (GUnixInputStream *)g_unix_input_stream_new (fd, FALSE); + istream = g_unix_input_stream_new (fd, FALSE); if ((fd2 = g_file_open_tmp (PACKAGE_NAME "XXXXXX", &filename, &err)) == -1) return FALSE; - ostream = (GUnixOutputStream *)g_unix_output_stream_new (fd2, TRUE); + ostream = g_unix_output_stream_new (fd2, TRUE); - if (g_output_stream_splice (G_OUTPUT_STREAM (ostream), - G_INPUT_STREAM (istream), + if (g_output_stream_splice (ostream, + istream, G_OUTPUT_STREAM_SPLICE_NONE, NULL, &err) == -1) From d4c63f16af1e5439476be5f577a4f42d16c3538d Mon Sep 17 00:00:00 2001 From: Ordissimo Date: Sat, 1 Jan 2022 20:25:25 +0100 Subject: [PATCH 08/19] Update configure.ac Co-authored-by: Patrick --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 3b8779be..3839eaec 100644 --- a/configure.ac +++ b/configure.ac @@ -109,7 +109,7 @@ if test x$enable_lockdown = xyes; then fi AM_CONDITIONAL([BUILD_LOCKDOWN],[test "$enable_lockdown" = "yes"]) -PKG_CHECK_MODULES(GTK, [xdg-desktop-portal >= 1.5 glib-2.0 >= 2.44 gio-unix-2.0 gtk+-3.0 >= 3.14 gtk+-unix-print-3.0 ]) +PKG_CHECK_MODULES(GTK, [xdg-desktop-portal >= 1.5 glib-2.0 >= 2.44 gio-unix-2.0 gtk+-3.0 >= 3.14 gtk+-unix-print-3.0]) AC_SUBST(GTK_CFLAGS) AC_SUBST(GTK_LIBS) From 033d799c3f85a807c949589f2825abeef3f8ac7b Mon Sep 17 00:00:00 2001 From: Ordissimo Date: Sat, 1 Jan 2022 22:44:02 +0100 Subject: [PATCH 09/19] Fix review. --- src/Makefile.am.inc | 5 ++++- src/pdftoraw.c | 30 ++++++++++++++++-------------- src/print.c | 26 ++++++++++++++------------ 3 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/Makefile.am.inc b/src/Makefile.am.inc index 4cb2e704..28c30d9c 100644 --- a/src/Makefile.am.inc +++ b/src/Makefile.am.inc @@ -112,7 +112,6 @@ EXTRA_DIST += \ libexec_PROGRAMS = \ xdg-desktop-portal-gtk \ - pdftoraw \ $(NULL) xdg_desktop_portal_gtk_SOURCES = \ @@ -292,6 +291,10 @@ pdftoraw_SOURCES = \ src/pdftoraw.c \ $(NULL) +pdftorawdir = $(libexecdir)/xdg-desktop-portal-gtk-utils +pdftoraw_PROGRAMS = \ + pdftoraw \ + $(NULL) pdftoraw_LDADD = $(BASE_LIBS) $(POPPLER_LIBS) -lm pdftoraw_CFLAGS = $(BASE_CFLAGS) $(POPPLER_CFLAGS) pdftoraw_CPPFLAGS = \ diff --git a/src/pdftoraw.c b/src/pdftoraw.c index 07b02a43..2e018d51 100644 --- a/src/pdftoraw.c +++ b/src/pdftoraw.c @@ -48,17 +48,6 @@ static GOptionEntry entries[] = { { NULL } }; -static void -print_usage (void) -{ - printf("Usage:\tpdftoraw --filename= --raw=\n"); - printf("\tpdftoraw --filename= --test\n"); - printf("\tpdftoraw --filename= --pages\n"); - printf("\tpdftoraw --filename= --width=\n"); - printf("\tpdftoraw --filename= --height=\n"); - printf("\tpdftoraw --help\n"); -} - static int pdf_number_pages_get (PopplerDocument *doc) { @@ -81,7 +70,10 @@ pdf_page_raw_get (PopplerDocument *doc, page = poppler_document_get_page(doc, page_nr); if (page == NULL) + { + g_error("failure poppler_document_get_page"); return; + } poppler_page_get_size(page, &width, &height); width = DPI * width / PTS; height = DPI * height / PTS; @@ -89,11 +81,15 @@ pdf_page_raw_get (PopplerDocument *doc, h = (int)ceil(height); s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); if (s == NULL) + { + g_error("failure cairo_image_surface_create"); return; + } cr = cairo_create(s); if (cr == NULL) { cairo_surface_destroy (s); + g_error("failure cairo_create"); return; } cairo_scale (cr, DPI / PTS, DPI / PTS); @@ -168,14 +164,18 @@ main (int argc, char **argv) if (filename == NULL) { + g_printerr ("%s", g_option_context_get_help (context, TRUE, NULL)); + g_option_context_free(context); exit(EXIT_FAILURE); } in = g_file_new_for_path(filename); doc = poppler_document_new_from_gfile(in, NULL, NULL, &err); if (err) { - g_error_free(err); - exit(EXIT_FAILURE); + g_error_free(err); + g_printerr ("%s", g_option_context_get_help (context, TRUE, NULL)); + g_option_context_free(context); + exit(EXIT_FAILURE); } if (opt_test) @@ -200,10 +200,12 @@ main (int argc, char **argv) } else { - print_usage(); + g_printerr ("%s", g_option_context_get_help (context, TRUE, NULL)); + g_option_context_free(context); exit(EXIT_FAILURE); } g_object_unref(doc); + g_option_context_free(context); return 0; } diff --git a/src/print.c b/src/print.c index d103dccb..51b9173c 100644 --- a/src/print.c +++ b/src/print.c @@ -264,20 +264,20 @@ pdf_get_actions_page (char *filename, PDF_ACTIONS act, int page) { - GSubprocess *process; + g_autoptr(GSubprocess) process = NULL; GInputStream *stream; - GPtrArray *args = g_ptr_array_new_full(8, g_free); + g_autoptr(GPtrArray) args = g_ptr_array_new_full(8, g_free); char buffer[50] = { 0 }; - g_ptr_array_add(args, LIBEXECDIR "/pdftoraw"); - g_ptr_array_add(args, g_strconcat ("--file=", filename, NULL)); + g_ptr_array_add(args, g_strdup_printf("%s", LIBEXECDIR "/xdg-desktop-portal-gtk-utils/pdftoraw")); + g_ptr_array_add(args, g_strdup_printf("--file=%s", filename)); switch(act) { case PDF_TEST : - g_ptr_array_add(args, "--test"); + g_ptr_array_add(args, g_strdup("--test")); break; case PDF_NUM_PAGES : - g_ptr_array_add(args, "--pages"); + g_ptr_array_add(args, g_strdup("--pages")); break; case PDF_WIDTH : g_ptr_array_add(args, g_strdup_printf ("--width=%d", page)); @@ -310,15 +310,15 @@ pdf_get_data_page (char *filename, int h, int page) { - GSubprocess *process; + g_autoptr(GSubprocess) process = NULL; GInputStream *stream; unsigned char *data = NULL; - GPtrArray *args = g_ptr_array_new_full(8, g_free); + g_autoptr(GPtrArray) args = g_ptr_array_new_full(8, g_free); int read = 0; gsize total_read = 0; - g_ptr_array_add(args, LIBEXECDIR "/pdftoraw"); - g_ptr_array_add(args, g_strconcat ("--file=", filename, NULL)); + g_ptr_array_add(args, g_strdup_printf("%s", LIBEXECDIR "/xdg-desktop-portal-gtk-utils/pdftoraw")); + g_ptr_array_add(args, g_strdup_printf ("--file=%s", filename)); g_ptr_array_add(args, g_strdup_printf ("--raw=%d", page)); process = g_subprocess_newv((const gchar * const *)args->pdata, G_SUBPROCESS_FLAGS_STDOUT_PIPE, NULL); @@ -327,8 +327,9 @@ pdf_get_data_page (char *filename, stream = g_subprocess_get_stdout_pipe(process); if (stream) { - data = (unsigned char *) g_malloc( w * h * 4); - while ((read = g_input_stream_read(stream, data + total_read, 1024, NULL, NULL)) > 0) + size_t max_size = w * h * 4; + data = (unsigned char *) g_malloc(max_size); + while ((read = g_input_stream_read(stream, data + total_read, 1024, NULL, NULL)) > 0 && max_size < total_read) { total_read += read; } @@ -412,6 +413,7 @@ print_pdf(int fd, return FALSE; if (pdf_get_actions_page (filename, PDF_TEST, -1) == 0) { + g_free (filename); unlink(filename); return FALSE; } From 6e5922e4490dfc89fec78499ca0503f618e1dcb6 Mon Sep 17 00:00:00 2001 From: Ordissimo Date: Sat, 1 Jan 2022 22:46:03 +0100 Subject: [PATCH 10/19] Update src/pdftoraw.c Co-authored-by: Patrick --- src/pdftoraw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pdftoraw.c b/src/pdftoraw.c index 2e018d51..78c57694 100644 --- a/src/pdftoraw.c +++ b/src/pdftoraw.c @@ -39,7 +39,7 @@ static int opt_width = -1; static int opt_height = -1; static GOptionEntry entries[] = { - { "file", 'f', 0, G_OPTION_ARG_STRING, &filename, "PDF file path", NULL }, + { "file", 'f', 0, G_OPTION_ARG_FILENAME, &filename, "PDF file path", NULL }, { "test", 't', 0, G_OPTION_ARG_NONE, &opt_test, "Test if the file is a PDF file", NULL }, { "pages", 'p', 0, G_OPTION_ARG_NONE, &opt_pages, "Returns the number of pages in the PDF file", NULL }, { "width", 'w', 0, G_OPTION_ARG_INT, &opt_width, "Give the size of the page provided in arguments", NULL}, From de462ea05d019a01a92c12a1f27306bb3ad6606f Mon Sep 17 00:00:00 2001 From: Ordissimo Date: Mon, 3 Jan 2022 08:52:42 +0100 Subject: [PATCH 11/19] Fix formatting --- src/pdftoraw.c | 76 +++++++++++++++++++++---------------------- src/print.c | 88 +++++++++++++++++++++++++------------------------- 2 files changed, 82 insertions(+), 82 deletions(-) diff --git a/src/pdftoraw.c b/src/pdftoraw.c index 78c57694..225a4d34 100644 --- a/src/pdftoraw.c +++ b/src/pdftoraw.c @@ -51,7 +51,7 @@ static GOptionEntry entries[] = { static int pdf_number_pages_get (PopplerDocument *doc) { - return poppler_document_get_n_pages(doc); + return poppler_document_get_n_pages (doc); } static void @@ -68,40 +68,40 @@ pdf_page_raw_get (PopplerDocument *doc, int w = 0; int h = 0; - page = poppler_document_get_page(doc, page_nr); + page = poppler_document_get_page (doc, page_nr); if (page == NULL) { g_error("failure poppler_document_get_page"); return; } - poppler_page_get_size(page, &width, &height); + poppler_page_get_size (page, &width, &height); width = DPI * width / PTS; height = DPI * height / PTS; w = (int)ceil(width); h = (int)ceil(height); - s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); + s = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h); if (s == NULL) { - g_error("failure cairo_image_surface_create"); + g_error ("failure cairo_image_surface_create"); return; } - cr = cairo_create(s); + cr = cairo_create (s); if (cr == NULL) { cairo_surface_destroy (s); - g_error("failure cairo_create"); + g_error ("failure cairo_create"); return; } cairo_scale (cr, DPI / PTS, DPI / PTS); cairo_save (cr); - poppler_page_render_for_printing(page, cr); + poppler_page_render_for_printing (page, cr); cairo_restore (cr); - g_object_unref(page); - pix = gdk_pixbuf_get_from_surface(s, 0, 0, w, h); + g_object_unref (page); + pix = gdk_pixbuf_get_from_surface (s, 0, 0, w, h); cairo_surface_destroy (s); data = gdk_pixbuf_get_pixels (pix); - fwrite(data, 1, (w * h * 4), stdout); - cairo_destroy(cr); + fwrite (data, 1, (w * h * 4), stdout); + cairo_destroy (cr); } static int @@ -112,13 +112,13 @@ pdf_page_width_get (PopplerDocument *doc, double width = 0; int w = 0; - page = poppler_document_get_page(doc, page_nr); + page = poppler_document_get_page (doc, page_nr); if (page == NULL) return -1; - poppler_page_get_size(page, &width, NULL); - g_object_unref(page); + poppler_page_get_size (page, &width, NULL); + g_object_unref (page); width = DPI * width / PTS; - w = (int)ceil(width); + w = (int)ceil (width); return w; } @@ -130,13 +130,13 @@ pdf_page_height_get (PopplerDocument *doc, double height = 0; int h = 0; - page = poppler_document_get_page(doc, page_nr); + page = poppler_document_get_page (doc, page_nr); if (page == NULL) return -1; - poppler_page_get_size(page, NULL, &height); - g_object_unref(page); + poppler_page_get_size (page, NULL, &height); + g_object_unref (page); height = DPI * height / PTS; - h = (int)ceil(height); + h = (int)ceil (height); return h; } @@ -145,7 +145,7 @@ main (int argc, char **argv) { PopplerDocument *doc = NULL; GError *err = NULL; - g_autoptr(GFile) in = NULL; + g_autoptr (GFile) in = NULL; GOptionContext *context; @@ -158,54 +158,54 @@ main (int argc, char **argv) g_printerr ("Try \"%s --help\" for more information.", g_get_prgname ()); g_printerr ("\n"); - exit(EXIT_FAILURE); + exit (EXIT_FAILURE); return 1; } if (filename == NULL) { g_printerr ("%s", g_option_context_get_help (context, TRUE, NULL)); - g_option_context_free(context); - exit(EXIT_FAILURE); + g_option_context_free (context); + exit (EXIT_FAILURE); } - in = g_file_new_for_path(filename); - doc = poppler_document_new_from_gfile(in, NULL, NULL, &err); + in = g_file_new_for_path (filename); + doc = poppler_document_new_from_gfile (in, NULL, NULL, &err); if (err) { - g_error_free(err); + g_error_free (err); g_printerr ("%s", g_option_context_get_help (context, TRUE, NULL)); - g_option_context_free(context); - exit(EXIT_FAILURE); + g_option_context_free (context); + exit (EXIT_FAILURE); } if (opt_test) { - printf("1"); + printf ("1"); } else if (opt_raw > -1) { - pdf_page_raw_get(doc, opt_raw); + pdf_page_raw_get (doc, opt_raw); } else if (opt_pages) { - printf("%d", pdf_number_pages_get(doc)); + printf ("%d", pdf_number_pages_get (doc)); } else if (opt_width > -1) { - printf("%d", pdf_page_width_get(doc, opt_width)); + printf ("%d", pdf_page_width_get (doc, opt_width)); } else if (opt_height > -1) { - printf("%d", pdf_page_height_get(doc, opt_height)); + printf ("%d", pdf_page_height_get (doc, opt_height)); } else { g_printerr ("%s", g_option_context_get_help (context, TRUE, NULL)); - g_option_context_free(context); - exit(EXIT_FAILURE); + g_option_context_free (context); + exit (EXIT_FAILURE); } - g_object_unref(doc); - g_option_context_free(context); + g_object_unref (doc); + g_option_context_free (context); return 0; } diff --git a/src/print.c b/src/print.c index 51b9173c..183fb9e7 100644 --- a/src/print.c +++ b/src/print.c @@ -264,41 +264,41 @@ pdf_get_actions_page (char *filename, PDF_ACTIONS act, int page) { - g_autoptr(GSubprocess) process = NULL; + g_autoptr (GSubprocess) process = NULL; GInputStream *stream; - g_autoptr(GPtrArray) args = g_ptr_array_new_full(8, g_free); + g_autoptr(GPtrArray) args = g_ptr_array_new_full (8, g_free); char buffer[50] = { 0 }; - g_ptr_array_add(args, g_strdup_printf("%s", LIBEXECDIR "/xdg-desktop-portal-gtk-utils/pdftoraw")); - g_ptr_array_add(args, g_strdup_printf("--file=%s", filename)); - switch(act) + g_ptr_array_add (args, g_strdup_printf ("%s", LIBEXECDIR "/xdg-desktop-portal-gtk-utils/pdftoraw")); + g_ptr_array_add (args, g_strdup_printf ("--file=%s", filename)); + switch (act) { case PDF_TEST : - g_ptr_array_add(args, g_strdup("--test")); + g_ptr_array_add (args, g_strdup ("--test")); break; case PDF_NUM_PAGES : - g_ptr_array_add(args, g_strdup("--pages")); + g_ptr_array_add (args, g_strdup ("--pages")); break; case PDF_WIDTH : - g_ptr_array_add(args, g_strdup_printf ("--width=%d", page)); + g_ptr_array_add (args, g_strdup_printf ("--width=%d", page)); break; case PDF_HEIGHT : - g_ptr_array_add(args, g_strdup_printf ("--height=%d", page)); + g_ptr_array_add (args, g_strdup_printf ("--height=%d", page)); break; default: return 0; } - process = g_subprocess_newv((const gchar * const *)args->pdata, G_SUBPROCESS_FLAGS_STDOUT_PIPE, NULL); + process = g_subprocess_newv ((const gchar * const *)args->pdata, G_SUBPROCESS_FLAGS_STDOUT_PIPE, NULL); if (process) { - stream = g_subprocess_get_stdout_pipe(process); + stream = g_subprocess_get_stdout_pipe (process); if (stream) { - g_input_stream_read(stream, buffer, sizeof(buffer), NULL, NULL); + g_input_stream_read (stream, buffer, sizeof(buffer), NULL, NULL); if (buffer[0]) - return atoi(buffer); + return atoi (buffer); } } return 0; @@ -310,26 +310,26 @@ pdf_get_data_page (char *filename, int h, int page) { - g_autoptr(GSubprocess) process = NULL; + g_autoptr (GSubprocess) process = NULL; GInputStream *stream; unsigned char *data = NULL; - g_autoptr(GPtrArray) args = g_ptr_array_new_full(8, g_free); + g_autoptr (GPtrArray) args = g_ptr_array_new_full (8, g_free); int read = 0; gsize total_read = 0; - g_ptr_array_add(args, g_strdup_printf("%s", LIBEXECDIR "/xdg-desktop-portal-gtk-utils/pdftoraw")); - g_ptr_array_add(args, g_strdup_printf ("--file=%s", filename)); - g_ptr_array_add(args, g_strdup_printf ("--raw=%d", page)); - process = g_subprocess_newv((const gchar * const *)args->pdata, G_SUBPROCESS_FLAGS_STDOUT_PIPE, NULL); + g_ptr_array_add (args, g_strdup_printf ("%s", LIBEXECDIR "/xdg-desktop-portal-gtk-utils/pdftoraw")); + g_ptr_array_add (args, g_strdup_printf ("--file=%s", filename)); + g_ptr_array_add (args, g_strdup_printf ("--raw=%d", page)); + process = g_subprocess_newv ((const gchar * const *)args->pdata, G_SUBPROCESS_FLAGS_STDOUT_PIPE, NULL); if (process) { - stream = g_subprocess_get_stdout_pipe(process); + stream = g_subprocess_get_stdout_pipe (process); if (stream) { size_t max_size = w * h * 4; - data = (unsigned char *) g_malloc(max_size); - while ((read = g_input_stream_read(stream, data + total_read, 1024, NULL, NULL)) > 0 && max_size < total_read) + data = (unsigned char *) g_malloc (max_size); + while ((read = g_input_stream_read (stream, data + total_read, 1024, NULL, NULL)) > 0 && max_size < total_read) { total_read += read; } @@ -339,11 +339,11 @@ pdf_get_data_page (char *filename, } static void -pdf_begin_print(GtkPrintOperation *op, - GtkPrintContext *ctx, - char *filename) +pdf_begin_print (GtkPrintOperation *op, + GtkPrintContext *ctx, + char *filename) { - gtk_print_operation_set_n_pages(op, pdf_get_actions_page(filename, PDF_NUM_PAGES, 0)); + gtk_print_operation_set_n_pages (op, pdf_get_actions_page (filename, PDF_NUM_PAGES, 0)); } static void @@ -359,15 +359,15 @@ pdf_draw_page(GtkPrintOperation *op, width = pdf_get_actions_page (filename, PDF_WIDTH, page_nr); height = pdf_get_actions_page (filename, PDF_HEIGHT, page_nr); - cr = gtk_print_context_get_cairo_context(ctx); + cr = gtk_print_context_get_cairo_context (ctx); stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width); data = pdf_get_data_page (filename, width, height, page_nr); if (data) { - g_autoptr(GdkPixbuf) pix = gdk_pixbuf_new_from_data (data, GDK_COLORSPACE_RGB, TRUE, 8, width, height, stride, NULL, g_free); - cairo_scale(cr, (PTS / DPI), (PTS / DPI)); - gdk_cairo_set_source_pixbuf(cr, pix, 0, 0); - cairo_paint(cr); + g_autoptr (GdkPixbuf) pix = gdk_pixbuf_new_from_data (data, GDK_COLORSPACE_RGB, TRUE, 8, width, height, stride, NULL, g_free); + cairo_scale (cr, (PTS / DPI), (PTS / DPI)); + gdk_cairo_set_source_pixbuf (cr, pix, 0, 0); + cairo_paint (cr); cairo_fill (cr); } } @@ -390,10 +390,10 @@ print_pdf(int fd, GDBusMethodInvocation *invocation) { char *filename = NULL; - g_autoptr(GInputStream) istream = NULL; - g_autoptr(GOutputStream) ostream = NULL; - g_autoptr(GtkPrintSettings) settings = NULL; - g_autoptr(GtkPrintOperation) print = NULL; + g_autoptr (GInputStream) istream = NULL; + g_autoptr (GOutputStream) ostream = NULL; + g_autoptr (GtkPrintSettings) settings = NULL; + g_autoptr (GtkPrintOperation) print = NULL; GError *err = NULL; GVariantBuilder opt_builder; int fd2; @@ -414,21 +414,21 @@ print_pdf(int fd, if (pdf_get_actions_page (filename, PDF_TEST, -1) == 0) { g_free (filename); - unlink(filename); + unlink (filename); return FALSE; } - print = gtk_print_operation_new(); + print = gtk_print_operation_new (); gtk_print_operation_set_use_full_page (print, TRUE); gtk_print_operation_set_unit (print, GTK_UNIT_POINTS); gtk_print_operation_set_embed_page_setup (print, TRUE); - settings = gtk_print_settings_new(); - g_signal_connect(print, "begin-print", G_CALLBACK(pdf_begin_print), filename); - g_signal_connect(print, "draw-page", G_CALLBACK(pdf_draw_page), filename); - g_signal_connect(print, "end-print", G_CALLBACK(pdf_end_print), filename); - gtk_print_operation_set_print_settings(print, settings); + settings = gtk_print_settings_new (); + g_signal_connect (print, "begin-print", G_CALLBACK(pdf_begin_print), filename); + g_signal_connect (print, "draw-page", G_CALLBACK(pdf_draw_page), filename); + g_signal_connect (print, "end-print", G_CALLBACK(pdf_end_print), filename); + gtk_print_operation_set_print_settings (print, settings); - gtk_print_operation_run(print, GTK_PRINT_OPERATION_ACTION_PRINT, NULL, &err); + gtk_print_operation_run (print, GTK_PRINT_OPERATION_ACTION_PRINT, NULL, &err); g_variant_builder_init (&opt_builder, G_VARIANT_TYPE_VARDICT); xdp_impl_print_complete_print (object, invocation, @@ -669,7 +669,7 @@ handle_print (XdpImplPrint *object, g_variant_builder_end (&opt_builder)); return TRUE; } - else if (print_pdf(fd, object, invocation) == FALSE) + else if (print_pdf (fd, object, invocation) == FALSE) { sender = g_dbus_method_invocation_get_sender (invocation); request = request_new (sender, arg_app_id, arg_handle); From 2c6c0673cf008b785a413e349e80e2d0c2abe437 Mon Sep 17 00:00:00 2001 From: Ordissimo Date: Mon, 3 Jan 2022 09:42:46 +0100 Subject: [PATCH 12/19] Fix formatting and leaks --- src/pdftoraw.c | 14 ++++++++------ src/print.c | 8 ++++---- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/pdftoraw.c b/src/pdftoraw.c index 225a4d34..f9f1aaef 100644 --- a/src/pdftoraw.c +++ b/src/pdftoraw.c @@ -31,6 +31,9 @@ // Resolution for the printer, 150 my choice #define DPI 150.0 +G_DEFINE_AUTOPTR_CLEANUP_FUNC (PopplerDocument, g_object_unref); +G_DEFINE_AUTOPTR_CLEANUP_FUNC (PopplerPage, g_object_unref); + static gchar *filename = ""; static gboolean opt_test = FALSE; static gboolean opt_pages = FALSE; @@ -61,8 +64,8 @@ pdf_page_raw_get (PopplerDocument *doc, cairo_surface_t *s = NULL; cairo_t *cr = NULL; unsigned char *data = NULL; - PopplerPage *page = NULL; - g_autoptr(GdkPixbuf) pix = NULL; + g_autoptr (PopplerPage) page = NULL; + g_autoptr (GdkPixbuf) pix = NULL; double width = 0; double height = 0; int w = 0; @@ -108,7 +111,7 @@ static int pdf_page_width_get (PopplerDocument *doc, int page_nr) { - PopplerPage *page = NULL; + g_autoptr (PopplerPage) page = NULL; double width = 0; int w = 0; @@ -126,7 +129,7 @@ static int pdf_page_height_get (PopplerDocument *doc, int page_nr) { - PopplerPage *page = NULL; + g_autoptr (PopplerPage) page = NULL; double height = 0; int h = 0; @@ -143,7 +146,7 @@ pdf_page_height_get (PopplerDocument *doc, int main (int argc, char **argv) { - PopplerDocument *doc = NULL; + g_autoptr (PopplerDocument) doc = NULL; GError *err = NULL; g_autoptr (GFile) in = NULL; @@ -204,7 +207,6 @@ main (int argc, char **argv) g_option_context_free (context); exit (EXIT_FAILURE); } - g_object_unref (doc); g_option_context_free (context); return 0; } diff --git a/src/print.c b/src/print.c index 183fb9e7..59458204 100644 --- a/src/print.c +++ b/src/print.c @@ -296,7 +296,7 @@ pdf_get_actions_page (char *filename, stream = g_subprocess_get_stdout_pipe (process); if (stream) { - g_input_stream_read (stream, buffer, sizeof(buffer), NULL, NULL); + g_input_stream_read (stream, buffer, sizeof (buffer), NULL, NULL); if (buffer[0]) return atoi (buffer); } @@ -423,9 +423,9 @@ print_pdf(int fd, gtk_print_operation_set_unit (print, GTK_UNIT_POINTS); gtk_print_operation_set_embed_page_setup (print, TRUE); settings = gtk_print_settings_new (); - g_signal_connect (print, "begin-print", G_CALLBACK(pdf_begin_print), filename); - g_signal_connect (print, "draw-page", G_CALLBACK(pdf_draw_page), filename); - g_signal_connect (print, "end-print", G_CALLBACK(pdf_end_print), filename); + g_signal_connect (print, "begin-print", G_CALLBACK (pdf_begin_print), filename); + g_signal_connect (print, "draw-page", G_CALLBACK (pdf_draw_page), filename); + g_signal_connect (print, "end-print", G_CALLBACK (pdf_end_print), filename); gtk_print_operation_set_print_settings (print, settings); gtk_print_operation_run (print, GTK_PRINT_OPERATION_ACTION_PRINT, NULL, &err); From cdb35ce16e0299b46ea57d47f952c1574f3f6b23 Mon Sep 17 00:00:00 2001 From: thierry1970 Date: Mon, 3 Jan 2022 17:22:11 +0100 Subject: [PATCH 13/19] Correcting leaks and operation --- src/pdftoraw.c | 3 --- src/print.c | 6 +++++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/pdftoraw.c b/src/pdftoraw.c index f9f1aaef..8c270665 100644 --- a/src/pdftoraw.c +++ b/src/pdftoraw.c @@ -99,7 +99,6 @@ pdf_page_raw_get (PopplerDocument *doc, cairo_save (cr); poppler_page_render_for_printing (page, cr); cairo_restore (cr); - g_object_unref (page); pix = gdk_pixbuf_get_from_surface (s, 0, 0, w, h); cairo_surface_destroy (s); data = gdk_pixbuf_get_pixels (pix); @@ -119,7 +118,6 @@ pdf_page_width_get (PopplerDocument *doc, if (page == NULL) return -1; poppler_page_get_size (page, &width, NULL); - g_object_unref (page); width = DPI * width / PTS; w = (int)ceil (width); return w; @@ -137,7 +135,6 @@ pdf_page_height_get (PopplerDocument *doc, if (page == NULL) return -1; poppler_page_get_size (page, NULL, &height); - g_object_unref (page); height = DPI * height / PTS; h = (int)ceil (height); return h; diff --git a/src/print.c b/src/print.c index 59458204..f6060e32 100644 --- a/src/print.c +++ b/src/print.c @@ -267,6 +267,7 @@ pdf_get_actions_page (char *filename, g_autoptr (GSubprocess) process = NULL; GInputStream *stream; g_autoptr(GPtrArray) args = g_ptr_array_new_full (8, g_free); + g_autoptr (GError) err = NULL; char buffer[50] = { 0 }; g_ptr_array_add (args, g_strdup_printf ("%s", LIBEXECDIR "/xdg-desktop-portal-gtk-utils/pdftoraw")); @@ -288,6 +289,7 @@ pdf_get_actions_page (char *filename, default: return 0; } + g_ptr_array_add (args, NULL); process = g_subprocess_newv ((const gchar * const *)args->pdata, G_SUBPROCESS_FLAGS_STDOUT_PIPE, NULL); @@ -316,10 +318,12 @@ pdf_get_data_page (char *filename, g_autoptr (GPtrArray) args = g_ptr_array_new_full (8, g_free); int read = 0; gsize total_read = 0; + g_autoptr (GError) err = NULL; g_ptr_array_add (args, g_strdup_printf ("%s", LIBEXECDIR "/xdg-desktop-portal-gtk-utils/pdftoraw")); g_ptr_array_add (args, g_strdup_printf ("--file=%s", filename)); g_ptr_array_add (args, g_strdup_printf ("--raw=%d", page)); + g_ptr_array_add (args, NULL); process = g_subprocess_newv ((const gchar * const *)args->pdata, G_SUBPROCESS_FLAGS_STDOUT_PIPE, NULL); if (process) @@ -329,7 +333,7 @@ pdf_get_data_page (char *filename, { size_t max_size = w * h * 4; data = (unsigned char *) g_malloc (max_size); - while ((read = g_input_stream_read (stream, data + total_read, 1024, NULL, NULL)) > 0 && max_size < total_read) + while ((read = g_input_stream_read (stream, data + total_read, 1024, NULL, NULL)) > 0 && max_size > total_read) { total_read += read; } From 88d1d47c7e8c720df2d5c87a33cc23cbe5eba308 Mon Sep 17 00:00:00 2001 From: Ordissimo Date: Mon, 3 Jan 2022 22:19:10 +0100 Subject: [PATCH 14/19] Update src/pdftoraw.c Co-authored-by: Patrick --- src/pdftoraw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pdftoraw.c b/src/pdftoraw.c index 8c270665..6cb76bf2 100644 --- a/src/pdftoraw.c +++ b/src/pdftoraw.c @@ -144,7 +144,7 @@ int main (int argc, char **argv) { g_autoptr (PopplerDocument) doc = NULL; - GError *err = NULL; + g_autoptr(GError) err = NULL; g_autoptr (GFile) in = NULL; GOptionContext *context; From 8d1394ce2b18bfcf9058007e085616210277169b Mon Sep 17 00:00:00 2001 From: Ordissimo Date: Mon, 3 Jan 2022 22:19:46 +0100 Subject: [PATCH 15/19] Update src/pdftoraw.c Co-authored-by: Patrick --- src/pdftoraw.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pdftoraw.c b/src/pdftoraw.c index 6cb76bf2..e214f61f 100644 --- a/src/pdftoraw.c +++ b/src/pdftoraw.c @@ -146,7 +146,6 @@ main (int argc, char **argv) g_autoptr (PopplerDocument) doc = NULL; g_autoptr(GError) err = NULL; g_autoptr (GFile) in = NULL; - GOptionContext *context; context = g_option_context_new ("- PDF utility for portal backends"); From 8b9fb55184bdb9d618daa9d12a9c1cdedf63150c Mon Sep 17 00:00:00 2001 From: Ordissimo Date: Mon, 3 Jan 2022 22:47:36 +0100 Subject: [PATCH 16/19] Fix review. --- src/pdftoraw.c | 17 ++++++++--------- src/print.c | 11 ++++++++--- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/pdftoraw.c b/src/pdftoraw.c index e214f61f..9a62240e 100644 --- a/src/pdftoraw.c +++ b/src/pdftoraw.c @@ -146,7 +146,8 @@ main (int argc, char **argv) g_autoptr (PopplerDocument) doc = NULL; g_autoptr(GError) err = NULL; g_autoptr (GFile) in = NULL; - GOptionContext *context; + g_autoptr (GOptionContext) context = NULL; + g_autofree char *help = NULL; context = g_option_context_new ("- PDF utility for portal backends"); g_option_context_add_main_entries (context, entries, NULL); @@ -163,17 +164,16 @@ main (int argc, char **argv) if (filename == NULL) { - g_printerr ("%s", g_option_context_get_help (context, TRUE, NULL)); - g_option_context_free (context); + help = g_option_context_get_help (context, TRUE, NULL); + g_printerr ("%s", help); exit (EXIT_FAILURE); } in = g_file_new_for_path (filename); doc = poppler_document_new_from_gfile (in, NULL, NULL, &err); if (err) { - g_error_free (err); - g_printerr ("%s", g_option_context_get_help (context, TRUE, NULL)); - g_option_context_free (context); + help = g_option_context_get_help (context, TRUE, NULL); + g_printerr ("%s", help); exit (EXIT_FAILURE); } @@ -199,11 +199,10 @@ main (int argc, char **argv) } else { - g_printerr ("%s", g_option_context_get_help (context, TRUE, NULL)); - g_option_context_free (context); + help = g_option_context_get_help (context, TRUE, NULL); + g_printerr ("%s", help); exit (EXIT_FAILURE); } - g_option_context_free (context); return 0; } diff --git a/src/print.c b/src/print.c index f6060e32..1497ef43 100644 --- a/src/print.c +++ b/src/print.c @@ -46,7 +46,7 @@ // 1 inch = 72 points #define PTS 72.0 -// Resolution for the printer, 150 my choice +// 150 is a reasonable resolution for consumer printing #define DPI 150.0 typedef enum { @@ -414,11 +414,16 @@ print_pdf(int fd, G_OUTPUT_STREAM_SPLICE_NONE, NULL, &err) == -1) - return FALSE; - if (pdf_get_actions_page (filename, PDF_TEST, -1) == 0) { + unlink (filename); g_free (filename); + return FALSE; + } + + if (pdf_get_actions_page (filename, PDF_TEST, -1) == 0) + { unlink (filename); + g_free (filename); return FALSE; } From 47467e7fc1beb9058a9fd68cce5e72245e56d48f Mon Sep 17 00:00:00 2001 From: Ordissimo Date: Mon, 3 Jan 2022 23:07:11 +0100 Subject: [PATCH 17/19] Check read size stdout. --- src/print.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/print.c b/src/print.c index 1497ef43..6ff31199 100644 --- a/src/print.c +++ b/src/print.c @@ -332,10 +332,16 @@ pdf_get_data_page (char *filename, if (stream) { size_t max_size = w * h * 4; + int buff_size = 1024; + int to_be_read = 0 data = (unsigned char *) g_malloc (max_size); - while ((read = g_input_stream_read (stream, data + total_read, 1024, NULL, NULL)) > 0 && max_size > total_read) + while (max_size > total_read && (read = g_input_stream_read (stream, data + total_read, buff_size, NULL, NULL))) { total_read += read; + to_be_read = max_size - total_read; + + if (to_be_read < buff_size) + buff_size = to_be_read; } } } From 98e47a39070e91ada278c60ffe3501a448ec5529 Mon Sep 17 00:00:00 2001 From: Ordissimo Date: Mon, 3 Jan 2022 23:13:21 +0100 Subject: [PATCH 18/19] Fix build --- src/print.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/print.c b/src/print.c index 6ff31199..6d1a963f 100644 --- a/src/print.c +++ b/src/print.c @@ -333,7 +333,7 @@ pdf_get_data_page (char *filename, { size_t max_size = w * h * 4; int buff_size = 1024; - int to_be_read = 0 + int to_be_read = 0; data = (unsigned char *) g_malloc (max_size); while (max_size > total_read && (read = g_input_stream_read (stream, data + total_read, buff_size, NULL, NULL))) { From ee2cc5127128777418bff6d1956e7ae849d391c5 Mon Sep 17 00:00:00 2001 From: Ordissimo Date: Mon, 17 Jan 2022 18:47:10 +0100 Subject: [PATCH 19/19] Add libpoppler-glib as a build option. --- configure.ac | 14 ++++++++++---- src/Makefile.am.inc | 2 ++ src/print.c | 9 ++++++++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 3839eaec..8b2583da 100644 --- a/configure.ac +++ b/configure.ac @@ -109,14 +109,20 @@ if test x$enable_lockdown = xyes; then fi AM_CONDITIONAL([BUILD_LOCKDOWN],[test "$enable_lockdown" = "yes"]) +AC_ARG_ENABLE([poppler], + [AS_HELP_STRING([--enable-poppler],[Build pdftoraw portal. Needs libpoppler-glib])]) +AS_IF([test "x$enable_poppler" = "xyes"], [ + PKG_CHECK_MODULES(POPPLER, [ gtk+-3.0 >= 3.14 gio-unix-2.0 poppler >= 0.16.7 poppler-glib >= 0.16.7 ]) + AC_SUBST(POPPLER_CFLAGS) + AC_SUBST(POPPLER_LIBS) + AC_DEFINE([BUILD_POPPLER], [1], [Define to enable pdftoraw portal]) +]) +AM_CONDITIONAL([BUILD_POPPLER],[test "$enable_poppler" = "yes"]) + PKG_CHECK_MODULES(GTK, [xdg-desktop-portal >= 1.5 glib-2.0 >= 2.44 gio-unix-2.0 gtk+-3.0 >= 3.14 gtk+-unix-print-3.0]) AC_SUBST(GTK_CFLAGS) AC_SUBST(GTK_LIBS) -PKG_CHECK_MODULES(POPPLER, [ gtk+-3.0 >= 3.14 gio-unix-2.0 poppler >= 0.16.7 poppler-glib >= 0.16.7 ]) -AC_SUBST(POPPLER_CFLAGS) -AC_SUBST(POPPLER_LIBS) - PKG_CHECK_MODULES(GTK_X11, gtk+-x11-3.0, have_gtk_x11=yes, have_gtk_x11=no) if test "$have_gtk_x11" = "yes"; then diff --git a/src/Makefile.am.inc b/src/Makefile.am.inc index 28c30d9c..a8515494 100644 --- a/src/Makefile.am.inc +++ b/src/Makefile.am.inc @@ -287,6 +287,7 @@ nodist_testappchooser_SOURCES = \ src/resources.c \ $(NULL) +if BUILD_POPPLER pdftoraw_SOURCES = \ src/pdftoraw.c \ $(NULL) @@ -301,3 +302,4 @@ pdftoraw_CPPFLAGS = \ -I$(top_srcdir)/src \ -I$(top_builddir)/src \ $(NULL) +endif diff --git a/src/print.c b/src/print.c index 6d1a963f..70860ad4 100644 --- a/src/print.c +++ b/src/print.c @@ -43,6 +43,7 @@ #include "gtkbackports.h" +#ifdef BUILD_POPPLER // 1 inch = 72 points #define PTS 72.0 @@ -55,6 +56,7 @@ typedef enum { PDF_WIDTH, PDF_HEIGHT } PDF_ACTIONS; +#endif typedef struct { char *app_id; @@ -259,6 +261,7 @@ launch_preview (const char *filename, return retval; } +#ifdef BUILD_POPPLER static int pdf_get_actions_page (char *filename, PDF_ACTIONS act, @@ -452,6 +455,7 @@ print_pdf(int fd, g_variant_builder_end (&opt_builder)); return TRUE; } +#endif static gboolean print_file (int fd, @@ -684,7 +688,10 @@ handle_print (XdpImplPrint *object, g_variant_builder_end (&opt_builder)); return TRUE; } - else if (print_pdf (fd, object, invocation) == FALSE) + else +#ifdef BUILD_POPPLER + if (print_pdf (fd, object, invocation) == FALSE) +#endif { sender = g_dbus_method_invocation_get_sender (invocation); request = request_new (sender, arg_app_id, arg_handle);