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"
44 GBool printCommands = gFalse;
50 * Number of servers running on the system
51 * when the count reaches zero, we unregister from the
52 * Name Server and we shut down.
54 static int embeddable_servers = 0;
57 * Our embeddable factory
59 static GnomeEmbeddableFactory *factory;
66 GnomeEmbeddable *embeddable;
69 GNOME_Stream stream; /* To free it later */
82 GtkWidget *drawing_area;
93 static void realize_drawing_areas (bed_t *bed);
94 static void setup_pixmap (bed_t *doc, view_data_t *view, GdkWindow *window);
98 redraw_view (view_data_t *view_data, GdkRectangle *rect)
101 bed_t *bed = view_data->bed;
103 g_return_if_fail (view_data->pixmap != NULL);
106 * Do not draw outside the region that we know how to display
108 if (rect->x > view_data->w)
111 if (rect->y > view_data->h)
115 * Clip the draw region
117 if (rect->x + rect->width > view_data->w)
118 rect->width = view_data->w - rect->x;
120 if (rect->y + rect->height > view_data->h)
121 rect->height = view_data->h - rect->y;
124 * Draw the exposed region.
126 gdk_draw_pixmap (view_data->drawing_area->window,
127 view_data->drawing_area->style->white_gc,
136 configure_size (view_data_t *view_data)
138 gtk_widget_set_usize (
139 view_data->drawing_area,
145 render_page (view_data_t *view_data)
147 setup_pixmap (view_data->bed, view_data,
149 view_data->bed->pdf->displayPage(view_data->out,
150 view_data->page, view_data->zoom,
155 redraw_view_all (view_data_t *view_data)
158 g_return_if_fail (view_data != NULL);
161 printf ("Redraw view of page %d\n", view_data->page);
163 render_page (view_data);
166 rect.width = view_data->w;
167 rect.height = view_data->h;
168 redraw_view (view_data, &rect);
169 gtk_widget_queue_draw (GTK_WIDGET (view_data->drawing_area));
173 redraw_all (bed_t *bed)
177 for (l = bed->views; l; l = l->next) {
179 view_data_t *view_data = (view_data_t *)l->data;
180 redraw_view_all (view_data);
185 save_image (GnomePersistStream *ps, GNOME_Stream stream, void *data)
187 g_warning ("Unimplemented");
195 setup_size (bed_t *doc, view_data_t *view)
200 if (!doc || !view || !doc->pdf) {
205 w = (int)((doc->pdf->getPageWidth (view->page) * view->zoom) / 72.0);
206 h = (int)((doc->pdf->getPageHeight (view->page) * view->zoom) / 72.0);
207 if (view->w == w && view->h == h)
218 * Loads a PDF from a GNOME_Stream
221 load_image_from_stream (GnomePersistStream *ps, GNOME_Stream stream, void *data)
223 bed_t *bed = (bed_t *)data;
225 GNOME_Stream_iobuf *buffer;
234 g_warning ("Won't overwrite pre-existing stream: you wierdo");
238 /* We need this for later */
239 CORBA_Object_duplicate (stream, &ev);
240 g_return_val_if_fail (ev._major == CORBA_NO_EXCEPTION, 0);
243 printf ("Loading PDF from persiststream\n");
245 bed->stream = stream;
247 BonoboStream *bs = new BonoboStream (stream, 0, -1, &obj);
248 bed->pdf = new PDFDoc (bs);
251 printf ("Done load\n");
253 if (!(bed->pdf->isOk())) {
254 g_warning ("Duff pdf data\n");
258 if (!bed->pdf->getCatalog()) {
259 g_warning ("Duff pdf catalog\n");
264 realize_drawing_areas (bed);
272 destroy_view (GnomeView *view, view_data_t *view_data)
274 view_data->bed->views = g_list_remove (view_data->bed->views, view_data);
275 gtk_object_unref (GTK_OBJECT (view_data->drawing_area));
281 destroy_embed (GnomeView *view, bed_t *bed)
284 destroy_view (NULL, (view_data_t *)bed->views->data);
288 gtk_object_unref (GTK_OBJECT (bed->stream));
292 embeddable_servers--;
294 if (embeddable_servers == 0){
295 gnome_object_unref (GNOME_OBJECT (factory));
301 setup_pixmap (bed_t *doc, view_data_t *view_data, GdkWindow *window)
303 GdkGCValues gcValues;
307 GdkPixmap *pixmap = NULL;
309 g_return_if_fail (doc != NULL);
310 g_return_if_fail (doc->pdf != NULL);
311 g_return_if_fail (view_data != NULL);
315 if (setup_size (doc, view_data) &&
318 printf ("No need to re-init output device\n");
326 pixmap = gdk_pixmap_new (window, w, h, -1);
328 gdk_color_white (gtk_widget_get_default_colormap(), &view_data->paper);
329 view_data->out = new GOutputDev (pixmap, view_data->paper, window);
331 gdk_color_white (gtk_widget_get_default_colormap (), &gcValues.foreground);
332 gdk_color_black (gtk_widget_get_default_colormap (), &gcValues.background);
333 gcValues.line_width = 1;
334 gcValues.line_style = GDK_LINE_SOLID;
335 strokeGC = gdk_gc_new_with_values (
337 (enum GdkGCValuesMask)(GDK_GC_FOREGROUND | GDK_GC_BACKGROUND | GDK_GC_LINE_WIDTH | GDK_GC_LINE_STYLE));
339 gdk_draw_rectangle (pixmap, strokeGC,
343 view_data->pixmap = pixmap;
344 configure_size (view_data);
348 view_is_good (view_data_t *view_data)
352 !view_data->bed->pdf)
359 first_page (view_data_t *view_data)
361 g_return_val_if_fail (view_is_good (view_data), FALSE);
362 if (view_data->page != 1) {
370 last_page (view_data_t *view_data)
372 g_return_val_if_fail (view_is_good (view_data), FALSE);
373 if (view_data->page < view_data->bed->pdf->getNumPages()) {
374 view_data->page = view_data->bed->pdf->getNumPages();
381 next_page (view_data_t *view_data)
383 g_return_val_if_fail (view_is_good (view_data), FALSE);
384 if (view_data->page < view_data->bed->pdf->getNumPages()) {
392 prev_page (view_data_t *view_data)
394 g_return_val_if_fail (view_is_good (view_data), FALSE);
395 if (view_data->page > 1) {
403 page_first_cb (GnomeUIHandler *uih, void *data, char *path)
405 first_page ((view_data_t *)data);
406 redraw_view_all ((view_data_t *)data);
410 page_next_cb (GnomeUIHandler *uih, void *data, char *path)
412 next_page ((view_data_t *)data);
413 redraw_view_all ((view_data_t *)data);
417 page_prev_cb (GnomeUIHandler *uih, void *data, char *path)
419 prev_page ((view_data_t *)data);
420 redraw_view_all ((view_data_t *)data);
424 page_last_cb (GnomeUIHandler *uih, void *data, char *path)
426 last_page ((view_data_t *)data);
427 redraw_view_all ((view_data_t *)data);
432 view_create_menus (view_data_t *view_data)
434 GNOME_UIHandler remote_uih;
435 GnomeView *view = view_data->view;
438 uih = gnome_view_get_ui_handler (view);
439 remote_uih = gnome_view_get_remote_ui_handler (view);
441 if (remote_uih == CORBA_OBJECT_NIL) {
442 g_warning ("server has no UI hander");
446 gnome_ui_handler_set_container (uih, remote_uih);
448 gnome_ui_handler_menu_new_subtree (uih, "/Page",
450 N_("Set the currently displayed page"),
452 GNOME_UI_HANDLER_PIXMAP_NONE, NULL,
453 0, (GdkModifierType)0);
455 gnome_ui_handler_menu_new_item (uih, "/Page/First",
456 N_("First"), N_("View the first page"), -1,
457 GNOME_UI_HANDLER_PIXMAP_NONE, NULL, 0,
458 (GdkModifierType)0, page_first_cb, (gpointer)view_data);
460 gnome_ui_handler_menu_new_item (uih, "/Page/Prev",
461 N_("Previous"), N_("View the previous page"), -1,
462 GNOME_UI_HANDLER_PIXMAP_NONE, NULL, 0,
463 (GdkModifierType)0, page_prev_cb, (gpointer)view_data);
465 gnome_ui_handler_menu_new_item (uih, "/Page/Next",
466 N_("Next"), N_("View the next page"), -1,
467 GNOME_UI_HANDLER_PIXMAP_NONE, NULL, 0,
468 (GdkModifierType)0, page_next_cb, (gpointer)view_data);
470 gnome_ui_handler_menu_new_item (uih, "/Page/Last",
471 N_("Last"), N_("View the last page"), -1,
472 GNOME_UI_HANDLER_PIXMAP_NONE, NULL, 0,
473 (GdkModifierType)0, page_last_cb, (gpointer)view_data);
475 gnome_ui_handler_toolbar_new_item (uih, "/First",
476 N_("First"), N_("View the first page"), -1,
477 GNOME_UI_HANDLER_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_FIRST,
478 0, (GdkModifierType)0, page_first_cb, (gpointer)view_data);
479 gnome_ui_handler_toolbar_new_item (uih, "/Prev",
480 N_("Previous"), N_("View the previous page"), -1,
481 GNOME_UI_HANDLER_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_BACK,
482 0, (GdkModifierType)0, page_prev_cb, (gpointer)view_data);
483 gnome_ui_handler_toolbar_new_item (uih, "/Next",
484 N_("Next"), N_("View the next page"), -1,
485 GNOME_UI_HANDLER_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_FORWARD,
486 0, (GdkModifierType)0, page_next_cb, (gpointer)view_data);
487 gnome_ui_handler_toolbar_new_item (uih, "/Last",
488 N_("Last"), N_("View the last page"), -1,
489 GNOME_UI_HANDLER_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_LAST,
490 0, (GdkModifierType)0, page_last_cb, (gpointer)view_data);
494 * When this view is deactivated, we must remove our menu items.
497 view_remove_menus (view_data_t *view_data)
499 GnomeView *view = view_data->view;
502 uih = gnome_view_get_ui_handler (view);
504 gnome_ui_handler_unset_container (uih);
510 drawing_area_realize (GtkWidget *drawing_area, view_data_t *view_data)
512 g_return_if_fail (view_data != NULL);
513 g_return_if_fail (drawing_area != NULL);
515 view_data->win = gtk_widget_get_parent_window (drawing_area);
519 drawing_area_exposed (GtkWidget *widget, GdkEventExpose *event, view_data_t *view_data)
522 !view_data->bed->pdf)
525 redraw_view (view_data, &event->area);
531 view_activate (GnomeView *view, gboolean activate, gpointer data)
533 view_data_t *view_data = (view_data_t *) data;
534 g_return_if_fail (view != NULL);
535 g_return_if_fail (view_data != NULL);
537 gnome_view_activate_notify (view, activate);
540 printf ("View change activation to %d\n", activate);
543 * If we were just activated, we merge in our menu entries.
544 * If we were just deactivated, we remove them.
547 view_create_menus (view_data);
549 view_remove_menus (view_data);
553 view_size_query (GnomeView *view, int *desired_width, int *desired_height,
556 view_data_t *view_data = (view_data_t *) data;
558 g_return_if_fail (view_data != NULL);
560 *desired_width = view_data->w;
561 *desired_height = view_data->h;
565 view_zoom_query (GnomeView *view, gdouble new_zoom, gpointer data)
567 view_data_t *view_data = (view_data_t *) data;
569 g_return_if_fail (view_data != NULL);
571 /* The rational behind this is that the _entire_ page is allocated
572 regardless of viewport size, so you _really_ don't want it too big ! */
573 g_return_if_fail (new_zoom > 10.0);
574 g_return_if_fail (new_zoom < 180.0);
576 view_data->zoom = new_zoom;
577 redraw_view_all (view_data);
581 realize_drawing_areas (bed_t *bed)
585 for (l = bed->views; l; l = l->next) {
586 view_data_t *view_data = (view_data_t *)l->data;
587 g_return_if_fail (view_data->win);
588 render_page (view_data);
589 configure_size (view_data);
594 view_switch_page (GnomeView *view, const char *verb_name, void *user_data)
596 view_data_t *view_data = (view_data_t *) user_data;
598 gboolean changed = FALSE;
600 if (!g_strcasecmp (verb_name, "firstpage")) {
601 changed = first_page (view_data);
602 } else if (!g_strcasecmp (verb_name, "prevpage")) {
603 changed = prev_page (view_data);
604 } else if (!g_strcasecmp (verb_name, "nextpage")) {
605 changed = next_page (view_data);
606 } else if (!g_strcasecmp (verb_name, "lastpage")) {
607 changed = last_page (view_data);
609 g_warning ("Unknown verb");
612 render_page (view_data);
613 redraw_view (view_data, &rect);
614 gtk_widget_queue_draw (GTK_WIDGET (view_data->drawing_area));
620 view_factory (GnomeEmbeddable *embeddable,
621 const GNOME_ViewFrame view_frame,
626 bed_t *bed = (bed_t *)data;
627 view_data_t *view_data = g_new (view_data_t, 1);
630 printf ("Created new bonobo object view %p\n", view_data);
633 view_data->scale = 1.0;
634 view_data->bed = bed;
635 view_data->drawing_area = gtk_drawing_area_new ();
636 view_data->pixmap = NULL;
637 view_data->win = NULL;
638 view_data->out = NULL;
641 view_data->zoom = 43.0; /* 86.0; Must be small for demos :-) */
645 GTK_OBJECT (view_data->drawing_area),
647 GTK_SIGNAL_FUNC (drawing_area_realize), view_data);
650 GTK_OBJECT (view_data->drawing_area),
652 GTK_SIGNAL_FUNC (drawing_area_exposed), view_data);
654 gtk_widget_show (view_data->drawing_area);
656 setup_size (bed, view_data);
658 view = gnome_view_new (view_data->drawing_area);
659 view_data->view = view;
662 GTK_OBJECT (view), "destroy",
663 GTK_SIGNAL_FUNC (destroy_view), view_data);
666 uih = gnome_ui_handler_new ();
667 gnome_view_set_ui_handler (view, uih);
669 gtk_signal_connect (GTK_OBJECT (view), "view_activate",
670 GTK_SIGNAL_FUNC (view_activate), view_data);
672 gtk_signal_connect (GTK_OBJECT (view), "size_query",
673 GTK_SIGNAL_FUNC (view_size_query), view_data);
675 gtk_signal_connect (GTK_OBJECT (view), "set_zoom_factor",
676 GTK_SIGNAL_FUNC (view_zoom_query), view_data);
678 bed->views = g_list_prepend (bed->views, view_data);
681 gnome_view_register_verb (view, "FirstPage",
682 view_switch_page, view_data);
683 gnome_view_register_verb (view, "PrevPage",
684 view_switch_page, view_data);
685 gnome_view_register_verb (view, "NextPage",
686 view_switch_page, view_data);
687 gnome_view_register_verb (view, "LastPage",
688 view_switch_page, view_data);
694 embeddable_factory (GnomeEmbeddableFactory *This, void *data)
696 GnomeEmbeddable *embeddable;
697 GnomePersistStream *stream;
698 bed_t *bed = (bed_t *)data;
700 bed = g_new0 (bed_t, 1);
705 printf ("Created new bonobo object %p\n", bed);
708 * Creates the BonoboObject server
710 embeddable = gnome_embeddable_new (view_factory, bed);
711 if (embeddable == NULL){
719 * Interface GNOME::PersistStream
721 stream = gnome_persist_stream_new ("bonobo-object:image-x-pdf",
722 load_image_from_stream,
725 if (stream == NULL) {
726 gtk_object_unref (GTK_OBJECT (embeddable));
731 bed->embeddable = embeddable;
734 * Bind the interfaces
736 gnome_object_add_interface (GNOME_OBJECT (embeddable),
737 GNOME_OBJECT (stream));
739 GTK_OBJECT (embeddable), "destroy",
740 GTK_SIGNAL_FUNC (destroy_embed), bed);
742 embeddable_servers++;
744 /* Setup some verbs */
745 gnome_embeddable_add_verb (embeddable,
748 _("goto the first page"));
749 gnome_embeddable_add_verb (embeddable,
752 _("goto the previous page"));
753 gnome_embeddable_add_verb (embeddable,
756 _("goto the next page"));
757 gnome_embeddable_add_verb (embeddable,
760 _("goto the last page"));
762 return (GnomeObject *) embeddable;
766 init_bonobo_image_x_pdf_factory (void)
768 factory = gnome_embeddable_factory_new (
769 "bonobo-object-factory:image-x-pdf",
770 embeddable_factory, NULL);
779 init_server_factory (int argc, char **argv)
781 gnome_CORBA_init_with_popt_table (
782 "bonobo-image-x-pdf", "1.0",
783 &argc, argv, NULL, 0, NULL, GNORBA_INIT_SERVER_FUNC, &ev);
785 if (bonobo_init (CORBA_OBJECT_NIL, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE)
786 g_error (_("I could not initialize Bonobo"));
790 main (int argc, char *argv [])
792 CORBA_exception_init (&ev);
794 init_server_factory (argc, argv);
795 if (!init_bonobo_image_x_pdf_factory ()){
796 fprintf (stderr, "Could not initialize the Bonobo PDF factory\n"
797 "probably a server is already running?");
803 initParams (xpdfConfigFile); /* Init font path */
805 gtk_widget_set_default_colormap (gdk_rgb_get_cmap ());
806 gtk_widget_set_default_visual (gdk_rgb_get_visual ());
810 CORBA_exception_free (&ev);