* atk-bridge/bridge.c:
[platform/core/uifw/at-spi2-atk.git] / util / magnifier.c
1 /*
2  * AT-SPI - Assistive Technology Service Provider Interface
3  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4  *
5  * Copyright 2001 Sun Microsystems Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include <popt.h>
24 #include <gdk/gdkwindow.h>
25 #include <libbonobo.h>
26 #include "magnifier.h"
27 #include "mag_image.h"
28
29 #define ENV_STRING_MAX_SIZE 128
30
31 /*
32  * Our parent GObject type
33  */
34 #define PARENT_TYPE BONOBO_OBJECT_TYPE
35
36 struct sockaddr_un mag_server = { AF_UNIX ,  "/tmp/magnifier_socket" };
37
38 typedef struct {
39         gchar *target_display;
40         gchar *source_display;
41         int   vertical_split;
42         int   horizontal_split;
43         int   dual_head;
44         int   fullscreen;
45         int   mouse_follow;
46         int   invert_image;
47         float zoom_factor;
48         int   min_refresh_time;
49         int   no_bonobo;
50         int   fast_cmap_convert;
51         int   no_initial_region;
52 } MagnifierOptions;
53
54 static MagnifierOptions global_options = { ":0.0",
55                                            ":0.0",
56                                            0,
57                                            0,
58                                            0,
59                                            0,
60                                            0,
61                                            0,
62                                            2.0,
63                                            200,
64                                            0,
65                                            0,
66                                            0
67                                          };
68
69 struct poptOption magnifier_options [] = {
70         {"target_display", 't', POPT_ARG_STRING, &global_options.target_display, 't', "specify display on which to show magnified view", NULL},
71         {"source_display", 's', POPT_ARG_STRING, &global_options.source_display, 's', "specify display to magnify", NULL},
72         {"vertical", 'v', POPT_ARG_NONE, &global_options.vertical_split, 'v', "split screen vertically (if target display = source display)", NULL},
73         {"horizontal", 'h', POPT_ARG_NONE, &global_options.horizontal_split, 'h', "split screen horizontally (if target display = source display)", NULL},
74         {"dual-head", 'd', POPT_ARG_NONE, &global_options.dual_head, 'd', "dual-head display mode (maps magnifier to second display)", NULL},
75         {"mouse follow", 'm', POPT_ARG_NONE, &global_options.mouse_follow, 'm', "track mouse movements", NULL},
76         {"refresh time", 'r', POPT_ARG_NONE, &global_options.min_refresh_time, 'r', "minimum refresh time for mouse follow and idle, in ms", NULL},
77         {"zoom (scale) factor", 'z', POPT_ARG_FLOAT, &global_options.zoom_factor, 'z', "zoom (scale) factor used to magnify source display", NULL}, 
78 /*      {"invert image", 'i', POPT_ARG_NONE, &global_options.invert_image, 'i', "invert the image colormap", NULL}, */
79         {"fast-colormap-conversion", 'c', POPT_ARG_NONE, &global_options.fast_cmap_convert, 'c', "use faster colormap conversion algorithm (fails for 6 bit color)", NULL}, 
80         {"no-bonobo", '\0', POPT_ARG_NONE, &global_options.no_bonobo, '\0', "don't use bonobo for controls, use sockets", NULL},
81         {"no-initial-region", '\0', POPT_ARG_NONE, &global_options.no_initial_region, '\0', "don't create an initial zoom region", NULL},
82         {NULL, 0, 0, NULL, 0, 0}
83 };
84
85 #define MSG_LEN 80
86
87 static GtkWidget *window; /* TODO: clean up, with accessor func? */
88
89 static void
90 magnifier_realize (GtkWidget *widget)
91 {
92   XWMHints wm_hints;
93   Atom wm_window_protocols[2];
94   static gboolean initialized = FALSE;
95   
96   if (!initialized)
97     {
98       wm_window_protocols[0] = gdk_x11_get_xatom_by_name ("WM_DELETE_WINDOW");
99       wm_window_protocols[1] = gdk_x11_get_xatom_by_name ("_NET_WM_PING");
100     }
101   
102   wm_hints.flags = InputHint;
103   wm_hints.input = False;
104   
105   XSetWMHints (GDK_WINDOW_XDISPLAY (widget->window),
106                GDK_WINDOW_XWINDOW (widget->window), &wm_hints);
107   
108   XSetWMProtocols (GDK_WINDOW_XDISPLAY (widget->window),
109                    GDK_WINDOW_XWINDOW (widget->window), wm_window_protocols, 2);
110 }
111
112 static void
113 magnifier_exit()
114 {
115   gtk_exit(0);
116 }
117
118 static gboolean get_commands(GIOChannel* client,
119                              GIOCondition condition,
120                              gpointer data){
121   char msg[MSG_LEN];
122   int desc_client = 0;
123   
124   memset(msg,0,MSG_LEN);
125   
126   if((desc_client = accept(desc,(struct sockaddr*)&client_sockaddr,&size_client)) == -1){
127     perror("Could connect to client");exit(1);
128   }
129   
130   read(desc_client,msg,sizeof(msg));
131   parse_message(msg, data);
132   return TRUE;
133
134 }
135
136 static void
137 magnifier_pack_regions (Magnifier *magnifier)
138 {
139   /* 
140    * this call prevents resizing, which is a bother, but required to 
141    * work around dtwm incompatibilities.  Perhaps a better workaround will
142    * be found, or we can make this a runtime option.
143    */ 
144   gtk_widget_set_size_request (magnifier->mag_data->output_window, 
145                                magnifier->mag_data->mag_width, 
146                                magnifier->mag_data->mag_height);
147
148   gdk_window_move(magnifier->mag_data->output_window->window,
149                   magnifier->mag_data->mag_x,
150                   magnifier->mag_data->mag_y);
151
152 }
153
154 int main (int argc, char** argv){
155   GIOChannel *mag_channel;
156   char *dpyname;
157   char env_string[ENV_STRING_MAX_SIZE];
158
159   /* TODO: finish replacing socket connection IPC with bonobo service. */
160   Magnifier *magnifier;
161   char * obj_id;
162   GdkGeometry geometry;
163   
164   x_cmap = NULL;
165
166   size_client = sizeof(client_sockaddr);
167
168   image = NULL;
169
170   if (!bonobo_init (&argc, argv))
171     {
172       g_error ("Could not initialize Bonobo");
173     }
174
175   magnifier = magnifier_new (argc, argv);
176   
177   magnifier->mag_data->follow_mouse =
178           global_options.mouse_follow;
179   magnifier->mag_data->color_inverted =
180           global_options.invert_image;
181   if (!global_options.no_initial_region) 
182     {
183       magnifier->mag_data->zoom_regions =
184               g_list_prepend (magnifier->mag_data->zoom_regions,
185                               g_new0 (ZoomRegionData, 1));
186       magnifier->mag_data->factor_x = (int) global_options.zoom_factor; 
187       magnifier->mag_data->factor_y = (int) global_options.zoom_factor;
188     }
189   else {
190       g_print ("starting magnifier with no initial zoom region\n");
191       magnifier->mag_data->mag_width = 0; 
192       magnifier->mag_data->mag_height = 0;
193   }
194       /* TODO: enable fractional magnifications option? */
195   if (global_options.target_display) {
196     g_snprintf (env_string, (size_t) (ENV_STRING_MAX_SIZE-1), "DISPLAY=%s", global_options.target_display);
197     putenv (env_string);
198   }
199   gtk_init (&argc, &argv);
200
201   window = g_object_connect (gtk_widget_new (gtk_window_get_type (),
202                                              "user_data", NULL,
203                                              "can_focus", FALSE,
204                                              "type", GTK_WINDOW_TOPLEVEL,
205                                              "title", "magnifier",
206                                              "allow_grow", FALSE,
207                                              "allow_shrink", FALSE,
208                                              "border_width", 10,
209                                              NULL),
210                              "signal::realize", magnifier_realize, NULL,
211                              "signal::destroy", magnifier_exit, NULL,
212                              NULL);
213   
214   drawing_area = gtk_drawing_area_new();
215   gtk_container_add (GTK_CONTAINER (window),drawing_area);
216   gtk_widget_add_events(GTK_WIDGET(drawing_area),GDK_BUTTON_PRESS_MASK);
217   gtk_signal_connect (GTK_OBJECT (drawing_area),"expose_event",
218                       GTK_SIGNAL_FUNC(expose_event),NULL);
219   
220   /* Init socket */
221   if (global_options.no_bonobo) {
222     if((desc = socket(AF_UNIX,SOCK_STREAM,0)) == -1){
223       perror("Socket");exit(1);
224     }
225     unlink("/tmp/magnifier_socket");
226
227     if(bind(desc,(struct sockaddr*)&mag_server,sizeof(mag_server)) == -1){
228        perror("Bind");exit(1);
229     }
230
231     if(listen(desc,100) == -1){
232        perror("Listen");exit(1);
233     }
234     mag_channel = g_io_channel_unix_new(desc);
235     g_io_add_watch(mag_channel,
236                    G_IO_IN | G_IO_ERR,
237                    get_commands,
238                    magnifier->mag_data);
239
240   }
241   
242   /* init image information */
243   if (!global_options.source_display) global_options.source_display = gdk_get_display();
244   dpyname = global_options.source_display + (strlen(global_options.source_display) - 1);
245   screen_num = atoi(dpyname);
246   if (!global_options.target_display) {
247     if((screen_num == 0) && global_options.dual_head)
248       screen_num++;
249     else if (global_options.dual_head)
250       screen_num--;
251     global_options.target_display =
252             (char *) malloc (strlen (global_options.source_display));
253     strncpy (global_options.target_display,
254              global_options.source_display,
255              strlen(global_options.source_display)-2);
256     global_options.target_display[strlen(global_options.source_display)-2] = 0;
257     sprintf(global_options.target_display, "%s.%d",
258             global_options.target_display, screen_num);
259   }
260
261   printf("displays: source=%s; target=%s\n",
262          global_options.source_display,
263          global_options.target_display);
264   
265   magnifier->mag_data->source_display = XOpenDisplay (global_options.source_display);
266   magnifier->mag_data->target_display = GDK_DISPLAY();
267
268   spi_image_root_window = RootWindow(magnifier->mag_data->source_display, screen_num);
269   gdk_pixbuf_xlib_init (magnifier->mag_data->source_display, screen_num);
270   image = gdk_pixbuf_new        (GDK_COLORSPACE_RGB,FALSE, 8,
271                                 DisplayWidth (magnifier->mag_data->source_display,screen_num)/2,
272                                 DisplayHeight(magnifier->mag_data->source_display,screen_num)/2);
273   scaled_image = gdk_pixbuf_new (GDK_COLORSPACE_RGB,FALSE, 8,
274                                 DisplayWidth (magnifier->mag_data->target_display,screen_num),
275                                 DisplayHeight(magnifier->mag_data->target_display,screen_num));
276   if (global_options.vertical_split)
277     {
278       magnifier->mag_data->mag_width =
279               DisplayWidth (magnifier->mag_data->target_display,screen_num)/2;
280       magnifier->mag_data->mag_height =
281               DisplayHeight (magnifier->mag_data->target_display, screen_num);
282     }
283   else if (global_options.horizontal_split)
284     {
285       magnifier->mag_data->mag_width =
286             DisplayWidth (magnifier->mag_data->target_display, screen_num);
287       magnifier->mag_data->mag_height =
288             DisplayHeight (magnifier->mag_data->target_display,screen_num)/2;
289     }
290   else if (global_options.fullscreen)
291     {
292       magnifier->mag_data->mag_width =
293             DisplayWidth (magnifier->mag_data->target_display, screen_num);
294       magnifier->mag_data->mag_height =
295             DisplayHeight (magnifier->mag_data->target_display,screen_num);
296     }
297   magnifier->mag_data->mag_x =
298           DisplayWidth (magnifier->mag_data->target_display, screen_num)
299           - magnifier->mag_data->mag_width;
300   magnifier->mag_data->mag_y =
301           DisplayHeight (magnifier->mag_data->target_display, screen_num)
302           - magnifier->mag_data->mag_height;
303
304   magnifier->mag_data->output_window = window;
305   gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
306   gtk_widget_show_all (window);
307
308   magnifier_pack_regions (magnifier);
309   
310   /* if (global_options.fullscreen) */
311   gdk_window_stick (window->window);
312   gdk_window_set_functions(window->window, 0);
313   gdk_window_raise(window->window);
314   
315   gtk_timeout_add(global_options.min_refresh_time, display_image, magnifier->mag_data);
316
317   obj_id = "OAFIID:Accessibility_Util_Magnifier:proto0.1";
318
319   if (! global_options.no_bonobo)
320     {     
321       int ret = bonobo_activation_active_server_register (
322         obj_id, BONOBO_OBJREF (magnifier));
323
324       if (ret == Bonobo_ACTIVATION_REG_SUCCESS)
325         {
326           bonobo_main ();
327         }
328     }
329   else
330     {
331       gtk_main ();
332     }
333
334   unlink("magnifier_socket");
335   return 0;
336 }
337
338 static void
339 impl_magnifier_fullscreen (PortableServer_Servant servant,
340                            CORBA_Environment *ev)
341 {
342   Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
343   magnifier->mag_data->mag_width = DisplayWidth (magnifier->mag_data->target_display, screen_num);
344   magnifier->mag_data->mag_height = DisplayHeight (magnifier->mag_data->target_display, screen_num);
345 }
346                                    
347 static void
348 impl_magnifier_set_extents (PortableServer_Servant servant,
349                             CORBA_long x1,
350                             CORBA_long y1,
351                             CORBA_long x2,
352                             CORBA_long y2,
353                             CORBA_Environment *ev)
354 {
355   Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
356   magnifier->mag_data->mag_width = x2 - x1;
357   magnifier->mag_data->mag_height = y2 - y1;
358   gdk_window_move(window->window, x1, y1);
359 }
360
361 static void
362 impl_magnifier_set_follow_mouse (PortableServer_Servant servant,
363                                  const CORBA_boolean follow_mouse,
364                                  CORBA_Environment *ev)
365 {
366   Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
367   magnifier->mag_data->follow_mouse = (int) follow_mouse;
368 }
369
370 static void
371 impl_magnifier_set_contrast (PortableServer_Servant servant,
372                              const CORBA_short contrast,
373                              CORBA_Environment *ev)
374 {
375   Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
376   magnifier->mag_data->contrast = (int) contrast;
377 }
378
379 static void
380 impl_magnifier_set_source_display (PortableServer_Servant servant,
381                                    const CORBA_char *display,
382                                    CORBA_Environment *ev)
383 {
384   Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
385   magnifier->mag_data->source_display =
386           XOpenDisplay (global_options.source_display);
387 }
388
389 static void
390 impl_magnifier_set_target_display (PortableServer_Servant servant,
391                                    const CORBA_char *display,
392                                    CORBA_Environment *ev)
393 {
394   Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
395   magnifier->mag_data->target_display = GDK_DISPLAY();
396 }
397
398 static void
399 impl_magnifier_goto (PortableServer_Servant servant,
400                      const CORBA_long x,
401                      const CORBA_long y,
402                      CORBA_Environment *ev)
403 {
404   Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
405   magnifier->mag_data->center.x = (int) x;
406   magnifier->mag_data->center.y = (int) y;
407 }
408
409 static void
410 impl_magnifier_set_roi (PortableServer_Servant servant,
411                         const CORBA_short zoom_region,
412                         const CORBA_long x1,
413                         const CORBA_long y1,
414                         const CORBA_long x2,
415                         const CORBA_long y2,
416                         CORBA_Environment *ev)
417 {
418   Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
419   magnifier->mag_data->center.x = (int) ((x1 + x2)/2);
420   magnifier->mag_data->center.y = (int) ((y1 + y2)/2);
421 }
422
423 static void
424 impl_magnifier_set_mag_factor (PortableServer_Servant servant,
425                                const CORBA_short zoom_region,
426                                const CORBA_float mag_factor_x,
427                                const CORBA_float mag_factor_y,
428                                CORBA_Environment *ev)
429 {
430   Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
431   if (zoom_region == (CORBA_short) 0) /* TODO: fix for multi-zoom-regions */
432     {
433       magnifier->mag_data->factor_x = (float) mag_factor_x;
434       magnifier->mag_data->factor_y = (float) mag_factor_y;
435     }
436 }
437
438 static void
439 impl_magnifier_mark_dirty (PortableServer_Servant servant,
440                            const CORBA_short zoom_region,
441                            const CORBA_long x1,
442                            const CORBA_long y1,
443                            const CORBA_long x2,
444                            const CORBA_long y2,
445                            CORBA_Environment *ev)
446 {
447   Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
448   /* TODO: implement */
449 }
450
451 static void
452 impl_magnifier_mark_unmanaged (PortableServer_Servant servant,
453                                const CORBA_short zoom_region,
454                                CORBA_Environment *ev)
455 {
456   Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
457   /* TODO: implement */
458 }
459
460 static CORBA_short
461 impl_magnifier_create_zoom_region (PortableServer_Servant servant,
462                                    const CORBA_float zx,
463                                    const CORBA_float zy,
464                                    const CORBA_long x1,
465                                    const CORBA_long y1,
466                                    const CORBA_long x2,
467                                    const CORBA_long y2,
468                                    CORBA_Environment *ev)
469 {
470   Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
471   if (magnifier->mag_data->zoom_regions == NULL)
472     {
473       magnifier->mag_data->zoom_regions =
474               g_list_prepend (magnifier->mag_data->zoom_regions,
475                               g_new0 (ZoomRegionData, 1));
476       magnifier->mag_data->factor_x = (int) zx; 
477       magnifier->mag_data->factor_y = (int) zy;
478       magnifier->mag_data->mag_x = x1;
479       magnifier->mag_data->mag_y = y1;
480       magnifier->mag_data->mag_width = (x2 - x1);
481       magnifier->mag_data->mag_height = (y2 - y1);
482       magnifier_pack_regions (magnifier);
483       return 0;
484     }
485   else
486     {
487       return -1;
488     }
489 }
490
491 static CORBA_boolean
492 impl_magnifier_get_zoom_region_params (PortableServer_Servant servant,
493                                        const CORBA_short zoom_region,
494                                        CORBA_float * zx,
495                                        CORBA_float * zy, CORBA_long * x1,
496                                        CORBA_long * y1, CORBA_long * x2,
497                                        CORBA_long * y2,
498                                        CORBA_Environment * ev)
499 {
500   Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
501   if (zoom_region == (CORBA_short) 0)
502   {
503     *zx = magnifier->mag_data->factor_x;
504     *zy = magnifier->mag_data->factor_y;
505     *x1 = 0;
506     *y1 = 0;
507     *x2 = *x1 + magnifier->mag_data->mag_width;
508     *y2 = *y1 + magnifier->mag_data->mag_height;
509     return CORBA_TRUE;    
510   }
511   else return CORBA_FALSE;
512 }
513
514 static void
515 impl_magnifier_resize_zoom_region (PortableServer_Servant servant,
516                                    const CORBA_short zoom_region,
517                                    const CORBA_long x1, const CORBA_long y1,
518                                    const CORBA_long x2, const CORBA_long y2,
519                                    CORBA_Environment * ev)
520 {
521   Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
522   if (zoom_region == 0)
523     {
524       magnifier->mag_data->mag_x = x1;
525       magnifier->mag_data->mag_y = y1;
526       magnifier->mag_data->mag_width = (x2 - x1);
527       magnifier->mag_data->mag_height = (y2 - y1);
528       magnifier_pack_regions (magnifier);
529     }
530 }
531
532 static void
533 impl_magnifier_destroy_zoom_region (PortableServer_Servant servant,
534                                     const CORBA_short zoom_region,
535                                     CORBA_Environment * ev)
536 {
537   Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
538   if (zoom_region == 0)
539     {
540       g_list_free (magnifier->mag_data->zoom_regions);
541     }
542 }
543
544 static void
545 impl_magnifier_clear_all_zoom_regions (PortableServer_Servant servant,
546                                        CORBA_Environment * ev)
547 {
548   Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
549   g_list_free (magnifier->mag_data->zoom_regions);
550   magnifier->mag_data->zoom_regions = NULL;
551 }
552
553 static void
554 impl_magnifier_exit (PortableServer_Servant servant, CORBA_Environment *ev)
555 {
556         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
557         if (magnifier->mag_data->zoom_regions) 
558                 g_list_free (magnifier->mag_data->zoom_regions);
559         g_free (magnifier->mag_data);
560         magnifier_exit();
561 }
562
563 static void
564 magnifier_class_init (MagnifierClass *klass)
565 {
566         GObjectClass * object_class = (GObjectClass *) klass;
567         POA_Accessibility_Magnifier__epv *epv = &klass->epv;
568 /*
569         object_class->finalize = magnifier_finalize;
570 */
571         epv->_set_SourceDisplay = impl_magnifier_set_source_display;
572         epv->_set_TargetDisplay = impl_magnifier_set_target_display;
573         epv->setROI = impl_magnifier_set_roi;
574         epv->setMagFactor = impl_magnifier_set_mag_factor;
575         epv->markDirty = impl_magnifier_mark_dirty;
576         epv->markUnmanaged = impl_magnifier_mark_unmanaged;
577         epv->createZoomRegion = impl_magnifier_create_zoom_region;
578         epv->getZoomRegionParams = impl_magnifier_get_zoom_region_params;
579         epv->resizeZoomRegion = impl_magnifier_resize_zoom_region;
580         epv->destroyZoomRegion = impl_magnifier_destroy_zoom_region;
581         epv->clearAllZoomRegions = impl_magnifier_clear_all_zoom_regions;
582         epv->exit = impl_magnifier_exit;
583 }
584
585 static void
586 magnifier_init (Magnifier *magnifier)
587 {
588   magnifier->mag_data = (MagnifierData *) g_new0 (MagnifierData, 1);
589   magnifier->mag_data->factor_x = 2;
590   magnifier->mag_data->factor_y = 2;
591   magnifier->mag_data->contrast = 0;
592   magnifier->mag_data->color_inverted = FALSE;
593   magnifier->mag_data->fast_rgb_convert = FALSE;
594   magnifier->mag_data->center.x = 0;
595   magnifier->mag_data->center.y = 0;
596   magnifier->mag_data->zoom_regions = NULL;
597 }
598
599 GType
600 magnifier_get_type (void)
601 {
602         static GType type = 0;
603
604         if (!type) {
605                 static const GTypeInfo tinfo = {
606                         sizeof (MagnifierClass),
607                         (GBaseInitFunc) NULL,
608                         (GBaseFinalizeFunc) NULL,
609                         (GClassInitFunc) magnifier_class_init,
610                         (GClassFinalizeFunc) NULL,
611                         NULL, /* class data */
612                         sizeof (Magnifier),
613                         0, /* n preallocs */
614                         (GInstanceInitFunc) magnifier_init,
615                         NULL /* value table */
616                 };
617                 /*
618                  *   Here we use bonobo_type_unique instead of
619                  * gtk_type_unique, this auto-generates a load of
620                  * CORBA structures for us. All derived types must
621                  * use bonobo_type_unique.
622                  */
623                 type = bonobo_type_unique (
624                         PARENT_TYPE,
625                         POA_Accessibility_Magnifier__init,
626                         NULL,
627                         G_STRUCT_OFFSET (MagnifierClass, epv),
628                         &tinfo,
629                         "Magnifier");
630         }
631
632         return type;
633 }
634
635 Magnifier *
636 magnifier_new (int argc, char **argv)
637 {
638   poptContext ctx;      
639   Magnifier *magnifier =
640           MAGNIFIER (g_object_new (magnifier_get_type(), NULL));
641   ctx = poptGetContext ("magnifier",
642                         argc,
643                         (const char **)argv,
644                         magnifier_options,
645                         0);
646
647   while (poptGetNextOpt (ctx) >= 0)
648         /**/;
649
650   return magnifier;
651 }