X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=ps%2Fps-document.c;h=958d7687c2a196213d4604ee0c032ebce667616c;hb=4e98bb0cf26487d84baf482bb75dcea8b8db465a;hp=c7263bc1fce04d98826abf54b104a30568ecec1c;hpb=eaa64d066e4b4e7e85d5045e5cb16ab2c19716f9;p=evince.git diff --git a/ps/ps-document.c b/ps/ps-document.c index c7263bc1..958d7687 100644 --- a/ps/ps-document.c +++ b/ps/ps-document.c @@ -216,6 +216,7 @@ static gint start_interpreter(PSDocument * gs); gboolean computeSize(void); static gboolean ps_document_set_page_size(PSDocument * gs, gint new_pagesize, gint pageid); static void ps_document_document_iface_init (EvDocumentIface *iface); +static gboolean ps_document_goto_page(PSDocument * gs, gint page); static GObjectClass *parent_class = NULL; @@ -226,7 +227,7 @@ ps_document_init(PSDocument * gs) { gs->bpixmap = NULL; - gs->current_page = -2; + gs->current_page = 0; gs->disable_start = FALSE; gs->interpreter_pid = -1; @@ -277,14 +278,11 @@ ps_document_init(PSDocument * gs) gs->page_y_offset = 0; /* Set user defined defaults */ - gs->override_orientation = gtk_gs_defaults_get_override_orientation(); - gs->fallback_orientation = gtk_gs_defaults_get_orientation(); - gs->zoom_factor = gtk_gs_defaults_get_zoom_factor(); - gs->default_size = gtk_gs_defaults_get_size(); - gs->antialiased = gtk_gs_defaults_get_antialiased(); - gs->override_size = gtk_gs_defaults_get_override_size(); - gs->respect_eof = gtk_gs_defaults_get_respect_eof(); - gs->zoom_mode = gtk_gs_defaults_get_zoom_mode(); + gs->fallback_orientation = GTK_GS_ORIENTATION_PORTRAIT; + gs->zoom_factor = 1.0; + gs->default_size = 1; + gs->antialiased = TRUE; + gs->respect_eof = TRUE; gs->gs_status = _("No document loaded."); } @@ -325,12 +323,12 @@ ps_document_get_property (GObject *object, } static void -ps_document_class_init(PSDocumentClass * klass) +ps_document_class_init(PSDocumentClass *klass) { GObjectClass *object_class; object_class = (GObjectClass *) klass; - parent_class = gtk_type_class(gtk_widget_get_type()); + parent_class = g_type_class_peek_parent (klass); gs_class = klass; object_class->finalize = ps_document_finalize; @@ -343,8 +341,6 @@ ps_document_class_init(PSDocumentClass * klass) klass->page_atom = gdk_atom_intern("PAGE", FALSE); klass->string_atom = gdk_atom_intern("STRING", FALSE); - gtk_gs_defaults_load(); - g_object_class_override_property (object_class, PROP_TITLE, "title"); } @@ -379,7 +375,7 @@ ps_document_cleanup(PSDocument * gs) g_free(gs->gs_filename_unc); gs->gs_filename_unc = NULL; } - gs->current_page = -1; + gs->current_page = 0; gs->loaded = FALSE; gs->llx = 0; gs->lly = 0; @@ -388,6 +384,63 @@ ps_document_cleanup(PSDocument * gs) set_up_page(gs); } +static gboolean +ps_document_widget_event (GtkWidget *widget, GdkEvent *event, gpointer data) +{ + PSDocument *gs = (PSDocument *) data; + + if(event->type != GDK_CLIENT_EVENT) + return FALSE; + + gs->message_window = event->client.data.l[0]; + + if (event->client.message_type == gs_class->page_atom) { + LOG ("GS rendered the document"); + gs->busy = FALSE; + + if (gs->scaling) { + ev_document_scale_changed (EV_DOCUMENT (gs)); + gs->scaling = FALSE; + } else { + ev_document_page_changed (EV_DOCUMENT (gs)); + } + } + + return TRUE; +} + +static void +ps_document_set_target (EvDocument *document, + GdkDrawable *target) +{ + PSDocument *gs = PS_DOCUMENT (document); + GtkWidget *widget; + gpointer data; + + if (gs->pstarget) { + gdk_window_get_user_data (gs->pstarget, &data); + g_return_if_fail (GTK_IS_WIDGET (data)); + + widget = GTK_WIDGET (data); + g_signal_handlers_disconnect_by_func + (widget, ps_document_widget_event, document); + } + + gs->pstarget = target; + + if (gs->pstarget) { + gdk_window_get_user_data (gs->pstarget, &data); + g_return_if_fail (GTK_IS_WIDGET (data)); + + widget = GTK_WIDGET (data); + g_signal_connect (widget, "event", + G_CALLBACK (ps_document_widget_event), + document); + } + + ps_document_goto_page (gs, gs->current_page); +} + static void ps_document_finalize (GObject * object) { @@ -396,13 +449,15 @@ ps_document_finalize (GObject * object) g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_GS (object)); - LOG ("Finalize") + LOG ("Finalize"); gs = PS_DOCUMENT (object); ps_document_cleanup (gs); stop_interpreter (gs); + ps_document_set_target (EV_DOCUMENT (object), NULL); + if(gs->input_buffer) { g_free(gs->input_buffer); gs->input_buffer = NULL; @@ -470,8 +525,7 @@ ps_document_get_orientation(PSDocument * gs) gs->real_orientation = gs->doc->orientation; } - if(gs->override_orientation || - gs->real_orientation == GTK_GS_ORIENTATION_NONE) + if(gs->real_orientation == GTK_GS_ORIENTATION_NONE) return gs->fallback_orientation; else return gs->real_orientation; @@ -486,13 +540,16 @@ set_up_page(PSDocument * gs) GdkGC *fill; GdkColor white = { 0, 0xFFFF, 0xFFFF, 0xFFFF }; /* pixel, r, g, b */ GdkColormap *colormap; - - LOG ("Setup the page") + gboolean size_changed; #ifdef HAVE_LOCALE_H char *savelocale; #endif + LOG ("Setup the page"); + + size_changed = compute_size (gs); + if (gs->pstarget == NULL) return; @@ -502,7 +559,7 @@ set_up_page(PSDocument * gs) orientation = ps_document_get_orientation(gs); - if(compute_size(gs)) { + if (size_changed || gs->bpixmap == NULL) { gdk_flush(); /* clear new pixmap (set to white) */ @@ -518,7 +575,7 @@ set_up_page(PSDocument * gs) gs->bpixmap = NULL; } - LOG ("Create our internal pixmap") + LOG ("Create our internal pixmap"); gs->bpixmap = gdk_pixmap_new(gs->pstarget, gs->width, gs->height, -1); gdk_draw_rectangle(gs->bpixmap, fill, TRUE, @@ -554,6 +611,8 @@ set_up_page(PSDocument * gs) gs->left_margin, gs->bottom_margin, gs->right_margin, gs->top_margin); + LOG ("GS property %s", buf); + #ifdef HAVE_LOCALE_H setlocale(LC_NUMERIC, savelocale); #endif @@ -718,8 +777,6 @@ start_interpreter(PSDocument * gs) int std_out[2]; /* pipe from interp stdout */ int std_err[2]; /* pipe from interp stderr */ - LOG ("Start the interpreter") - #define NUM_ARGS 100 #define NUM_GS_ARGS (NUM_ARGS - 20) #define NUM_ALPHA_ARGS 10 @@ -728,6 +785,8 @@ start_interpreter(PSDocument * gs) char **gs_args, **alpha_args = NULL; int argc = 0, i; + LOG ("Start the interpreter"); + if(!gs->gs_filename) return 0; @@ -784,6 +843,12 @@ start_interpreter(PSDocument * gs) return -1; } + gv_env = g_strdup_printf("GHOSTVIEW=%ld %ld", + gdk_x11_drawable_get_xid(gs->pstarget), + gdk_x11_drawable_get_xid(gs->bpixmap)); + + LOG ("Launching ghostview with env %s", gv_env); + gs->busy = TRUE; gs->interpreter_pid = fork(); switch (gs->interpreter_pid) { @@ -819,13 +884,8 @@ start_interpreter(PSDocument * gs) } } - gv_env = g_strdup_printf("GHOSTVIEW=%ld %ld", - gdk_x11_drawable_get_xid(gs->pstarget), - gdk_x11_drawable_get_xid(gs->bpixmap)); putenv(gv_env); - LOG ("Launching ghostview with env %s", gv_env) - /* change to directory where the input file is. This helps * with postscript-files which include other files using * a relative path */ @@ -873,7 +933,7 @@ stop_interpreter(PSDocument * gs) { if(gs->interpreter_pid > 0) { int status = 0; - LOG ("Stop the interpreter") + LOG ("Stop the interpreter"); kill(gs->interpreter_pid, SIGTERM); while((wait(&status) == -1) && (errno == EINTR)) ; gs->interpreter_pid = -1; @@ -1024,113 +1084,6 @@ check_filecompressed(PSDocument * gs) return filename_unc; } -/* - * Check if gs->gs_filename or gs->gs_filename_unc is a pdf file and scan - * pdf file if necessary. - * Set gs->filename_dsc to the name of the dsc file or NULL. - * Error reporting via signal 'interpreter_message'. - */ -static gchar * -check_pdf(PSDocument * gs) -{ - FILE *file; - gchar buf[1024], *filename; - int fd; - - /* use uncompressed file as input if necessary */ - filename = (gs->gs_filename_unc ? gs->gs_filename_unc : gs->gs_filename); - - if((file = fopen(filename, "r")) - && (fread(buf, sizeof(char), 5, file) == 5) - && (strncmp(buf, "%PDF-", 5) == 0)) { - /* we found a PDF file */ - gchar *fname, *filename_dsc, *filename_err, *cmd, *cmdline; - filename_dsc = g_strconcat(g_get_tmp_dir(), "/ggvXXXXXX", NULL); - if((fd = mkstemp(filename_dsc)) < 0) { - return NULL; - } - close(fd); - filename_err = g_strconcat(g_get_tmp_dir(), "/ggvXXXXXX", NULL); - if((fd = mkstemp(filename_err)) < 0) { - g_free(filename_dsc); - return NULL; - } - close(fd); - fname = g_shell_quote(filename); - cmd = g_strdup_printf(gtk_gs_defaults_get_dsc_cmd(), filename_dsc, fname); - g_free(fname); - /* this command (sometimes?) prints error messages to stdout! */ - cmdline = g_strdup_printf("%s >%s 2>&1", cmd, filename_err); - g_free(cmd); - - if((system(cmdline) == 0) && file_readable(filename_dsc)) { - - /* success */ - filename = gs->gs_filename_dsc = filename_dsc; - - if(file_length(filename_err) > 0) { - gchar *err_msg = " "; - GtkWidget *dialog; - FILE *err; - GdkColor color; - - if((err = fopen(filename_err, "r"))) { - - /* print the content of the file to a message box */ - while(fgets(buf, 1024, err)) - err_msg = g_strconcat(err_msg, buf, NULL); - - /* FIXME The dialog is not yet set to modal, difficult to - * get the parent of the dialog box here - */ - - dialog = gtk_message_dialog_new(NULL, - GTK_DIALOG_MODAL, - GTK_MESSAGE_WARNING, - GTK_BUTTONS_OK, - ("There was an error while scaning the file: %s \n%s"), - gs->gs_filename, err_msg); - - gdk_color_parse("white", &color); - gtk_widget_modify_bg(GTK_WIDGET(dialog), GTK_STATE_NORMAL, &color); - - g_signal_connect(G_OBJECT(dialog), "response", - G_CALLBACK(gtk_widget_destroy), NULL); - - gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE); - gtk_widget_show(dialog); - g_free(err_msg); - } - } - - } - else { - /* report error */ - g_snprintf(buf, 1024, - _("Error while converting pdf file %s:\n"), filename); - ps_document_emit_error_msg(gs, buf); - - if(file_length(filename_err) > 0) { - FILE *err; - if((err = fopen(filename_err, "r"))) { - /* print file to message window */ - while(fgets(buf, 1024, err)) - ps_document_emit_error_msg(gs, buf); - } - } - unlink(filename_dsc); - g_free(filename_dsc); - filename = NULL; - } - unlink(filename_err); - g_free(filename_err); - g_free(cmdline); - } - if(NULL != file) - fclose(file); - return filename; -} - #ifdef BROKEN_XINERAMA_PATCH_THAT_SHOULD_NOT_BE_USED /* never mind this patch: a properly working X server should take care of calculating the proper values. */ @@ -1297,7 +1250,7 @@ document_load(PSDocument * gs, const gchar * fname) g_return_val_if_fail(gs != NULL, FALSE); g_return_val_if_fail(GTK_IS_GS(gs), FALSE); - LOG ("Load the document") + LOG ("Load the document"); /* clean up previous document */ ps_document_cleanup(gs); @@ -1312,7 +1265,7 @@ document_load(PSDocument * gs, const gchar * fname) /* default values: no dsc information available */ gs->structured_doc = FALSE; gs->send_filename_to_gs = TRUE; - gs->current_page = -2; + gs->current_page = 0; gs->loaded = FALSE; if(*fname == '/') { /* an absolute path */ @@ -1343,8 +1296,6 @@ document_load(PSDocument * gs, const gchar * fname) } else { filename = check_filecompressed(gs); - if(filename) - filename = check_pdf(gs); } if(!filename || (gs->gs_psfile = fopen(filename, "r")) == NULL) { @@ -1374,22 +1325,7 @@ document_load(PSDocument * gs, const gchar * fname) } /* We have to set up the orientation of the document */ - - - /* orientation can only be portrait, and landscape or none. - This is the document default. A document can have - pages in landscape and some in portrait */ - if(gs->override_orientation) { - /* If the orientation should be override... - then gs->orientation has already the correct - value (it was set when the widget was created */ - /* So do nothing */ - - } - else { - /* Otherwise, set the proper orientation for the doc */ - gs->real_orientation = gs->doc->orientation; - } + gs->real_orientation = gs->doc->orientation; } ps_document_set_page_size(gs, -1, gs->current_page); gs->loaded = TRUE; @@ -1405,7 +1341,7 @@ ps_document_next_page(PSDocument * gs) { XEvent event; - LOG ("Make ghostscript render next page") + LOG ("Make ghostscript render next page"); g_return_val_if_fail(gs != NULL, FALSE); g_return_val_if_fail(GTK_IS_GS(gs), FALSE); @@ -1440,7 +1376,7 @@ ps_document_goto_page(PSDocument * gs, gint page) g_return_val_if_fail(gs != NULL, FALSE); g_return_val_if_fail(GTK_IS_GS(gs), FALSE); - LOG ("Go to page %d", page) + LOG ("Go to page %d", page); if(!gs->gs_filename) { return FALSE; @@ -1452,7 +1388,7 @@ ps_document_goto_page(PSDocument * gs, gint page) if(gs->structured_doc && gs->doc) { - LOG ("It's a structured document, let's send one page to gs") + LOG ("It's a structured document, let's send one page to gs"); if(page >= gs->doc->numpages) page = gs->doc->numpages - 1; @@ -1463,7 +1399,6 @@ ps_document_goto_page(PSDocument * gs, gint page) gs->current_page = page; if(gs->doc->pages[page].orientation != NONE && - !gs->override_orientation && gs->doc->pages[page].orientation != gs->real_orientation) { gs->real_orientation = gs->doc->pages[page].orientation; gs->changed = TRUE; @@ -1495,7 +1430,7 @@ ps_document_goto_page(PSDocument * gs, gint page) case, ggv restarts GS again and the first page is displayed. */ - LOG ("It's an unstructured document, gs will just read the file") + LOG ("It's an unstructured document, gs will just read the file"); if(page == gs->current_page && !gs->changed) return TRUE; @@ -1529,7 +1464,7 @@ ps_document_set_page_size(PSDocument * gs, gint new_pagesize, gint pageid) gint new_ury = 0; GtkGSPaperSize *papersizes = gtk_gs_defaults_get_paper_sizes(); - LOG ("Set the page size") + LOG ("Set the page size"); g_return_val_if_fail(gs != NULL, FALSE); g_return_val_if_fail(GTK_IS_GS(gs), FALSE); @@ -1537,7 +1472,7 @@ ps_document_set_page_size(PSDocument * gs, gint new_pagesize, gint pageid) if(new_pagesize == -1) { if(gs->default_size > 0) new_pagesize = gs->default_size; - if(!gs->override_size && gs->doc) { + if(gs->doc) { /* If we have a document: We use -- the page size (if specified) or the doc. size (if specified) @@ -1568,7 +1503,7 @@ ps_document_set_page_size(PSDocument * gs, gint new_pagesize, gint pageid) } /* Compute bounding box */ - if(gs->doc && ((gs->doc->epsf && !gs->override_size) || new_pagesize == -1)) { /* epsf or bbox */ + if(gs->doc && (gs->doc->epsf || new_pagesize == -1)) { /* epsf or bbox */ if((pageid >= 0) && (gs->doc->pages) && (gs->doc->pages[pageid].boundingbox[URX] > @@ -1594,7 +1529,7 @@ ps_document_set_page_size(PSDocument * gs, gint new_pagesize, gint pageid) if(new_pagesize < 0) new_pagesize = gs->default_size; new_llx = new_lly = 0; - if(gs->doc && !gs->override_size && gs->doc->size && + if(gs->doc && gs->doc->size && (new_pagesize < gs->doc->numsizes)) { new_urx = gs->doc->size[new_pagesize].width; new_ury = gs->doc->size[new_pagesize].height; @@ -1629,54 +1564,19 @@ ps_document_set_page_size(PSDocument * gs, gint new_pagesize, gint pageid) return FALSE; } -static gfloat -ps_document_zoom_to_fit(PSDocument * gs, gboolean fit_width) -{ - gint new_y; - gfloat new_zoom; - guint avail_w, avail_h; - - g_return_val_if_fail(gs != NULL, 0.0); - g_return_val_if_fail(GTK_IS_GS(gs), 0.0); - - avail_w = (gs->avail_w > 0) ? gs->avail_w : gs->width; - avail_h = (gs->avail_h > 0) ? gs->avail_h : gs->height; - - new_zoom = ((gfloat) avail_w) / ((gfloat) gs->width) * gs->zoom_factor; - if(!fit_width) { - new_y = new_zoom * ((gfloat) gs->height) / gs->zoom_factor; - if(new_y > avail_h) - new_zoom = ((gfloat) avail_h) / ((gfloat) gs->height) * gs->zoom_factor; - } - - return new_zoom; -} - static void -ps_document_set_zoom(PSDocument * gs, gfloat zoom) +ps_document_set_zoom (PSDocument * gs, gfloat zoom) { - g_return_if_fail(gs != NULL); - g_return_if_fail(GTK_IS_GS(gs)); + g_return_if_fail (gs != NULL); - switch (gs->zoom_mode) { - case GTK_GS_ZOOM_FIT_WIDTH: - zoom = ps_document_zoom_to_fit(gs, TRUE); - break; - case GTK_GS_ZOOM_FIT_PAGE: - zoom = ps_document_zoom_to_fit(gs, FALSE); - break; - case GTK_GS_ZOOM_ABSOLUTE: - default: - break; - } + gs->zoom_factor = zoom; - if(fabs(gs->zoom_factor - zoom) > 0.001) { - gs->zoom_factor = zoom; - set_up_page(gs); - gs->changed = TRUE; - } - - ps_document_goto_page(gs, gs->current_page); + if (gs->pstarget != NULL) { + set_up_page(gs); + gs->changed = TRUE; + gs->scaling = TRUE; + ps_document_goto_page (gs, gs->current_page); + } } static gboolean @@ -1692,6 +1592,12 @@ ps_document_load (EvDocument *document, return FALSE; result = document_load (PS_DOCUMENT (document), filename); + if (!result) { + g_set_error (error, G_FILE_ERROR, + G_FILE_ERROR_FAILED, + "Failed to load document '%s'\n", + uri); + } g_free (filename); @@ -1725,7 +1631,7 @@ static void ps_document_set_page (EvDocument *document, int page) { - ps_document_goto_page (PS_DOCUMENT (document), page); + ps_document_goto_page (PS_DOCUMENT (document), page - 1); } static int @@ -1735,49 +1641,7 @@ ps_document_get_page (EvDocument *document) g_return_val_if_fail (ps != NULL, -1); - return ps->current_page; -} - -static gboolean -ps_document_widget_event (GtkWidget *widget, GdkEvent *event, gpointer data) -{ - PSDocument *gs = (PSDocument *) data; - - if(event->type != GDK_CLIENT_EVENT) - return FALSE; - - gs->message_window = event->client.data.l[0]; - - if (event->client.message_type == gs_class->page_atom) { - LOG ("GS rendered the document") - gs->busy = FALSE; - ev_document_changed (EV_DOCUMENT (gs)); - } - - return TRUE; -} - -static void -ps_document_set_target (EvDocument *document, - GdkDrawable *target) -{ - PSDocument *gs = PS_DOCUMENT (document); - GtkWidget *widget; - gpointer data; - - gs->pstarget = target; - - if (gs->pstarget) { - gdk_window_get_user_data (gs->pstarget, &data); - g_return_if_fail (GTK_IS_WIDGET (data)); - - widget = GTK_WIDGET (data); - g_signal_connect (widget, "event", - G_CALLBACK (ps_document_widget_event), - document); - } - - ps_document_goto_page (gs, gs->current_page); + return ps->current_page + 1; } static void @@ -1854,7 +1718,7 @@ ps_document_render (EvDocument *document, LOG ("Copy the internal pixmap: %d %d %d %d %d %d", draw.x - page.x, draw.y - page.y, - draw.x, draw.y, draw.width, draw.height) + draw.x, draw.y, draw.width, draw.height); g_object_unref (gc); }