2 * image/x-pdf BonoboObject.
5 * Michael Meeks <michael@imaginator.com>
14 #define GString G_String
16 #include <libgnorba/gnorba.h>
17 #include <bonobo/gnome-bonobo.h>
22 #include "parseargs.h"
34 #include "GOutputDev.h"
35 #include "PSOutputDev.h"
36 #include "TextOutputDev.h"
40 #include "BonoboStream.h"
45 GBool printCommands = gFalse;
54 GnomeEmbeddable *embeddable;
57 GNOME_Stream stream; /* To free it later */
70 GtkWidget *drawing_area;
81 static void realize_drawing_areas (bed_t *bed);
82 static void setup_pixmap (bed_t *doc, view_data_t *view, GdkWindow *window);
86 redraw_view (view_data_t *view_data, GdkRectangle *rect)
89 bed_t *bed = view_data->bed;
91 g_return_if_fail (view_data->pixmap != NULL);
94 * Do not draw outside the region that we know how to display
96 if (rect->x > view_data->w)
99 if (rect->y > view_data->h)
103 * Clip the draw region
105 if (rect->x + rect->width > view_data->w)
106 rect->width = view_data->w - rect->x;
108 if (rect->y + rect->height > view_data->h)
109 rect->height = view_data->h - rect->y;
112 * Draw the exposed region.
114 gdk_draw_pixmap (view_data->drawing_area->window,
115 view_data->drawing_area->style->white_gc,
124 render_page (view_data_t *view_data)
126 setup_pixmap (view_data->bed, view_data,
128 view_data->bed->pdf->displayPage(view_data->out,
129 view_data->page, view_data->zoom,
134 redraw_view_all (view_data_t *view_data)
137 g_return_if_fail (view_data != NULL);
140 printf ("Redraw view of page %d\n", view_data->page);
142 render_page (view_data);
145 rect.width = view_data->w;
146 rect.height = view_data->h;
147 redraw_view (view_data, &rect);
148 gtk_widget_queue_draw (GTK_WIDGET (view_data->drawing_area));
152 configure_size (view_data_t *view_data)
154 gtk_widget_set_usize (
155 view_data->drawing_area,
161 redraw_all (bed_t *bed)
165 for (l = bed->views; l; l = l->next) {
167 view_data_t *view_data = (view_data_t *)l->data;
168 configure_size (view_data);
169 redraw_view_all (view_data);
174 save_image (GnomePersistStream *ps, GNOME_Stream stream, void *data)
176 g_warning ("Unimplemented");
184 setup_size (bed_t *doc, view_data_t *view)
189 if (!doc || !view || !doc->pdf) {
194 w = (int)((doc->pdf->getPageWidth (view->page) * view->zoom) / 72.0);
195 h = (int)((doc->pdf->getPageHeight (view->page) * view->zoom) / 72.0);
196 if (view->w == w && view->h == h)
207 * Loads a PDF from a GNOME_Stream
210 load_image_from_stream (GnomePersistStream *ps, GNOME_Stream stream, void *data)
212 bed_t *bed = (bed_t *)data;
214 GNOME_Stream_iobuf *buffer;
222 g_warning ("Won't overwrite pre-existing stream: you wierdo");
226 /* We need this for later */
227 CORBA_Object_duplicate (stream, &ev);
228 g_return_val_if_fail (ev._major == CORBA_NO_EXCEPTION, 0);
231 printf ("Loading PDF from persiststream\n");
233 bed->stream = stream;
234 BonoboStream *bs = new BonoboStream (stream);
235 GString *st = new GString ("Bonobo.pdf");
236 bed->pdf = new PDFDoc (bs, st);
239 printf ("Done load\n");
241 if (!(bed->pdf->isOk())) {
242 g_warning ("Duff pdf data\n");
246 if (!bed->pdf->getCatalog()) {
247 g_warning ("Duff pdf catalog\n");
252 realize_drawing_areas (bed);
260 destroy_view (GnomeView *view, view_data_t *view_data)
262 view_data->bed->views = g_list_remove (view_data->bed->views, view_data);
263 gtk_object_unref (GTK_OBJECT (view_data->drawing_area));
269 destroy_embed (GnomeView *view, bed_t *bed)
272 destroy_view (NULL, (view_data_t *)bed->views->data);
276 gtk_object_unref (GTK_OBJECT (bed->stream));
282 setup_pixmap (bed_t *doc, view_data_t *view_data, GdkWindow *window)
284 GdkGCValues gcValues;
288 GdkPixmap *pixmap = NULL;
290 g_return_if_fail (doc != NULL);
291 g_return_if_fail (doc->pdf != NULL);
292 g_return_if_fail (view_data != NULL);
296 if (setup_size (doc, view_data) &&
299 printf ("No need to re-init output device\n");
307 pixmap = gdk_pixmap_new (window, w, h, -1);
309 gdk_color_white (gtk_widget_get_default_colormap(), &view_data->paper);
310 view_data->out = new GOutputDev (pixmap, view_data->paper, window);
312 gdk_color_white (gtk_widget_get_default_colormap (), &gcValues.foreground);
313 gdk_color_black (gtk_widget_get_default_colormap (), &gcValues.background);
314 gcValues.line_width = 1;
315 gcValues.line_style = GDK_LINE_SOLID;
316 strokeGC = gdk_gc_new_with_values (
318 (enum GdkGCValuesMask)(GDK_GC_FOREGROUND | GDK_GC_BACKGROUND | GDK_GC_LINE_WIDTH | GDK_GC_LINE_STYLE));
320 gdk_draw_rectangle (pixmap, strokeGC,
324 view_data->pixmap = pixmap;
328 view_is_good (view_data_t *view_data)
332 !view_data->bed->pdf)
339 first_page (view_data_t *view_data)
341 g_return_val_if_fail (view_is_good (view_data), FALSE);
342 if (view_data->page != 1) {
350 last_page (view_data_t *view_data)
352 g_return_val_if_fail (view_is_good (view_data), FALSE);
353 if (view_data->page < view_data->bed->pdf->getNumPages()) {
354 view_data->page = view_data->bed->pdf->getNumPages();
361 next_page (view_data_t *view_data)
363 g_return_val_if_fail (view_is_good (view_data), FALSE);
364 if (view_data->page < view_data->bed->pdf->getNumPages()) {
372 prev_page (view_data_t *view_data)
374 g_return_val_if_fail (view_is_good (view_data), FALSE);
375 if (view_data->page > 1) {
383 page_first_cb (GnomeUIHandler *uih, void *data, char *path)
385 first_page ((view_data_t *)data);
386 redraw_view_all ((view_data_t *)data);
390 page_next_cb (GnomeUIHandler *uih, void *data, char *path)
392 next_page ((view_data_t *)data);
393 redraw_view_all ((view_data_t *)data);
397 page_prev_cb (GnomeUIHandler *uih, void *data, char *path)
399 prev_page ((view_data_t *)data);
400 redraw_view_all ((view_data_t *)data);
404 page_last_cb (GnomeUIHandler *uih, void *data, char *path)
406 last_page ((view_data_t *)data);
407 redraw_view_all ((view_data_t *)data);
412 view_create_menus (view_data_t *view_data)
414 GNOME_UIHandler remote_uih;
415 GnomeView *view = view_data->view;
418 uih = gnome_view_get_ui_handler (view);
419 remote_uih = gnome_view_get_remote_ui_handler (view);
421 if (remote_uih == CORBA_OBJECT_NIL) {
422 g_warning ("server has no UI hander");
426 gnome_ui_handler_set_container (uih, remote_uih);
428 gnome_ui_handler_menu_new_subtree (uih, "/Page",
430 N_("Set the currently displayed page"),
432 GNOME_UI_HANDLER_PIXMAP_NONE, NULL,
433 0, (GdkModifierType)0);
435 gnome_ui_handler_menu_new_item (uih, "/Page/First",
436 N_("First"), N_("View the first page"), -1,
437 GNOME_UI_HANDLER_PIXMAP_NONE, NULL, 0,
438 (GdkModifierType)0, page_first_cb, (gpointer)view_data);
440 gnome_ui_handler_menu_new_item (uih, "/Page/Prev",
441 N_("Previous"), N_("View the previous page"), -1,
442 GNOME_UI_HANDLER_PIXMAP_NONE, NULL, 0,
443 (GdkModifierType)0, page_prev_cb, (gpointer)view_data);
445 gnome_ui_handler_menu_new_item (uih, "/Page/Next",
446 N_("Next"), N_("View the next page"), -1,
447 GNOME_UI_HANDLER_PIXMAP_NONE, NULL, 0,
448 (GdkModifierType)0, page_next_cb, (gpointer)view_data);
450 gnome_ui_handler_menu_new_item (uih, "/Page/Last",
451 N_("Last"), N_("View the last page"), -1,
452 GNOME_UI_HANDLER_PIXMAP_NONE, NULL, 0,
453 (GdkModifierType)0, page_last_cb, (gpointer)view_data);
455 gnome_ui_handler_toolbar_new_item (uih, "/First", GNOME_UI_HANDLER_MENU_ITEM,
456 N_("First"), N_("View the first page"), -1,
457 GNOME_UI_HANDLER_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_FIRST,
458 0, (GdkModifierType)0, page_first_cb, (gpointer)view_data);
459 gnome_ui_handler_toolbar_new_item (uih, "/Prev", GNOME_UI_HANDLER_MENU_ITEM,
460 N_("Previous"), N_("View the previous page"), -1,
461 GNOME_UI_HANDLER_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_FIRST,
462 0, (GdkModifierType)0, page_prev_cb, (gpointer)view_data);
463 gnome_ui_handler_toolbar_new_item (uih, "/Next", GNOME_UI_HANDLER_MENU_ITEM,
464 N_("Next"), N_("View the next page"), -1,
465 GNOME_UI_HANDLER_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_FIRST,
466 0, (GdkModifierType)0, page_next_cb, (gpointer)view_data);
467 gnome_ui_handler_toolbar_new_item (uih, "/Last", GNOME_UI_HANDLER_MENU_ITEM,
468 N_("Last"), N_("View the last page"), -1,
469 GNOME_UI_HANDLER_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_FIRST,
470 0, (GdkModifierType)0, page_last_cb, (gpointer)view_data);
476 * When this view is deactivated, we must remove our menu items.
479 view_remove_menus (view_data_t *view_data)
481 GnomeView *view = view_data->view;
484 uih = gnome_view_get_ui_handler (view);
486 gnome_ui_handler_unset_container (uih);
492 drawing_area_realize (GtkWidget *drawing_area, view_data_t *view_data)
494 g_return_if_fail (view_data != NULL);
495 g_return_if_fail (drawing_area != NULL);
497 view_data->win = gtk_widget_get_parent_window (drawing_area);
501 drawing_area_exposed (GtkWidget *widget, GdkEventExpose *event, view_data_t *view_data)
504 !view_data->bed->pdf)
507 redraw_view (view_data, &event->area);
513 view_activate (GnomeView *view, gboolean activate, gpointer data)
515 view_data_t *view_data = (view_data_t *) data;
516 g_return_if_fail (view != NULL);
517 g_return_if_fail (view_data != NULL);
519 gnome_view_activate_notify (view, activate);
522 printf ("View change activation to %d\n", activate);
525 * If we were just activated, we merge in our menu entries.
526 * If we were just deactivated, we remove them.
529 view_create_menus (view_data);
531 view_remove_menus (view_data);
535 view_size_query (GnomeView *view, int *desired_width, int *desired_height,
538 view_data_t *view_data = (view_data_t *) data;
540 g_return_if_fail (view_data != NULL);
542 *desired_width = view_data->w;
543 *desired_height = view_data->h;
547 view_zoom_query (GnomeView *view, gdouble new_zoom, gpointer data)
549 view_data_t *view_data = (view_data_t *) data;
551 g_return_if_fail (view_data != NULL);
553 view_data->zoom = new_zoom;
555 redraw_view_all (view_data);
559 realize_drawing_areas (bed_t *bed)
563 for (l = bed->views; l; l = l->next) {
564 view_data_t *view_data = (view_data_t *)l->data;
565 g_return_if_fail (view_data->win);
566 render_page (view_data);
567 configure_size (view_data);
572 view_switch_page (GnomeView *view, const char *verb_name, void *user_data)
574 view_data_t *view_data = (view_data_t *) user_data;
576 gboolean changed = FALSE;
578 if (!g_strcasecmp (verb_name, "firstpage")) {
579 changed = first_page (view_data);
580 } else if (!g_strcasecmp (verb_name, "prevpage")) {
581 changed = prev_page (view_data);
582 } else if (!g_strcasecmp (verb_name, "nextpage")) {
583 changed = next_page (view_data);
584 } else if (!g_strcasecmp (verb_name, "lastpage")) {
585 changed = last_page (view_data);
587 g_warning ("Unknown verb");
590 render_page (view_data);
591 redraw_view (view_data, &rect);
592 gtk_widget_queue_draw (GTK_WIDGET (view_data->drawing_area));
598 view_factory (GnomeEmbeddable *embeddable,
599 const GNOME_ViewFrame view_frame,
604 bed_t *bed = (bed_t *)data;
605 view_data_t *view_data = g_new (view_data_t, 1);
608 printf ("Created new bonobo object view %p\n", view_data);
611 view_data->scale = 1.0;
612 view_data->bed = bed;
613 view_data->drawing_area = gtk_drawing_area_new ();
614 view_data->pixmap = NULL;
615 view_data->win = NULL;
616 view_data->out = NULL;
619 view_data->zoom = 43.0; /* 86.0; Must be small for demos :-) */
623 GTK_OBJECT (view_data->drawing_area),
625 GTK_SIGNAL_FUNC (drawing_area_realize), view_data);
628 GTK_OBJECT (view_data->drawing_area),
630 GTK_SIGNAL_FUNC (drawing_area_exposed), view_data);
632 gtk_widget_show (view_data->drawing_area);
634 setup_size (bed, view_data);
636 view = gnome_view_new (view_data->drawing_area);
637 view_data->view = view;
640 GTK_OBJECT (view), "destroy",
641 GTK_SIGNAL_FUNC (destroy_view), view_data);
644 uih = gnome_ui_handler_new ();
645 gnome_view_set_ui_handler (view, uih);
647 gtk_signal_connect (GTK_OBJECT (view), "view_activate",
648 GTK_SIGNAL_FUNC (view_activate), view_data);
650 gtk_signal_connect (GTK_OBJECT (view), "size_query",
651 GTK_SIGNAL_FUNC (view_size_query), view_data);
653 gtk_signal_connect (GTK_OBJECT (view), "set_zoom_factor",
654 GTK_SIGNAL_FUNC (view_zoom_query), view_data);
656 bed->views = g_list_prepend (bed->views, view_data);
659 gnome_view_register_verb (view, "FirstPage",
660 view_switch_page, view_data);
661 gnome_view_register_verb (view, "PrevPage",
662 view_switch_page, view_data);
663 gnome_view_register_verb (view, "NextPage",
664 view_switch_page, view_data);
665 gnome_view_register_verb (view, "LastPage",
666 view_switch_page, view_data);
672 embeddable_factory (GnomeEmbeddableFactory *This, void *data)
674 GnomeEmbeddable *embeddable;
675 GnomePersistStream *stream;
676 bed_t *bed = (bed_t *)data;
678 bed = g_new0 (bed_t, 1);
683 printf ("Created new bonobo object %p\n", bed);
686 * Creates the BonoboObject server
688 embeddable = gnome_embeddable_new (view_factory, bed);
689 if (embeddable == NULL){
697 * Interface GNOME::PersistStream
699 stream = gnome_persist_stream_new ("bonobo-object:image-x-pdf",
700 load_image_from_stream,
703 if (stream == NULL) {
704 gtk_object_unref (GTK_OBJECT (embeddable));
709 bed->embeddable = embeddable;
712 * Bind the interfaces
714 gnome_object_add_interface (GNOME_OBJECT (embeddable),
715 GNOME_OBJECT (stream));
717 GTK_OBJECT (embeddable), "destroy",
718 GTK_SIGNAL_FUNC (destroy_embed), bed);
720 /* Setup some verbs */
721 gnome_embeddable_add_verb (embeddable,
724 _("goto the first page"));
725 gnome_embeddable_add_verb (embeddable,
728 _("goto the previous page"));
729 gnome_embeddable_add_verb (embeddable,
732 _("goto the next page"));
733 gnome_embeddable_add_verb (embeddable,
736 _("goto the last page"));
738 return (GnomeObject *) embeddable;
742 init_bonobo_image_x_pdf_factory (void)
744 GnomeEmbeddableFactory *factory;
746 factory = gnome_embeddable_factory_new (
747 "bonobo-object-factory:image-x-pdf",
748 embeddable_factory, NULL);
757 init_server_factory (int argc, char **argv)
759 gnome_CORBA_init_with_popt_table (
760 "bonobo-image-x-pdf", "1.0",
761 &argc, argv, NULL, 0, NULL, GNORBA_INIT_SERVER_FUNC, &ev);
763 if (bonobo_init (CORBA_OBJECT_NIL, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE)
764 g_error (_("I could not initialize Bonobo"));
768 main (int argc, char *argv [])
770 CORBA_exception_init (&ev);
772 init_server_factory (argc, argv);
773 if (!init_bonobo_image_x_pdf_factory ()){
774 fprintf (stderr, "Could not initialize the Bonobo PDF factory\n"
775 "probably a server is already running?");
781 initParams (xpdfConfigFile); /* Init font path */
783 gtk_widget_set_default_colormap (gdk_rgb_get_cmap ());
784 gtk_widget_set_default_visual (gdk_rgb_get_visual ());
788 CORBA_exception_free (&ev);