]> www.fi.muni.cz Git - evince.git/blob - bonobo-image-x-pdf.cc
caa65fcddf1d9496841f057311804b6b6f7d821e
[evince.git] / bonobo-image-x-pdf.cc
1 /*
2  * image/x-pdf BonoboObject.
3  *
4  * Author:
5  *   Michael Meeks <michael@imaginator.com>
6  *
7  */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <stddef.h>
11 #include <string.h>
12 #include <config.h>
13 extern "C" {
14 #define GString G_String
15 #include <gnome.h>
16 #include <libgnorba/gnorba.h>
17 #include <bonobo/gnome-bonobo.h>
18 #undef  GString 
19 }
20 #include "gtypes.h"
21 #include "GString.h"
22 #include "parseargs.h"
23 #include "gfile.h"
24 #include "gmem.h"
25 #include "Object.h"
26 #include "Stream.h"
27 #include "Array.h"
28 #include "Dict.h"
29 #include "XRef.h"
30 #include "Catalog.h"
31 #include "Page.h"
32 #include "Link.h"
33 #include "PDFDoc.h"
34 #include "GOutputDev.h"
35 #include "PSOutputDev.h"
36 #include "TextOutputDev.h"
37 #include "Params.h"
38 #include "Error.h"
39 #include "config.h"
40 #include "BonoboStream.h"
41
42 #define PDF_DEBUG 0
43
44 GBool printCommands = gFalse;
45
46 CORBA_Environment ev;
47 CORBA_ORB orb;
48
49 /*
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.
53  */
54 static int embeddable_servers = 0;
55
56 /*
57  * Our embeddable factory
58  */
59 static GnomeEmbeddableFactory *factory;
60         
61
62 /*
63  * BonoboObject data
64  */
65 typedef struct {
66   GnomeEmbeddable *embeddable;
67
68   PDFDoc       *pdf;
69   XRef         *xref; /* Ugly global XRef hack fix */
70   BonoboStream *pdf_stream;
71   GNOME_Stream  bonobo_stream;
72
73   GList *views;
74 } bed_t;
75
76 /*
77  * View data
78  */
79 typedef struct {
80   GnomeView            *view;
81   bed_t *bed;
82
83   double                scale;
84   GtkWidget            *drawing_area;
85   GdkPixmap            *pixmap;
86   GdkWindow            *win;
87   GOutputDev           *out;
88   GdkColor              paper;
89   gint                  w, h;
90   gdouble               zoom;
91   gint                  page;
92 } view_data_t;
93
94 extern "C" {
95   static void realize_drawing_areas (bed_t *bed);
96   static void setup_pixmap (bed_t *doc, view_data_t *view, GdkWindow *window);
97 }
98
99 static void
100 redraw_view (view_data_t *view_data, GdkRectangle *rect)
101 {
102   gint width, height;
103   bed_t *bed = view_data->bed;
104
105   g_return_if_fail (view_data->pixmap != NULL);
106
107   /*
108    * Do not draw outside the region that we know how to display
109    */
110   if (rect->x > view_data->w)
111     return;
112   
113   if (rect->y > view_data->h)
114     return;
115
116   /*
117    * Clip the draw region
118    */
119   if (rect->x + rect->width > view_data->w)
120     rect->width = view_data->w - rect->x;
121   
122   if (rect->y + rect->height > view_data->h)
123     rect->height = view_data->h - rect->y;
124   
125   /*
126    * Draw the exposed region.
127    */
128   gdk_draw_pixmap (view_data->drawing_area->window,
129                    view_data->drawing_area->style->white_gc,
130                    view_data->pixmap,
131                    rect->x, rect->y,
132                    rect->x, rect->y,
133                    rect->width,
134                    rect->height);
135 }
136
137 static void
138 configure_size (view_data_t *view_data)
139 {
140   gtk_widget_set_usize (
141     view_data->drawing_area,
142     view_data->w,
143     view_data->h);
144 }
145
146 static void
147 render_page (view_data_t *view_data)
148 {
149   setup_pixmap (view_data->bed, view_data,
150                 view_data->win);
151   xref = view_data->bed->xref; /* Ugly global XRef hack fix */
152   view_data->out->startDoc();
153   view_data->bed->pdf->displayPage(view_data->out,
154                                    view_data->page, view_data->zoom,
155                                    0, gTrue);
156   view_data->bed->xref = xref;
157   xref = NULL;
158 }
159
160 static void
161 redraw_view_all (view_data_t *view_data)
162 {
163   GdkRectangle rect;
164   g_return_if_fail (view_data != NULL);
165
166 #if PDF_DEBUG > 0
167   printf ("Redraw view of page %d\n", view_data->page);
168 #endif
169   render_page (view_data);
170   rect.x = 0;
171   rect.y = 0;
172   rect.width  = view_data->w;
173   rect.height = view_data->h;
174   redraw_view (view_data, &rect);
175   gtk_widget_queue_draw (GTK_WIDGET (view_data->drawing_area));
176 }
177
178 static void
179 redraw_all (bed_t *bed)
180 {
181         GList *l;
182         
183         for (l = bed->views; l; l = l->next) {
184           GdkRectangle rect;
185           view_data_t *view_data = (view_data_t *)l->data;
186           redraw_view_all (view_data);
187         }
188 }
189
190 static int
191 save_image (GnomePersistStream *ps, GNOME_Stream stream, void *data)
192 {
193   g_warning ("Unimplemented");
194   return -1;
195 }
196
197 /*
198  * different size ?
199  */
200 static gboolean
201 setup_size (bed_t *doc, view_data_t *view)
202 {
203   int      w, h;
204   gboolean same;
205
206   if (!doc || !view || !doc->pdf) {
207     view->w = 320;
208     view->h = 200;
209     return FALSE;
210   }
211   w = (int)((doc->pdf->getPageWidth  (view->page) * view->zoom) / 72.0);
212   h = (int)((doc->pdf->getPageHeight (view->page) * view->zoom) / 72.0);
213   if (view->w == w && view->h == h)
214     same = TRUE;
215   else
216     same = FALSE;
217   view->w = w;
218   view->h = h;
219
220   return same;
221 }
222
223 static void
224 bed_free_data (bed_t *bed)
225 {
226   g_return_if_fail (bed != NULL);
227
228   if (bed->pdf)
229     delete bed->pdf;
230   bed->pdf = NULL;
231   if (bed->pdf_stream)
232     delete (bed->pdf_stream);
233   bed->pdf_stream = NULL;
234   
235   if (bed->bonobo_stream) {
236     CORBA_exception_init (&ev);
237     CORBA_Object_release (bed->bonobo_stream, &ev);
238     bed->bonobo_stream = NULL;
239     CORBA_exception_free (&ev);
240   }
241 }
242
243 /*
244  * Loads a PDF from a GNOME_Stream
245  */
246 static int
247 load_image_from_stream (GnomePersistStream *ps, GNOME_Stream stream, void *data)
248 {
249         bed_t *bed = (bed_t *)data;
250         CORBA_long length;
251         GNOME_Stream_iobuf *buffer;
252         guint lp;
253         #define CHUNK 512
254         FILE *hack;
255         char *name;
256         Object obj;
257
258         if (bed->pdf || bed->pdf_stream ||
259             bed->bonobo_stream) {
260           g_warning ("Won't overwrite pre-existing stream: you wierdo");
261           return 0;
262         }
263
264         /* We need this for later */
265         CORBA_Object_duplicate (stream, &ev);
266         bed->bonobo_stream = stream;
267         g_return_val_if_fail (ev._major == CORBA_NO_EXCEPTION, 0);
268
269 #if PDF_DEBUG > 0
270         printf ("Loading PDF from persiststream\n");
271 #endif
272         obj.initNull();
273         bed->pdf_stream = new BonoboStream (stream, 0, -1, &obj);
274         bed->pdf = new PDFDoc (bed->pdf_stream);
275         bed->xref = xref; /* Ugly global XRef hack fix */
276         xref = NULL;
277                                               
278 #if PDF_DEBUG > 0
279         printf ("Done load\n");
280 #endif
281         if (!(bed->pdf->isOk())) {
282           g_warning ("Duff pdf data\n");
283           bed_free_data (bed);
284         }
285         if (!bed->pdf->getCatalog()) {
286           g_warning ("Duff pdf catalog\n");
287           bed_free_data (bed);
288         }
289
290         realize_drawing_areas (bed);
291         redraw_all (bed);
292         return 0;
293 }
294
295 extern "C" {
296
297   static void
298   destroy_view (GnomeView *view, view_data_t *view_data)
299   {
300     view_data->bed->views = g_list_remove (view_data->bed->views, view_data);
301     gtk_object_unref (GTK_OBJECT (view_data->drawing_area));
302     
303     g_free (view_data);
304   }
305
306   static void
307   destroy_embed (GnomeView *view, bed_t *bed)
308   {
309     CORBA_Environment ev;
310
311     printf ("Destroying embedded component\n");
312
313     while (bed->views)
314       destroy_view (NULL, (view_data_t *)bed->views->data);
315
316     bed_free_data (bed);
317     g_free (bed);
318
319     embeddable_servers--;
320
321     if (embeddable_servers == 0){
322       gnome_object_unref (GNOME_OBJECT (factory));
323       gtk_main_quit ();
324     }
325   }
326
327   static void
328   setup_pixmap (bed_t *doc, view_data_t *view_data, GdkWindow *window)
329   {
330     GdkGCValues  gcValues;
331     GdkGC       *strokeGC;
332     PDFDoc      *pdf;
333     int          w, h;
334     GdkPixmap   *pixmap = NULL;
335     
336     g_return_if_fail (doc != NULL);
337     g_return_if_fail (doc->pdf != NULL);
338     g_return_if_fail (view_data != NULL);
339     
340     pdf = doc->pdf;
341
342     if (setup_size (doc, view_data) &&
343         view_data->pixmap) {
344 #if PDF_DEBUG > 0
345       printf ("No need to re-init output device\n");
346 #endif
347       return;
348     }
349
350     w = view_data->w;
351     h = view_data->h;
352
353     pixmap = gdk_pixmap_new (window, w, h, -1);
354     
355     gdk_color_white (gtk_widget_get_default_colormap(), &view_data->paper);
356     view_data->out = new GOutputDev (pixmap, view_data->paper, window);
357     
358     gdk_color_white (gtk_widget_get_default_colormap (), &gcValues.foreground);
359     gdk_color_black (gtk_widget_get_default_colormap (), &gcValues.background);
360     gcValues.line_width = 1;
361     gcValues.line_style = GDK_LINE_SOLID;
362     strokeGC = gdk_gc_new_with_values (
363       pixmap, &gcValues, 
364       (enum GdkGCValuesMask)(GDK_GC_FOREGROUND | GDK_GC_BACKGROUND | GDK_GC_LINE_WIDTH | GDK_GC_LINE_STYLE));
365     
366     gdk_draw_rectangle (pixmap, strokeGC,
367                         TRUE, 0, 0,
368                         w, h);
369     
370     view_data->pixmap = pixmap;
371     configure_size (view_data);
372   }
373
374   static gboolean
375   view_is_good (view_data_t *view_data)
376   {
377     if (!view_data ||
378         !view_data->bed ||
379         !view_data->bed->pdf)
380       return FALSE;
381
382     return TRUE;
383   }
384
385   static gboolean
386   first_page (view_data_t *view_data)
387   {
388     g_return_val_if_fail (view_is_good (view_data), FALSE);
389     if (view_data->page != 1) {
390       view_data->page = 1;
391       return TRUE;
392     } else
393       return FALSE;
394   }
395
396   static gboolean
397   last_page (view_data_t *view_data)
398   {
399     g_return_val_if_fail (view_is_good (view_data), FALSE);
400     if (view_data->page < view_data->bed->pdf->getNumPages()) {
401       view_data->page = view_data->bed->pdf->getNumPages();
402       return TRUE;
403     } else
404       return FALSE;
405   }
406
407   static gboolean
408   next_page (view_data_t *view_data)
409   {
410     g_return_val_if_fail (view_is_good (view_data), FALSE);
411     if (view_data->page < view_data->bed->pdf->getNumPages()) {
412       view_data->page++;
413       return TRUE;
414     } else
415       return FALSE;
416   }
417
418   static gboolean
419   prev_page (view_data_t *view_data)
420   {
421     g_return_val_if_fail (view_is_good (view_data), FALSE);
422     if (view_data->page > 1) {
423       view_data->page--;
424       return TRUE;
425     } else
426       return FALSE;
427   }
428
429   static void
430   page_first_cb (GnomeUIHandler *uih, void *data, char *path)
431   {
432     first_page ((view_data_t *)data);
433     redraw_view_all ((view_data_t *)data);
434   }
435   
436   static void
437   page_next_cb  (GnomeUIHandler *uih, void *data, char *path)
438   {
439     next_page ((view_data_t *)data);
440     redraw_view_all ((view_data_t *)data);
441   }
442   
443   static void
444   page_prev_cb  (GnomeUIHandler *uih, void *data, char *path)
445   {
446     prev_page ((view_data_t *)data);
447     redraw_view_all ((view_data_t *)data);
448   }
449
450   static void
451   page_last_cb  (GnomeUIHandler *uih, void *data, char *path)
452   {
453     last_page ((view_data_t *)data);
454     redraw_view_all ((view_data_t *)data);
455   }
456 }
457
458 static void
459 view_create_menus (view_data_t *view_data)
460 {
461   GNOME_UIHandler remote_uih;
462   GnomeView *view = view_data->view;
463   GnomeUIHandler *uih;
464   
465   uih = gnome_view_get_ui_handler (view);
466   remote_uih = gnome_view_get_remote_ui_handler (view);
467   
468   if (remote_uih == CORBA_OBJECT_NIL) {
469     g_warning ("server has no UI hander");
470     return;
471   }
472   
473   gnome_ui_handler_set_container (uih, remote_uih);
474
475   gnome_ui_handler_menu_new_subtree (uih, "/Page",
476                                      N_("Page..."),
477                                      N_("Set the currently displayed page"),
478                                      1,
479                                      GNOME_UI_HANDLER_PIXMAP_NONE, NULL,
480                                      0, (GdkModifierType)0);
481
482   gnome_ui_handler_menu_new_item (uih, "/Page/First",
483                                   N_("First"), N_("View the first page"), -1,
484                                   GNOME_UI_HANDLER_PIXMAP_NONE, NULL, 0,
485                                   (GdkModifierType)0, page_first_cb, (gpointer)view_data);
486                                  
487   gnome_ui_handler_menu_new_item (uih, "/Page/Prev",
488                                   N_("Previous"), N_("View the previous page"), -1,
489                                   GNOME_UI_HANDLER_PIXMAP_NONE, NULL, 0,
490                                   (GdkModifierType)0, page_prev_cb, (gpointer)view_data);
491                                  
492   gnome_ui_handler_menu_new_item (uih, "/Page/Next",
493                                   N_("Next"), N_("View the next page"), -1,
494                                   GNOME_UI_HANDLER_PIXMAP_NONE, NULL, 0,
495                                   (GdkModifierType)0, page_next_cb, (gpointer)view_data);
496                                  
497   gnome_ui_handler_menu_new_item (uih, "/Page/Last",
498                                   N_("Last"), N_("View the last page"), -1,
499                                   GNOME_UI_HANDLER_PIXMAP_NONE, NULL, 0,
500                                   (GdkModifierType)0, page_last_cb, (gpointer)view_data);
501
502   gnome_ui_handler_toolbar_new_item (uih, "/First", 
503                                      N_("First"), N_("View the first page"), -1,
504                                      GNOME_UI_HANDLER_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_FIRST,
505                                      0, (GdkModifierType)0, page_first_cb, (gpointer)view_data);
506   gnome_ui_handler_toolbar_new_item (uih, "/Prev",
507                                      N_("Previous"), N_("View the previous page"), -1,
508                                      GNOME_UI_HANDLER_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_BACK,
509                                      0, (GdkModifierType)0, page_prev_cb, (gpointer)view_data);
510   gnome_ui_handler_toolbar_new_item (uih, "/Next",
511                                      N_("Next"), N_("View the next page"), -1,
512                                      GNOME_UI_HANDLER_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_FORWARD,
513                                      0, (GdkModifierType)0, page_next_cb, (gpointer)view_data);
514   gnome_ui_handler_toolbar_new_item (uih, "/Last",
515                                      N_("Last"), N_("View the last page"), -1,
516                                      GNOME_UI_HANDLER_PIXMAP_STOCK, GNOME_STOCK_PIXMAP_LAST,
517                                      0, (GdkModifierType)0, page_last_cb, (gpointer)view_data);
518 }
519
520 /*
521  * When this view is deactivated, we must remove our menu items.
522  */
523 static void
524 view_remove_menus (view_data_t *view_data)
525 {
526         GnomeView *view = view_data->view;
527         GnomeUIHandler *uih;
528
529         uih = gnome_view_get_ui_handler (view);
530
531         gnome_ui_handler_unset_container (uih);
532 }
533
534 extern "C" {
535
536   static void
537   drawing_area_realize (GtkWidget *drawing_area, view_data_t *view_data)
538   {
539     g_return_if_fail (view_data != NULL);
540     g_return_if_fail (drawing_area != NULL);
541
542     view_data->win = gtk_widget_get_parent_window (drawing_area);
543   }
544
545   static int
546   drawing_area_exposed (GtkWidget *widget, GdkEventExpose *event, view_data_t *view_data)
547   {
548     if (!view_data ||
549         !view_data->bed->pdf)
550       return TRUE;
551     
552     redraw_view (view_data, &event->area);
553     
554     return TRUE;
555   }
556
557   static void
558   view_activate (GnomeView *view, gboolean activate, gpointer data)
559   {
560     view_data_t *view_data = (view_data_t *) data;
561     g_return_if_fail (view != NULL);
562     g_return_if_fail (view_data != NULL);
563     
564     gnome_view_activate_notify (view, activate);
565     
566 #if PDF_DEBUG > 0
567     printf ("View change activation to %d\n", activate);
568 #endif
569     /*
570      * If we were just activated, we merge in our menu entries.
571      * If we were just deactivated, we remove them.
572      */
573     if (activate)
574       view_create_menus (view_data);
575     else
576       view_remove_menus (view_data);
577   }
578
579   static void
580   view_size_query (GnomeView *view, int *desired_width, int *desired_height,
581                    gpointer data)
582   {
583     view_data_t *view_data = (view_data_t *) data;
584     
585     g_return_if_fail (view_data != NULL);
586
587     *desired_width  = view_data->w;
588     *desired_height = view_data->h;
589   }
590
591   static void
592   view_zoom_query (GnomeView *view, gdouble new_zoom, gpointer data)
593   {
594     view_data_t *view_data = (view_data_t *) data;
595
596     g_return_if_fail (view_data != NULL);
597
598     /* The rational behind this is that the _entire_ page is allocated
599        regardless of viewport size, so you _really_ don't want it too big ! */
600     g_return_if_fail (new_zoom > 10.0);
601     g_return_if_fail (new_zoom < 180.0);
602
603     view_data->zoom = new_zoom;
604     redraw_view_all (view_data);
605   }
606
607   static void
608   realize_drawing_areas (bed_t *bed)
609   {
610     GList *l;
611     
612     for (l = bed->views; l; l = l->next) {
613       view_data_t *view_data = (view_data_t *)l->data;
614       g_return_if_fail (view_data->win);
615       render_page (view_data);
616       configure_size (view_data);
617     }  
618   }
619
620   static void
621   view_switch_page (GnomeView *view, const char *verb_name, void *user_data)
622   {
623     view_data_t  *view_data = (view_data_t *) user_data;
624     GdkRectangle  rect;
625     gboolean      changed = FALSE;
626
627     if (!g_strcasecmp (verb_name, "firstpage")) {
628       changed = first_page (view_data);
629     } else if (!g_strcasecmp (verb_name, "prevpage")) {
630       changed = prev_page (view_data);
631     } else if (!g_strcasecmp (verb_name, "nextpage")) {
632       changed = next_page (view_data);
633     } else if (!g_strcasecmp (verb_name, "lastpage")) {
634       changed = last_page (view_data);
635     } else
636       g_warning ("Unknown verb");
637
638     if (changed) {
639       render_page (view_data);
640       redraw_view (view_data, &rect);
641       gtk_widget_queue_draw (GTK_WIDGET (view_data->drawing_area));
642     }
643   }
644 }
645
646 static GnomeView *
647 view_factory (GnomeEmbeddable *embeddable,
648               const GNOME_ViewFrame view_frame,
649               void *data)
650 {
651         GnomeView *view;
652         GnomeUIHandler *uih;
653         bed_t *bed = (bed_t *)data;
654         view_data_t *view_data = g_new (view_data_t, 1);
655
656 #if PDF_DEBUG > 0
657         printf ("Created new bonobo object view %p\n", view_data);
658 #endif
659         
660         view_data->scale  = 1.0;
661         view_data->bed    = bed;
662         view_data->drawing_area = gtk_drawing_area_new ();
663         view_data->pixmap = NULL;
664         view_data->win    = NULL;
665         view_data->out    = NULL;
666         view_data->w      = 320;
667         view_data->h      = 320;
668         view_data->zoom   = 43.0; /* 86.0; Must be small for demos :-) */
669         view_data->page   = 1;
670
671         gtk_signal_connect (
672                 GTK_OBJECT (view_data->drawing_area),
673                 "realize",
674                 GTK_SIGNAL_FUNC (drawing_area_realize), view_data);
675
676         gtk_signal_connect (
677                 GTK_OBJECT (view_data->drawing_area),
678                 "expose_event",
679                 GTK_SIGNAL_FUNC (drawing_area_exposed), view_data);
680
681         gtk_widget_show (view_data->drawing_area);
682
683         setup_size (bed, view_data);
684
685         view = gnome_view_new (view_data->drawing_area);
686         view_data->view = view;
687
688         gtk_signal_connect (
689                 GTK_OBJECT (view), "destroy",
690                 GTK_SIGNAL_FUNC (destroy_view), view_data);
691
692         /* UI handling */
693         uih = gnome_ui_handler_new ();
694         gnome_view_set_ui_handler (view, uih);
695
696         gtk_signal_connect (GTK_OBJECT (view), "view_activate",
697                             GTK_SIGNAL_FUNC (view_activate), view_data);
698
699         gtk_signal_connect (GTK_OBJECT (view), "size_query",
700                             GTK_SIGNAL_FUNC (view_size_query), view_data);
701
702         gtk_signal_connect (GTK_OBJECT (view), "set_zoom_factor",
703                             GTK_SIGNAL_FUNC (view_zoom_query), view_data);
704
705         bed->views = g_list_prepend (bed->views, view_data);
706
707         /* Verb handling */
708         gnome_view_register_verb (view, "FirstPage",
709                                   view_switch_page, view_data);
710         gnome_view_register_verb (view, "PrevPage",
711                                   view_switch_page, view_data);
712         gnome_view_register_verb (view, "NextPage",
713                                   view_switch_page, view_data);
714         gnome_view_register_verb (view, "LastPage",
715                                   view_switch_page, view_data);
716
717         return view;
718 }
719
720 static GnomeObject *
721 embeddable_factory (GnomeEmbeddableFactory *This, void *data)
722 {
723         GnomeEmbeddable *embeddable;
724         GnomePersistStream *stream;
725         bed_t *bed = (bed_t *)data;
726
727         bed = g_new0 (bed_t, 1);
728         if (!bed)
729                 return NULL;
730
731 #if PDF_DEBUG > 0
732         printf ("Created new bonobo object %p\n", bed);
733 #endif
734         /*
735          * Creates the BonoboObject server
736          */
737         embeddable = gnome_embeddable_new (view_factory, bed);
738         if (embeddable == NULL){
739                 g_free (bed);
740                 return NULL;
741         }
742
743         bed->pdf = NULL;
744
745         /*
746          * Interface GNOME::PersistStream 
747          */
748         stream = gnome_persist_stream_new ("bonobo-object:image-x-pdf",
749                                            load_image_from_stream,
750                                            save_image,
751                                            bed);
752         if (stream == NULL) {
753                 gtk_object_unref (GTK_OBJECT (embeddable));
754                 g_free (bed);
755                 return NULL;
756         }
757
758         bed->embeddable = embeddable;
759
760         /*
761          * Bind the interfaces
762          */
763         gnome_object_add_interface (GNOME_OBJECT (embeddable),
764                                     GNOME_OBJECT (stream));
765         gtk_signal_connect (
766           GTK_OBJECT (embeddable), "destroy",
767           GTK_SIGNAL_FUNC (destroy_embed), bed);
768
769         embeddable_servers++;
770
771         /* Setup some verbs */
772         gnome_embeddable_add_verb (embeddable,
773                                    "FirstPage",
774                                    _("_First page"),
775                                    _("goto the first page"));
776         gnome_embeddable_add_verb (embeddable,
777                                    "PrevPage",
778                                    _("_Previous page"),
779                                    _("goto the previous page"));
780         gnome_embeddable_add_verb (embeddable,
781                                    "NextPage",
782                                    _("_Next page"),
783                                    _("goto the next page"));
784         gnome_embeddable_add_verb (embeddable,
785                                    "LastPage",
786                                    _("_Last page"),
787                                    _("goto the last page"));
788         
789         return (GnomeObject *) embeddable;
790 }
791
792 static gboolean
793 init_bonobo_image_x_pdf_factory (void)
794 {
795         factory = gnome_embeddable_factory_new (
796                 "bonobo-object-factory:image-x-pdf",
797                 embeddable_factory, NULL);
798
799         if (factory == NULL)
800                 return FALSE;
801         else
802                 return TRUE;
803 }
804
805 static void
806 init_server_factory (int argc, char **argv)
807 {
808         gnome_CORBA_init_with_popt_table (
809                 "bonobo-image-x-pdf", "1.0",
810                 &argc, argv, NULL, 0, NULL, GNORBA_INIT_SERVER_FUNC, &ev);
811
812         if (bonobo_init (CORBA_OBJECT_NIL, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE)
813                 g_error (_("I could not initialize Bonobo"));
814 }
815
816 int
817 main (int argc, char *argv [])
818 {
819   CORBA_exception_init (&ev);
820   
821   init_server_factory (argc, argv);
822   if (!init_bonobo_image_x_pdf_factory ()) {
823     fprintf (stderr, "Could not initialize the Bonobo PDF factory\n"
824                      "probably a server is already running?");
825     exit (1);
826   }
827   
828   errorInit ();
829   
830   initParams (xpdfConfigFile); /* Init font path */
831   
832   gtk_widget_set_default_colormap (gdk_rgb_get_cmap ());
833   gtk_widget_set_default_visual (gdk_rgb_get_visual ());
834
835   bonobo_main ();
836
837   freeParams ();
838   CORBA_exception_free (&ev);
839   
840   return 0;
841 }