magnifier.c

Go to the documentation of this file.
00001 /*
00002  * AT-SPI - Assistive Technology Service Provider Interface
00003  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
00004  *
00005  * Copyright 2001 Sun Microsystems Inc.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Library General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Library General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Library General Public
00018  * License along with this library; if not, write to the
00019  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00020  * Boston, MA 02111-1307, USA.
00021  */
00022 
00023 #include "config.h"
00024 #include "magnifier.h"
00025 #include "magnifier-private.h"
00026 #include "zoom-region.h"
00027 #include "zoom-region-private.h"
00028 #include "gmag-cursor.h"
00029 #include "gmag-graphical-server.h"
00030 #include "GNOME_Magnifier.h"
00031 
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <strings.h>
00035 
00036 #include <libbonobo.h>
00037 #include <login-helper/login-helper.h>
00038 
00039 #include <gdk-pixbuf/gdk-pixbuf-io.h>
00040 #include <gdk/gdkx.h>
00041 #include <gdk/gdk.h>
00042 #include <gtk/gtk.h>
00043 
00044 /* if you #define this, don't forget to set MAG_CLIENT_DEBUG env variable */
00045 #define DEBUG_CLIENT_CALLS
00046 
00047 #ifdef DEBUG_CLIENT_CALLS
00048 static gboolean client_debug = FALSE;
00049 #define DBG(a) if (client_debug) { (a); }
00050 #else
00051 #define DBG(a)
00052 #endif
00053 
00054 typedef struct
00055 {
00056     LoginHelper parent;
00057     Magnifier *mag;
00058 } MagLoginHelper;
00059 
00060 typedef struct 
00061 {
00062     LoginHelperClass parent_class;
00063 } MagLoginHelperClass;
00064 
00065 static GObjectClass *parent_class = NULL;
00066 
00067 enum {
00068         MAGNIFIER_SOURCE_DISPLAY_PROP,
00069         MAGNIFIER_TARGET_DISPLAY_PROP,
00070         MAGNIFIER_SOURCE_SIZE_PROP,
00071         MAGNIFIER_TARGET_SIZE_PROP,
00072         MAGNIFIER_CURSOR_SET_PROP,
00073         MAGNIFIER_CURSOR_SIZE_PROP,
00074         MAGNIFIER_CURSOR_ZOOM_PROP,
00075         MAGNIFIER_CURSOR_COLOR_PROP,
00076         MAGNIFIER_CURSOR_HOTSPOT_PROP,
00077         MAGNIFIER_CURSOR_DEFAULT_SIZE_PROP,
00078         MAGNIFIER_CROSSWIRE_SIZE_PROP,
00079         MAGNIFIER_CROSSWIRE_CLIP_PROP,
00080         MAGNIFIER_CROSSWIRE_COLOR_PROP
00081 } PropIdx;
00082 
00083 typedef struct
00084 {
00085         GNOME_Magnifier_RectBounds rectbounds;
00086         GNOME_Magnifier_RectBounds viewport;
00087         gboolean is_managed;
00088         gint scroll_policy;
00089         gfloat contrast;
00090         gfloat zx;
00091         gfloat zy;
00092         gint32 xalign;
00093         gint32 yalign;
00094         guint32 border_color;
00095         gint32 border_size;
00096         gchar *smoothing_type;
00097         gboolean inverse;
00098 
00099 } MagnifierZoomRegionSaveProps;
00100 
00101 #ifdef DEBUG_CLIENT_CALLS
00102 gchar* mag_prop_names[MAGNIFIER_CROSSWIRE_COLOR_PROP + 1] = {
00103     "SOURCE_DISPLAY",
00104     "TARGET_DISPLAY",
00105     "SOURCE_SIZE",
00106     "TARGET_SIZE",
00107     "CURSOR_SET",
00108     "CURSOR_SIZE",
00109     "CURSOR_ZOOM",
00110     "CURSOR_COLOR",
00111     "CURSOR_HOTSPOT",
00112     "CURSOR_DEFAULT_SIZE",
00113     "CROSSWIRE_SIZE",
00114     "CROSSWIRE_CLIP",
00115     "CROSSWIRE_COLOR"
00116 };
00117 #endif
00118 
00119 static Magnifier *_this_magnifier = NULL;
00120 extern gint       fixes_event_base;
00121 
00122 static void magnifier_init_cursor_set (Magnifier *magnifier, gchar *cursor_set);
00123 static void magnifier_init_window (Magnifier *magnifier, GdkScreen *screen);
00124 static gboolean magnifier_reset_struts_at_idle (gpointer data);
00125 static void magnifier_init_window (Magnifier *magnifier, GdkScreen *screen);
00126 static void magnifier_adjust_source_size (Magnifier *magnifier);
00127 static gboolean _is_override_redirect = FALSE;
00128 
00129 static Window*
00130 mag_login_helper_get_raise_windows (LoginHelper *helper)
00131 {
00132     Window *mainwin = NULL;
00133     MagLoginHelper *mag_helper = (MagLoginHelper *) helper;
00134     Magnifier *magnifier = MAGNIFIER (mag_helper->mag);
00135 
00136     if (magnifier && magnifier->priv && magnifier->priv->w)
00137     {
00138         mainwin = g_new0 (Window, 2);
00139         mainwin[0] = GDK_WINDOW_XWINDOW (magnifier->priv->w->window);
00140         mainwin[1] = None;
00141     }
00142     return mainwin;
00143 }
00144 
00145 static LoginHelperDeviceReqFlags
00146 mag_login_helper_get_device_reqs (LoginHelper *helper)
00147 {
00148     /* means "don't grab the xserver or core pointer", 
00149        and "we need to raise windows" */
00150 
00151     return LOGIN_HELPER_GUI_EVENTS | 
00152         LOGIN_HELPER_POST_WINDOWS | 
00153         LOGIN_HELPER_CORE_POINTER;
00154 }
00155 
00156 static gboolean
00157 mag_login_helper_set_safe (LoginHelper *helper, gboolean ignored)
00158 {
00159     return TRUE;
00160 }
00161 
00162 static void
00163 mag_login_helper_class_init (MagLoginHelperClass *klass)
00164 {
00165         LoginHelperClass *login_helper_class = LOGIN_HELPER_CLASS(klass);
00166         login_helper_class->get_raise_windows = mag_login_helper_get_raise_windows;
00167         login_helper_class->get_device_reqs = mag_login_helper_get_device_reqs;
00168         login_helper_class->set_safe = mag_login_helper_set_safe;
00169 }
00170 
00171 static void
00172 mag_login_helper_init (MagLoginHelper *helper)
00173 {
00174     helper->mag = NULL; /* we set this with mag_login_helper_set_magnifier */
00175 }
00176 
00177 static void
00178 mag_login_helper_set_magnifier (MagLoginHelper *helper, Magnifier *mag)
00179 {
00180     if (helper) 
00181         helper->mag = mag;
00182 }
00183 
00184 BONOBO_TYPE_FUNC (MagLoginHelper, 
00185                   LOGIN_HELPER_TYPE,
00186                   mag_login_helper)
00187 
00188 static gboolean
00189 can_open_display (gchar *display_name)
00190 {
00191     Display *d;
00192     if ((d = XOpenDisplay (display_name)))
00193     {
00194         XCloseDisplay (d);
00195         return TRUE;
00196     }
00197     return FALSE;
00198 }
00199 
00200 static void
00201 magnifier_warp_cursor_to_screen (Magnifier *magnifier)
00202 {
00203         int x, y, unused_x, unused_y;
00204         unsigned int mask;
00205         Window root_return, child_return;
00206 
00207         if (magnifier->source_display)
00208         {
00209             if (!XQueryPointer (GDK_DISPLAY_XDISPLAY (magnifier->source_display), 
00210                                 GDK_WINDOW_XWINDOW (magnifier->priv->root), 
00211                                 &root_return,
00212                                 &child_return,
00213                                 &x, &y,
00214                                 &unused_x, &unused_y,
00215                                 &mask))
00216             {
00217                 XWarpPointer (GDK_DISPLAY_XDISPLAY (magnifier->source_display),
00218                               None,
00219                               GDK_WINDOW_XWINDOW (magnifier->priv->root),
00220                               0, 0, 0, 0,
00221                               x, y);
00222                 XSync (GDK_DISPLAY_XDISPLAY (magnifier->source_display), FALSE);
00223             }
00224         }
00225 }
00226 
00227 static void
00228 magnifier_zoom_regions_mark_dirty (Magnifier *magnifier, GNOME_Magnifier_RectBounds rect_bounds)
00229 {
00230         GList *list;
00231 
00232         g_assert (magnifier);
00233 
00234         list = magnifier->zoom_regions;
00235         while (list) 
00236         {
00237                 /* propagate the expose events to the zoom regions */
00238                 GNOME_Magnifier_ZoomRegion zoom_region;
00239                 CORBA_Environment ev;
00240                 zoom_region = list->data;
00241                 CORBA_exception_init (&ev);
00242                 if (zoom_region)
00243                         GNOME_Magnifier_ZoomRegion_markDirty (CORBA_Object_duplicate (zoom_region, &ev),
00244                                                               &rect_bounds,
00245                                                               &ev);
00246                 list = g_list_next (list);
00247         }
00248 }
00249 
00250 void
00251 magnifier_set_cursor_from_pixbuf (Magnifier *magnifier,
00252                                   GdkPixbuf *cursor_pixbuf)
00253 {
00254         GdkPixmap *pixmap, *mask;
00255         gint width, height;
00256         GdkGC *gc;
00257         GdkDrawable *drawable = magnifier->priv->w->window;
00258 
00259         if (magnifier->priv->cursor) {
00260                 g_object_unref (magnifier->priv->cursor);
00261                 magnifier->priv->cursor = NULL;
00262         }
00263         if (drawable && cursor_pixbuf) {
00264                 const gchar *xhot_string = NULL, *yhot_string = NULL;
00265                 width = gdk_pixbuf_get_width (cursor_pixbuf);
00266                 height = gdk_pixbuf_get_height (cursor_pixbuf);
00267                 pixmap = gdk_pixmap_new (drawable, width, height, -1);
00268                 gc = gdk_gc_new (pixmap);
00269                 if (GDK_IS_DRAWABLE (pixmap))
00270                         gdk_draw_pixbuf (pixmap, gc, cursor_pixbuf, 0, 0, 0, 0,
00271                                          width, height, GDK_RGB_DITHER_NONE,
00272                                          0, 0);
00273                 else
00274                         DBG (g_warning ("empty cursor pixmap created."));
00275                 mask = gdk_pixmap_new (drawable, width, height, 1);
00276                 gdk_pixbuf_render_threshold_alpha (cursor_pixbuf, mask,
00277                                                    0, 0, 0, 0, 
00278                                                    width, height,
00279                                                    200);
00280                 g_object_unref (gc);
00281                 magnifier->priv->cursor = pixmap;
00282                 magnifier->priv->cursor_mask = mask;
00283                 xhot_string = gdk_pixbuf_get_option (cursor_pixbuf,"x_hot");
00284                 yhot_string = gdk_pixbuf_get_option (cursor_pixbuf,"y_hot");
00285                 if (xhot_string)
00286                         magnifier->cursor_hotspot.x = atoi (xhot_string);
00287                 if (yhot_string)
00288                         magnifier->cursor_hotspot.y = atoi (yhot_string);
00289                 if (pixmap) {
00290                         gdk_drawable_get_size (
00291                                 pixmap,
00292                                 &magnifier->priv->cursor_default_size_x,
00293                                 &magnifier->priv->cursor_default_size_y);
00294                         magnifier->priv->cursor_hotspot_x =
00295                                 magnifier->cursor_hotspot.x;
00296                         magnifier->priv->cursor_hotspot_y =
00297                                 magnifier->cursor_hotspot.y;
00298                 }
00299         }
00300 }
00301 
00302 
00303 GdkPixbuf *
00304 magnifier_get_pixbuf_for_name (Magnifier *magnifier, const gchar *cursor_name)
00305 {
00306     GdkPixbuf *retval = NULL;
00307     if (magnifier->priv->cursorlist) 
00308             retval = g_hash_table_lookup (magnifier->priv->cursorlist, cursor_name);
00309     if (retval) 
00310             g_object_ref (retval);
00311     return retval;
00312 }
00313 
00314 void
00315 magnifier_set_cursor_pixmap_by_name (Magnifier *magnifier,
00316                                      const gchar *cursor_name, 
00317                                      gboolean source_fallback)
00318 {
00319         GdkPixbuf *pixbuf;
00320         /* search local table; if not found, use source screen's cursor if source_fallback is TRUE */
00321         if ((pixbuf = magnifier_get_pixbuf_for_name (magnifier, cursor_name)) == NULL) {
00322                 if (source_fallback == TRUE)
00323                 {
00324                         pixbuf = gmag_cursor_get_source_pixbuf (magnifier);
00325                 }
00326                 else
00327                 {
00328                         pixbuf = magnifier_get_pixbuf_for_name (magnifier, "default");
00329                 }
00330         }
00331         magnifier_set_cursor_from_pixbuf (magnifier, pixbuf);
00332         if (pixbuf) g_object_unref (pixbuf);
00333 }
00334 
00335 void
00336 magnifier_notify_damage (Magnifier *magnifier, GdkRectangle *rect)
00337 {
00338         GNOME_Magnifier_RectBounds rect_bounds;
00339         rect_bounds.x1 = rect->x;
00340         rect_bounds.y1 = rect->y;
00341         rect_bounds.x2 = rect->x + rect->width;
00342         rect_bounds.y2 = rect->y + rect->height;
00343 #undef DEBUG_DAMAGE
00344 #ifdef DEBUG_DAMAGE
00345         g_message ("damage");
00346         g_message ("dirty %d, %d to %d, %d", rect_bounds.x1, rect_bounds.y1,
00347                    rect_bounds.x2, rect_bounds.y2);
00348 #endif
00349         magnifier_zoom_regions_mark_dirty (magnifier, rect_bounds);
00350 }
00351 
00352 static void
00353 magnifier_set_extension_listeners (Magnifier *magnifier, GdkWindow *root)
00354 {
00355         gmag_gs_client_init (magnifier);
00356         magnifier->source_initialized = TRUE;
00357 }
00358 
00359 static void
00360 magnifier_size_allocate (GtkWidget *widget)
00361 {
00362         gmag_gs_check_set_struts (_this_magnifier);
00363 }
00364 
00365 static void
00366 magnifier_realize (GtkWidget *widget)
00367 {
00368         gmag_gs_magnifier_realize (widget);
00369 }
00370 
00371 GdkWindow*
00372 magnifier_get_root (Magnifier *magnifier)
00373 {
00374     if (!magnifier->priv->root && magnifier->source_display) {
00375         magnifier->priv->root = gdk_screen_get_root_window (
00376             gdk_display_get_screen (magnifier->source_display,
00377                                     magnifier->source_screen_num));
00378     }
00379     return magnifier->priv->root;
00380 }
00381 
00382 static gint
00383 magnifier_parse_display_name (Magnifier *magnifier, gchar *full_display_string,
00384                               gchar **display_name)
00385 {
00386         gchar *screen_ptr;
00387         gchar **strings;
00388         
00389         if (display_name != NULL) {
00390                 strings = g_strsplit (full_display_string, ":", 2);
00391                 *display_name = strings [0];
00392                 if (strings [1] != NULL)
00393                         g_free (strings [1]);
00394         }
00395 
00396         screen_ptr = rindex (full_display_string, '.');
00397         if (screen_ptr != NULL) {
00398                 return (gint) strtol (++screen_ptr, NULL, 10);
00399         }
00400         return 0;
00401 }
00402 
00403 static void
00404 magnifier_get_display_rect_bounds (Magnifier *magnifier, GNOME_Magnifier_RectBounds *rect_bounds, gboolean is_target)
00405 {
00406     if (is_target)
00407     {
00408         rect_bounds->x1 = 0;
00409         rect_bounds->x2 = gdk_screen_get_width (
00410             gdk_display_get_screen (magnifier->target_display,
00411                                     magnifier->target_screen_num));
00412         rect_bounds->y1 = 0;
00413         rect_bounds->y2 = gdk_screen_get_height (
00414             gdk_display_get_screen (magnifier->target_display,
00415                                     magnifier->target_screen_num));
00416 
00417     }
00418     else 
00419     {
00420         rect_bounds->x1 = 0;
00421         rect_bounds->x2 = gdk_screen_get_width (
00422             gdk_display_get_screen (magnifier->source_display,
00423                                     magnifier->source_screen_num));
00424         rect_bounds->y1 = 0;
00425         rect_bounds->y2 = gdk_screen_get_height (
00426             gdk_display_get_screen (magnifier->source_display,
00427                                     magnifier->source_screen_num));
00428 
00429     }
00430 }
00431 
00432 static void
00433 magnifier_adjust_source_size (Magnifier *magnifier)
00434 {
00435         GNOME_Magnifier_RectBounds rect_bounds; 
00436         gdouble vfract_top, vfract_bottom, hfract_left, hfract_right;
00437         magnifier_get_display_rect_bounds (magnifier, &rect_bounds, FALSE);
00438         hfract_left = (double) (magnifier->target_bounds.x1) / (double) rect_bounds.x2;
00439         vfract_top = (double) (magnifier->target_bounds.y1) / (double) rect_bounds.y2;
00440         hfract_right = (double) (rect_bounds.x2 - magnifier->target_bounds.x2) / (double) rect_bounds.x2;
00441         vfract_bottom = (double) (rect_bounds.y2 - magnifier->target_bounds.y2) / (double) rect_bounds.y2;
00442         /* we make our 'source' rectangle the largest available subsection which we aren't occupying */
00443 #ifdef HAVE_COMPOSITE
00444         if (!g_getenv ("MAGNIFIER_IGNORE_COMPOSITE")) {
00445                 magnifier->source_bounds = rect_bounds;
00446         } else
00447 #endif
00448         if (MAX (hfract_left, hfract_right) > MAX (vfract_top, vfract_bottom))  /* vertical split, approximately */
00449         {
00450                 if (hfract_right > hfract_left) {
00451                         magnifier->source_bounds.x1 = magnifier->target_bounds.x2;
00452                         magnifier->source_bounds.x2 = rect_bounds.x2;
00453                 }
00454                 else 
00455                 {
00456                         magnifier->source_bounds.x1 = rect_bounds.x1;
00457                         magnifier->source_bounds.x2 = magnifier->target_bounds.x1;
00458                 }
00459                 magnifier->source_bounds.y1 = rect_bounds.y1;
00460                 magnifier->source_bounds.y2 = rect_bounds.y2;
00461         }
00462         else /* more-or-less horizontally split */
00463         {
00464                 if (vfract_bottom > vfract_top) {
00465                         magnifier->source_bounds.y1 = magnifier->target_bounds.y2;
00466                         magnifier->source_bounds.y2 = rect_bounds.y2;
00467                 }
00468                 else 
00469                 {
00470                         magnifier->source_bounds.y1 = rect_bounds.y1;
00471                         magnifier->source_bounds.y2 = magnifier->target_bounds.y1;
00472                 }
00473                 magnifier->source_bounds.x1 = rect_bounds.x1;
00474                 magnifier->source_bounds.x2 = rect_bounds.x2;
00475         }
00476         g_message ("set source bounds to %d,%d; %d,%d", 
00477                    magnifier->source_bounds.x1, magnifier->source_bounds.y1, magnifier->source_bounds.x2, magnifier->source_bounds.y2);
00478 }
00479 
00480 static void
00481 magnifier_unref_zoom_region (gpointer data, gpointer user_data)
00482 {
00483 /*      Magnifier *magnifier = user_data; NOT USED */
00484         CORBA_Environment ev;
00485         GNOME_Magnifier_ZoomRegion zoom_region = data;
00486         CORBA_exception_init (&ev);
00487         
00488         DBG(g_message ("unreffing zoom region"));
00489 
00490         GNOME_Magnifier_ZoomRegion_dispose (zoom_region, &ev);
00491         if (!BONOBO_EX (&ev))
00492             Bonobo_Unknown_unref (zoom_region, &ev);
00493 }
00494 
00495 static GSList*
00496 magnifier_zoom_regions_save (Magnifier *magnifier)
00497 {
00498     GList *list;
00499     GSList *save_props = NULL;
00500     
00501     g_assert (magnifier);
00502     list = magnifier->zoom_regions;
00503 
00504     DBG(g_message ("saving %d regions", g_list_length (list)));
00505 
00506     while (list) 
00507     {
00508         GNOME_Magnifier_ZoomRegion zoom_region;
00509         CORBA_Environment ev;
00510         zoom_region = list->data;
00511         CORBA_exception_init (&ev);
00512         if (zoom_region)
00513         {
00514             Bonobo_PropertyBag properties;
00515             CORBA_any *value;
00516             MagnifierZoomRegionSaveProps *zoomer_props = g_new0 (MagnifierZoomRegionSaveProps, 1);
00517 
00518             zoomer_props->rectbounds = GNOME_Magnifier_ZoomRegion_getROI (zoom_region, &ev);
00519             properties = GNOME_Magnifier_ZoomRegion_getProperties (zoom_region, &ev);
00520             value = bonobo_pbclient_get_value (properties, "viewport", TC_GNOME_Magnifier_RectBounds, &ev);
00521             memcpy (&zoomer_props->viewport, value->_value, sizeof (GNOME_Magnifier_RectBounds));
00522             CORBA_free (value);
00523             zoomer_props->is_managed = bonobo_pbclient_get_boolean (properties, "is-managed", NULL);
00524             zoomer_props->scroll_policy = bonobo_pbclient_get_short (properties, "smooth-scroll-policy", NULL);
00525             zoomer_props->contrast = bonobo_pbclient_get_float (properties, "contrast", NULL);
00526             zoomer_props->zx = bonobo_pbclient_get_float (properties, "mag-factor-x", NULL);
00527             zoomer_props->zy = bonobo_pbclient_get_float (properties, "mag-factor-y", NULL);
00528             zoomer_props->xalign = bonobo_pbclient_get_long (properties, "x-alignment", NULL);
00529             zoomer_props->yalign = bonobo_pbclient_get_long (properties, "y-alignment", NULL);
00530             zoomer_props->border_color = bonobo_pbclient_get_long (properties, "border-color", NULL); 
00531             zoomer_props->border_size = bonobo_pbclient_get_long (properties, "border-size", NULL);
00532             zoomer_props->smoothing_type = bonobo_pbclient_get_string (properties, "smoothing-type", NULL); 
00533             zoomer_props->inverse = bonobo_pbclient_get_boolean (properties, "inverse-video", NULL); 
00534 
00535             bonobo_object_release_unref (properties, &ev);
00536             magnifier_unref_zoom_region ((gpointer) zoom_region, NULL);
00537             save_props = g_slist_append (save_props, zoomer_props);
00538         }
00539         list = g_list_next (list);
00540     }   
00541 
00542     magnifier->zoom_regions = NULL;
00543 
00544     return save_props;
00545 }
00546 
00547 static void
00548 magnifier_zoom_regions_restore (Magnifier *magnifier, GSList *region_params)
00549 {
00550         GSList *list = region_params;
00551 
00552         while (list)
00553         {
00554                 CORBA_Environment ev;
00555                 MagnifierZoomRegionSaveProps *zoomer_props = list->data;
00556                 GNOME_Magnifier_ZoomRegion new_region;
00557                 Bonobo_PropertyBag new_properties;
00558 
00559                 CORBA_exception_init (&ev);
00560                 new_region = GNOME_Magnifier_Magnifier_createZoomRegion (BONOBO_OBJREF (magnifier), zoomer_props->zx, zoomer_props->zy, &zoomer_props->rectbounds, &zoomer_props->viewport, &ev);
00561                 new_properties = GNOME_Magnifier_ZoomRegion_getProperties (new_region, &ev);
00562                 bonobo_pbclient_set_boolean (new_properties, "is-managed", 
00563                                              zoomer_props->is_managed, NULL);
00564                 bonobo_pbclient_set_short (new_properties, "smooth-scroll-policy", 
00565                                            zoomer_props->scroll_policy, NULL);
00566                 bonobo_pbclient_set_float (new_properties, "contrast", 
00567                                            zoomer_props->contrast, NULL);
00568 /* NOT YET USED
00569                 bonobo_pbclient_set_long (new_properties, "x-alignment", 
00570                                              zoomer_props->xalign, NULL);
00571                 bonobo_pbclient_set_long (new_properties, "y-alignment", 
00572                                              zoomer_props->yalign, NULL);
00573 */
00574                 bonobo_pbclient_set_long (new_properties, "border-color", 
00575                                              zoomer_props->border_color, NULL);
00576                 bonobo_pbclient_set_long (new_properties, "border-size", 
00577                                              zoomer_props->border_size, NULL);
00578                 bonobo_pbclient_set_string (new_properties, "smoothing-type", 
00579                                              zoomer_props->smoothing_type, NULL);
00580                 bonobo_pbclient_set_boolean (new_properties, "inverse-video", 
00581                                              zoomer_props->inverse, NULL);
00582                 GNOME_Magnifier_Magnifier_addZoomRegion (BONOBO_OBJREF (magnifier), new_region, &ev);
00583                 g_free (zoomer_props->smoothing_type);
00584                 g_free (zoomer_props);
00585                 bonobo_object_release_unref (new_properties, &ev);
00586                 list = g_slist_next (list);
00587         }
00588         g_slist_free (region_params);
00589 }
00590 
00591 static void
00592 magnifier_init_display (Magnifier *magnifier, gchar *display_name, gboolean is_target)
00593 {
00594     if (!can_open_display (display_name))
00595         return;
00596 
00597     if (is_target)
00598     {
00599         magnifier->target_screen_num =
00600             magnifier_parse_display_name (magnifier,
00601                                           display_name,
00602                                           NULL);
00603         magnifier->target_display =
00604             gdk_display_open (display_name);
00605         if (magnifier->target_display_name) g_free (magnifier->target_display_name);
00606         magnifier->target_display_name = g_strdup (display_name);
00607         magnifier->priv->root =
00608             gdk_screen_get_root_window (
00609                 gdk_display_get_screen (
00610                     magnifier->target_display,
00611                     magnifier->target_screen_num));
00612     }
00613     else 
00614     {
00615         magnifier->source_screen_num =
00616             magnifier_parse_display_name (magnifier,
00617                                           display_name,
00618                                           NULL);
00619         magnifier->source_display =
00620             gdk_display_open (display_name);
00621         if (magnifier->source_display)
00622         {
00623             if (magnifier->source_display_name) g_free (magnifier->source_display_name);
00624             magnifier->source_display_name = g_strdup (display_name);
00625             magnifier->priv->root =
00626                 gdk_screen_get_root_window (
00627                     gdk_display_get_screen (
00628                         magnifier->source_display,
00629                         magnifier->source_screen_num));
00630         }
00631     }
00632 }
00633 
00634 static void
00635 magnifier_exit (GtkObject *object)
00636 {
00637         gtk_main_quit ();
00638         exit (0);
00639 }
00640 
00641 #define GET_PIXEL(a,i,j,s,b) \
00642 (*(guint32 *)(memcpy (b,(a) + ((j) * s + (i) * pixel_size_t), pixel_size_t)))
00643 
00644 #define PUT_PIXEL(a,i,j,s,b) \
00645 (memcpy (a + ((j) * s + (i) * pixel_size_t), &(b), pixel_size_t))
00646 
00647 static void
00648 magnifier_recolor_pixbuf (Magnifier *magnifier, GdkPixbuf *pixbuf)
00649 {
00650         int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
00651         int i, j;
00652         int w = gdk_pixbuf_get_width (pixbuf);
00653         int h = gdk_pixbuf_get_height (pixbuf);
00654         guchar *pixels = gdk_pixbuf_get_pixels (pixbuf);
00655         guint32 pixval = 0, cursor_color = 0;
00656         size_t pixel_size_t = 3; /* FIXME: invalid assumption ? */
00657 
00658         cursor_color = ((magnifier->cursor_color & 0xFF0000) >> 16) +
00659                 (magnifier->cursor_color & 0x00FF00) +
00660                 ((magnifier->cursor_color & 0x0000FF) << 16);
00661         for (j = 0; j < h; ++j) {
00662                 for (i = 0; i < w; ++i) {
00663                         pixval = GET_PIXEL (pixels, i, j, rowstride, &pixval);
00664                         if ((pixval & 0x808080) == 0)
00665                         {
00666                                 pixval = cursor_color;
00667                                 PUT_PIXEL (pixels, i, j, rowstride,
00668                                            pixval);
00669                         }
00670                 }
00671         }
00672 }
00673 
00674 void
00675 magnifier_transform_cursor (Magnifier *magnifier)
00676 {
00677         if (magnifier->priv->cursor) /* don't do this if cursor isn't intialized yet */
00678         {
00679                 int width, height;
00680                 int size_x, size_y;
00681                 GdkPixbuf *scaled_cursor_pixbuf;
00682                 GdkPixbuf *scaled_mask_pixbuf;
00683                 GdkPixbuf *scaled_mask_pixbuf_alpha;
00684                 GdkPixbuf *cursor_pixbuf;
00685                 GdkPixbuf *mask_pixbuf;
00686                 GdkPixmap *cursor_pixmap = magnifier->priv->cursor;
00687                 GdkPixmap *mask_pixmap = magnifier->priv->cursor_mask;
00688                 GdkGC *cgc;
00689                 GdkGC *mgc;
00690 
00691                 if (magnifier->cursor_size_x)
00692                 {
00693                         size_x = magnifier->cursor_size_x;
00694                         size_y = magnifier->cursor_size_y;
00695                 }
00696                 else
00697                 {
00698                         size_x = magnifier->priv->cursor_default_size_x * 
00699                                magnifier->cursor_scale_factor;
00700                         size_y = magnifier->priv->cursor_default_size_y * 
00701                                magnifier->cursor_scale_factor;
00702                 }
00703                 gdk_drawable_get_size (magnifier->priv->cursor, &width, &height);
00704                 if ((size_x == width) && (size_y == height) 
00705                     && (magnifier->cursor_color == 0xFF000000)) {
00706                         return; /* nothing changes */
00707                 }
00708                 cgc = gdk_gc_new (cursor_pixmap);
00709                 mgc = gdk_gc_new (mask_pixmap);
00710                 cursor_pixbuf = gdk_pixbuf_get_from_drawable (NULL, cursor_pixmap,
00711                                                               NULL, 0, 0, 0, 0,
00712                                                               width, height);
00713                 if (magnifier->cursor_color != 0xFF000000)
00714                         magnifier_recolor_pixbuf (magnifier, cursor_pixbuf);
00715                 mask_pixbuf = gdk_pixbuf_get_from_drawable (NULL,
00716                                                             mask_pixmap,
00717                                                             NULL, 0, 0, 0, 0,
00718                                                             width, height);
00719                 scaled_cursor_pixbuf = gdk_pixbuf_scale_simple (
00720                         cursor_pixbuf, size_x, size_y, GDK_INTERP_NEAREST);
00721                 
00722                 magnifier->cursor_hotspot.x = magnifier->priv->cursor_hotspot_x * size_x 
00723                                             / magnifier->priv->cursor_default_size_x;
00724                 magnifier->cursor_hotspot.y = magnifier->priv->cursor_hotspot_y * size_y 
00725                                             / magnifier->priv->cursor_default_size_y;
00726                                             
00727                 scaled_mask_pixbuf = gdk_pixbuf_scale_simple (
00728                         mask_pixbuf, size_x, size_y, GDK_INTERP_NEAREST);
00729                 g_object_unref (cursor_pixbuf);
00730                 g_object_unref (mask_pixbuf);
00731                 g_object_unref (cursor_pixmap);
00732                 g_object_unref (mask_pixmap);
00733                 magnifier->priv->cursor = gdk_pixmap_new (
00734                         magnifier->priv->w->window,
00735                         size_x, size_y,
00736                         -1);
00737                 if (!GDK_IS_DRAWABLE (magnifier->priv->cursor)) 
00738                 {
00739                     DBG (g_warning ("NULL magnifier cursor pixmap."));
00740                     return;
00741                 }
00742                 magnifier->priv->cursor_mask = gdk_pixmap_new (
00743                         magnifier->priv->w->window,
00744                         size_x, size_y,
00745                         1);
00746                 if (GDK_IS_DRAWABLE (magnifier->priv->cursor)) {
00747                     gdk_draw_pixbuf (magnifier->priv->cursor,
00748                                      cgc,
00749                                      scaled_cursor_pixbuf,
00750                                      0, 0, 0, 0, size_x, size_y,
00751                                      GDK_RGB_DITHER_NONE, 0, 0 );
00752                 }
00753                 else
00754                     DBG (g_warning ("cursor pixmap is non-drawable."));
00755                 scaled_mask_pixbuf_alpha = gdk_pixbuf_add_alpha (
00756                         scaled_mask_pixbuf, True, 0, 0, 0);
00757                 gdk_pixbuf_render_threshold_alpha (scaled_mask_pixbuf_alpha,
00758                                                    magnifier->priv->cursor_mask,
00759                                                    0, 0, 0, 0, size_x, size_y,
00760                                                    0x80);
00761                 g_object_unref (scaled_mask_pixbuf_alpha);
00762                 g_object_unref (scaled_cursor_pixbuf);
00763                 g_object_unref (scaled_mask_pixbuf);
00764                 g_object_unref (mgc);
00765                 g_object_unref (cgc);
00766         }       
00767 }
00768 
00769 static void
00770 magnifier_init_cursor_set (Magnifier *magnifier, gchar *cursor_set)
00771 {
00772         /*
00773          * we check the cursor-set property string here,
00774          * and create/apply the appropriate cursor settings
00775          */
00776         magnifier->cursor_set = cursor_set;
00777         magnifier->priv->use_source_cursor = 
00778             (!strcmp (cursor_set, "default") && 
00779              (fixes_event_base != 0));
00780         if (magnifier->priv->use_source_cursor) return;
00781 
00782         if (!strcmp (magnifier->cursor_set, "none")) {
00783                 magnifier->priv->cursor = NULL;
00784                 return;
00785         }
00786         else 
00787         {
00788                 GDir *cursor_dir;
00789                 const gchar *filename;
00790                 gchar *cursor_dirname;
00791 
00792                 if (magnifier->priv->cursorlist)
00793                 {
00794                         g_hash_table_destroy (magnifier->priv->cursorlist);
00795                 }
00796                 magnifier->priv->cursorlist = g_hash_table_new_full (g_str_hash, g_str_equal,
00797                                                                      g_free, g_object_unref);
00798 
00799                 cursor_dirname = g_strconcat (CURSORSDIR, "/", magnifier->cursor_set, NULL);
00800                 cursor_dir = g_dir_open (cursor_dirname, 0, NULL);
00801                 /* assignment, not comparison, is intentional */
00802                 while (cursor_dir && (filename = g_dir_read_name (cursor_dir)) != NULL) 
00803                 {
00804                         if (filename) 
00805                         {
00806                                 gchar *path = g_strconcat (cursor_dirname, "/", filename, NULL);
00807                                 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (path, NULL);
00808                                 if (pixbuf)
00809                                 {
00810                                         /* add this pixbuf and its name to our list */
00811                                         gchar **sv, *cname;
00812                                         cname = g_path_get_basename (filename);
00813                                         sv = g_strsplit (cname, ".", 2);
00814                                         g_hash_table_insert (magnifier->priv->cursorlist, 
00815                                                              g_strdup (sv[0]),
00816                                                              pixbuf);
00817                                         g_free (cname);
00818                                         g_strfreev (sv);
00819                                 }
00820                                 g_free (path);
00821                         }
00822                 } 
00823                 g_free (cursor_dirname);
00824                 if (cursor_dir) g_dir_close (cursor_dir);
00825         }
00826         /* don't fallover to source cursor here, we haven't initialized X yet */
00827         magnifier_set_cursor_pixmap_by_name (magnifier, "default", FALSE);
00828         magnifier_transform_cursor (magnifier);
00829 }
00830 
00831 static gboolean 
00832 magnifier_reset_struts_at_idle (gpointer data)
00833 {
00834         if (data)
00835         {
00836                 Magnifier *magnifier = MAGNIFIER (data);
00837                 if (magnifier->priv &&
00838                     GTK_WIDGET_REALIZED (magnifier->priv->w) && 
00839                     gmag_gs_check_set_struts (magnifier)) {
00840                         return FALSE;
00841                 }
00842         }
00843         return TRUE;
00844 }
00845 
00846 static void
00847 magnifier_get_property (BonoboPropertyBag *bag,
00848                         BonoboArg *arg,
00849                         guint arg_id,
00850                         CORBA_Environment *ev,
00851                         gpointer user_data)
00852 {
00853         Magnifier *magnifier = user_data;
00854         int csize = 0;
00855 
00856         DBG (fprintf (stderr, "Get property: \t%s\n", mag_prop_names[arg_id]));
00857         
00858         switch (arg_id) {
00859         case MAGNIFIER_SOURCE_SIZE_PROP:
00860                 BONOBO_ARG_SET_GENERAL (arg, magnifier->source_bounds,
00861                                         TC_GNOME_Magnifier_RectBounds,
00862                                         GNOME_Magnifier_RectBounds, NULL);
00863                 break;
00864         case MAGNIFIER_TARGET_SIZE_PROP:
00865                 BONOBO_ARG_SET_GENERAL (arg, magnifier->target_bounds,
00866                                         TC_GNOME_Magnifier_RectBounds,
00867                                         GNOME_Magnifier_RectBounds, NULL);
00868 
00869                 break;
00870         case MAGNIFIER_CURSOR_SET_PROP:
00871                 BONOBO_ARG_SET_STRING (arg, magnifier->cursor_set);
00872                 break;
00873         case MAGNIFIER_CURSOR_SIZE_PROP:
00874                 BONOBO_ARG_SET_INT (arg, magnifier->cursor_size_x);
00875                 BONOBO_ARG_SET_INT (arg, magnifier->cursor_size_y);
00876                 break;
00877         case MAGNIFIER_CURSOR_ZOOM_PROP:
00878                 BONOBO_ARG_SET_FLOAT (arg, magnifier->cursor_scale_factor);
00879                 break;
00880         case MAGNIFIER_CURSOR_COLOR_PROP:
00881                 BONOBO_ARG_SET_GENERAL (arg, magnifier->cursor_color,
00882                                         TC_CORBA_unsigned_long,
00883                                         CORBA_unsigned_long, NULL);
00884                 break;
00885         case MAGNIFIER_CURSOR_HOTSPOT_PROP:
00886                 BONOBO_ARG_SET_GENERAL (arg, magnifier->cursor_hotspot,
00887                                         TC_GNOME_Magnifier_Point,
00888                                         GNOME_Magnifier_Point, NULL);
00889 
00890                 break;
00891         case MAGNIFIER_CURSOR_DEFAULT_SIZE_PROP:
00892                 if (magnifier->priv->cursor)
00893                         gdk_drawable_get_size (magnifier->priv->cursor,
00894                                                &csize, &csize);
00895                 BONOBO_ARG_SET_INT (arg, csize);
00896                 break;
00897         case MAGNIFIER_CROSSWIRE_SIZE_PROP:
00898                 BONOBO_ARG_SET_INT (arg, magnifier->crosswire_size);
00899                 break;
00900         case MAGNIFIER_CROSSWIRE_CLIP_PROP:
00901                 BONOBO_ARG_SET_BOOLEAN (arg, magnifier->crosswire_clip);
00902                 break;
00903         case MAGNIFIER_CROSSWIRE_COLOR_PROP:
00904                 BONOBO_ARG_SET_LONG (arg, magnifier->crosswire_color);
00905                 break;
00906         case MAGNIFIER_SOURCE_DISPLAY_PROP:
00907                 BONOBO_ARG_SET_STRING (arg, magnifier->source_display_name);
00908                 break;
00909         case MAGNIFIER_TARGET_DISPLAY_PROP:
00910                 BONOBO_ARG_SET_STRING (arg, magnifier->target_display_name);
00911                 break;
00912         default:
00913                 bonobo_exception_set (ev, ex_Bonobo_PropertyBag_NotFound);
00914         };
00915 }
00916 
00917 static void
00918 magnifier_set_property (BonoboPropertyBag *bag,
00919                         BonoboArg *arg,
00920                         guint arg_id,
00921                         CORBA_Environment *ev,
00922                         gpointer user_data)
00923 {
00924         Magnifier *magnifier = user_data;
00925         gchar *full_display_string;
00926 
00927         switch (arg_id) {
00928         case MAGNIFIER_SOURCE_DISPLAY_PROP:
00929                 full_display_string = BONOBO_ARG_GET_STRING (arg);
00930                 if (can_open_display (full_display_string))
00931                 {
00932                     GSList *zoom_region_params = NULL;
00933                     magnifier->source_screen_num =
00934                         magnifier_parse_display_name (magnifier,
00935                                                       full_display_string,
00936                                                       NULL);
00937                     magnifier->source_display =
00938                         gdk_display_open (full_display_string);
00939                     magnifier->source_display_name = g_strdup (full_display_string);
00940                     zoom_region_params = magnifier_zoom_regions_save (magnifier);
00941                     magnifier->priv->root =
00942                         gdk_screen_get_root_window (
00943                             gdk_display_get_screen (
00944                                 magnifier->source_display,
00945                                 magnifier->source_screen_num));
00946                      /* attach listeners for DAMAGE, "dirty region", XFIXES cursor changes */
00947                     magnifier_set_extension_listeners (magnifier, magnifier_get_root (magnifier));
00948                     magnifier_get_display_rect_bounds (magnifier, &magnifier->source_bounds, FALSE);
00949                     magnifier_zoom_regions_restore (magnifier, zoom_region_params);
00950                     magnifier_warp_cursor_to_screen (magnifier);
00951                     gmag_gs_check_set_struts (magnifier);
00952                 }
00953                 DBG(fprintf (stderr, "Set source display: \t%s\n", full_display_string));
00954                 break;
00955         case MAGNIFIER_TARGET_DISPLAY_PROP:
00956                 full_display_string = BONOBO_ARG_GET_STRING (arg);
00957                 if (can_open_display (full_display_string))
00958                 {
00959                     magnifier->target_screen_num =
00960                         magnifier_parse_display_name (magnifier,
00961                                                       full_display_string,
00962                                                       NULL);
00963                     magnifier->target_display =
00964                         gdk_display_open (full_display_string);
00965                     magnifier->target_display_name = g_strdup (full_display_string);
00966                     if (GTK_IS_WINDOW (magnifier->priv->w)) 
00967                     {
00968 #ifdef REPARENT_GTK_WINDOW_WORKS
00969                         gtk_window_set_screen (GTK_WINDOW (magnifier->priv->w), 
00970                                                gdk_display_get_screen (
00971                                                    magnifier->target_display,
00972                                                    magnifier->target_screen_num));
00973 #else
00974                         GSList *zoom_region_params = NULL;
00975                         /* disconnect from the old window's destroy signal */
00976                         g_object_disconnect (magnifier->priv->w,
00977                                   "any_signal::realize", magnifier_realize, NULL,
00978                                   "any_signal::size_allocate", magnifier_size_allocate, NULL,
00979                                   "any_signal::destroy", magnifier_exit, NULL,
00980                                   NULL);
00981                         /* save the old zoom region state */
00982                         zoom_region_params = magnifier_zoom_regions_save (magnifier);
00983                         /* destroy the old window */
00984                         gtk_widget_destroy (magnifier->priv->w);
00985                         /* and re-initialize... */
00986                         magnifier_init_window (magnifier, gdk_display_get_screen (
00987                                                    magnifier->target_display,
00988                                                    magnifier->target_screen_num));
00989                         /* restore the zoom regions in their new host magnifier window */
00990                         magnifier_zoom_regions_restore (magnifier, zoom_region_params);
00991 #endif
00992                     }
00993                     magnifier_get_display_rect_bounds (magnifier, &magnifier->source_bounds, FALSE);
00994                     magnifier_init_cursor_set (magnifier, magnifier->cursor_set); /* needed to reset pixmaps */
00995                     if (magnifier->priv->overlay)
00996                             gdk_window_move (magnifier->priv->overlay,
00997                                              magnifier->target_bounds.x1,
00998                                              magnifier->target_bounds.y1);
00999                     else
01000                             gtk_window_move (GTK_WINDOW (magnifier->priv->w),
01001                                              magnifier->target_bounds.x1,
01002                                              magnifier->target_bounds.y1);
01003                     
01004                     if ((magnifier->target_bounds.x2 - magnifier->target_bounds.x1 > 0) &&
01005                         (magnifier->target_bounds.y2 - magnifier->target_bounds.y1) > 0)
01006                     {
01007                             if (magnifier->priv->overlay)
01008                                     gdk_window_resize (
01009                                             magnifier->priv->overlay,
01010                                             magnifier->target_bounds.x2 -
01011                                             magnifier->target_bounds.x1,
01012                                             magnifier->target_bounds.y2 -
01013                                             magnifier->target_bounds.y1);
01014                         gtk_window_resize (GTK_WINDOW (magnifier->priv->w),
01015                                        magnifier->target_bounds.x2 - magnifier->target_bounds.x1,
01016                                        magnifier->target_bounds.y2 - magnifier->target_bounds.y1);
01017                     DBG(fprintf (stderr, "Set target size: \t%d,%d to %d,%d\n", 
01018                              magnifier->target_bounds.x1, magnifier->target_bounds.y1, magnifier->target_bounds.x2, magnifier->target_bounds.y2));
01019                     }
01020                     /* N. B. we don't reset the target bounds to the limits of the new display, because */
01021                     /* doing so would override the client-specified magnifier size */
01022                     /* magnifier_get_display_rect_bounds (magnifier, &magnifier->target_bounds, TRUE); */
01023                     gmag_gs_check_set_struts (magnifier);
01024                 }
01025                 DBG(fprintf (stderr, "Set target display: \t%s (screen %d)\n", 
01026                               full_display_string, magnifier->target_screen_num));
01027                 break;
01028         case MAGNIFIER_SOURCE_SIZE_PROP:
01029                 magnifier->source_bounds = BONOBO_ARG_GET_GENERAL (arg,
01030                                                                    TC_GNOME_Magnifier_RectBounds,
01031                                                                    GNOME_Magnifier_RectBounds,
01032                                                                    NULL);
01033                 DBG (fprintf (stderr, "Set source size: \t%d,%d to %d,%d\n", 
01034                               magnifier->source_bounds.x1, magnifier->source_bounds.y1, magnifier->source_bounds.x2, magnifier->source_bounds.y2));
01035                 break;
01036         case MAGNIFIER_TARGET_SIZE_PROP:
01037                 magnifier->target_bounds = BONOBO_ARG_GET_GENERAL (arg,
01038                                                                    TC_GNOME_Magnifier_RectBounds,
01039                                                                    GNOME_Magnifier_RectBounds,
01040                                 
01041                                    NULL);
01042                 if (magnifier->priv->overlay)
01043                         gdk_window_move_resize (magnifier->priv->overlay,
01044                                                 magnifier->target_bounds.x1,
01045                                                 magnifier->target_bounds.y1,
01046                                                 magnifier->target_bounds.x2 -
01047                                                 magnifier->target_bounds.x1,
01048                                                 magnifier->target_bounds.y2 -
01049                                                 magnifier->target_bounds.y1);
01050                 else
01051                         gtk_window_move (GTK_WINDOW (magnifier->priv->w),
01052                                          magnifier->target_bounds.x1,
01053                                          magnifier->target_bounds.y1);
01054                 
01055                 gtk_window_resize (GTK_WINDOW (magnifier->priv->w),
01056                                    magnifier->target_bounds.x2 - magnifier->target_bounds.x1,
01057                                    magnifier->target_bounds.y2 - magnifier->target_bounds.y1);
01058                 gmag_gs_check_set_struts (magnifier);
01059                 DBG(fprintf (stderr, "Set target size: \t%d,%d to %d,%d\n", 
01060                               magnifier->target_bounds.x1, magnifier->target_bounds.y1, magnifier->target_bounds.x2, magnifier->target_bounds.y2));
01061                 if (!strcmp (magnifier->target_display_name, magnifier->source_display_name) && 
01062                     (magnifier->target_screen_num == magnifier->source_screen_num)) 
01063                     magnifier_adjust_source_size (magnifier);
01064                 break;
01065         case MAGNIFIER_CURSOR_SET_PROP:
01066                 magnifier_init_cursor_set (magnifier, g_strdup (BONOBO_ARG_GET_STRING (arg)));
01067                 DBG (fprintf (stderr, "Setting cursor set: \t%s\n", BONOBO_ARG_GET_STRING (arg)));
01068                 break;
01069         case MAGNIFIER_CURSOR_SIZE_PROP:
01070                 magnifier->cursor_size_x = BONOBO_ARG_GET_INT (arg);
01071                 magnifier->cursor_size_y = BONOBO_ARG_GET_INT (arg);
01072                 magnifier_transform_cursor (magnifier);
01073                 DBG (fprintf (stderr, "Setting cursor size: \t%d\n", magnifier->cursor_size_x));
01074                 break;
01075         case MAGNIFIER_CURSOR_ZOOM_PROP:
01076                 magnifier->cursor_scale_factor = BONOBO_ARG_GET_FLOAT (arg);
01077                 DBG (fprintf (stderr, "Setting cursor scale factor: \t%f\n", (float) magnifier->cursor_scale_factor));
01078                 magnifier_transform_cursor (magnifier);
01079                 break;
01080         case MAGNIFIER_CURSOR_COLOR_PROP:
01081                 magnifier->cursor_color = BONOBO_ARG_GET_GENERAL (arg,
01082                                                                   TC_CORBA_unsigned_long, 
01083                                                                   CORBA_unsigned_long, 
01084                                                                   NULL);
01085                 magnifier_transform_cursor (magnifier);
01086                 DBG (fprintf (stderr, "Setting cursor color: \t%u\n", (unsigned) magnifier->cursor_color));
01087                 break;
01088         case MAGNIFIER_CURSOR_HOTSPOT_PROP:
01089                 magnifier->cursor_hotspot = BONOBO_ARG_GET_GENERAL (arg,
01090                                                                     TC_GNOME_Magnifier_Point,
01091                                                                     GNOME_Magnifier_Point,
01092                                                                     NULL);
01093                 /* TODO: notify zoomers */
01094                 /* FIXME: don't call init_cursor, it overwrites this property! */
01095                 magnifier_transform_cursor (magnifier); 
01096                 break;
01097         case MAGNIFIER_CURSOR_DEFAULT_SIZE_PROP:
01098                 bonobo_exception_set (ev, ex_Bonobo_PropertyBag_ReadOnly);
01099                 break;
01100         case MAGNIFIER_CROSSWIRE_SIZE_PROP:
01101                 magnifier->crosswire_size = BONOBO_ARG_GET_INT (arg);
01102                 DBG (fprintf (stderr, "Setting crosswire size: \t%d\n", magnifier->crosswire_size));
01103                 /* TODO: notify zoomers */
01104                 break;
01105         case MAGNIFIER_CROSSWIRE_CLIP_PROP:
01106                 magnifier->crosswire_clip = BONOBO_ARG_GET_BOOLEAN (arg);
01107                 DBG (fprintf (stderr, "Setting crosswire clip: \t%s\n", magnifier->crosswire_clip ? "true" : "false"));
01108                 break;
01109         case MAGNIFIER_CROSSWIRE_COLOR_PROP:
01110                 magnifier->crosswire_color = BONOBO_ARG_GET_LONG (arg);
01111                 DBG (fprintf (stderr, "Setting crosswire size: \t%ld\n", (long) magnifier->crosswire_color));
01112                 break;
01113         default:
01114                 bonobo_exception_set (ev, ex_Bonobo_PropertyBag_NotFound);
01115                 break;
01116         };
01117 }
01118 
01119 static void
01120 magnifier_do_dispose (Magnifier *magnifier)
01121 {
01122         /* FIXME: this is dead ropey code structuring */
01123         bonobo_activation_active_server_unregister (
01124                 MAGNIFIER_OAFIID, BONOBO_OBJREF (magnifier));
01125 
01126         if (magnifier->zoom_regions)
01127                 g_list_free (magnifier->zoom_regions);
01128         magnifier->zoom_regions = NULL;
01129         
01130         bonobo_main_quit ();
01131 }
01132 
01133 static void
01134 magnifier_gobject_dispose (GObject *object)
01135 {
01136         magnifier_do_dispose (MAGNIFIER (object));
01137 
01138         BONOBO_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
01139 }
01140 
01141 static void
01142 impl_magnifier_set_source_display (PortableServer_Servant servant,
01143                                    const CORBA_char *display,
01144                                    CORBA_Environment *ev)
01145 {
01146         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01147         BonoboArg *arg = bonobo_arg_new (BONOBO_ARG_STRING);
01148         gchar *full_display_string;
01149 
01150         full_display_string = g_strdup (display);
01151         if (strcmp (full_display_string, "") == 0)
01152                 full_display_string = (gchar *) g_getenv ("DISPLAY");
01153 
01154         BONOBO_ARG_SET_STRING (arg, full_display_string);
01155         
01156         DBG (fprintf (stderr, "Set source display: \t%s\n",
01157                       full_display_string));
01158 
01159         if (strcmp (full_display_string, magnifier->source_display_name)) {
01160             magnifier_set_property (magnifier->property_bag,
01161                                     arg,
01162                                     MAGNIFIER_SOURCE_DISPLAY_PROP,
01163                                     ev,
01164                                     magnifier);
01165         }
01166         else
01167         {
01168             DBG (fprintf (stderr, "Attempt to set source to same value as previous: %s\n",
01169                           full_display_string));
01170         }
01171         bonobo_arg_release (arg);
01172 }
01173 
01174 static void
01175 impl_magnifier_set_target_display (PortableServer_Servant servant,
01176                                    const CORBA_char *display,
01177                                    CORBA_Environment *ev)
01178 {
01179         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01180         BonoboArg *arg = bonobo_arg_new (BONOBO_ARG_STRING);
01181         gchar *full_display_string;
01182 
01183         full_display_string = g_strdup (display);
01184         if (strcmp (full_display_string, "") == 0)
01185                 full_display_string = (gchar *) g_getenv ("DISPLAY");
01186 
01187         BONOBO_ARG_SET_STRING (arg, full_display_string);
01188         
01189         DBG (fprintf (stderr, "Set target display: \t%s\n",
01190                       full_display_string));
01191 
01192         if (strcmp (full_display_string, magnifier->target_display_name)) 
01193         {
01194             magnifier_set_property (magnifier->property_bag,
01195                                     arg,
01196                                     MAGNIFIER_TARGET_DISPLAY_PROP,
01197                                     ev,
01198                                     magnifier);
01199         }
01200         else
01201         {
01202             DBG (fprintf (stderr, "Attempt to set target to same value as previous: %s\n",
01203                           full_display_string));
01204         }
01205         bonobo_arg_release (arg);
01206 }
01207 
01208 static 
01209 CORBA_string
01210 impl_magnifier_get_source_display (PortableServer_Servant servant,
01211                                    CORBA_Environment *ev)
01212 {
01213         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01214         DBG (fprintf (stderr, "Get source display: \t%s\n", magnifier->source_display_name));
01215 
01216         return CORBA_string_dup (magnifier->source_display_name ? magnifier->source_display_name : "");
01217 }
01218 
01219 static 
01220 CORBA_string
01221 impl_magnifier_get_target_display (PortableServer_Servant servant,
01222                                    CORBA_Environment *ev)
01223 {
01224         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01225         DBG (fprintf (stderr, "Get target display: \t%s\n", 
01226                       magnifier->target_display_name));
01227 
01228         return CORBA_string_dup (magnifier->target_display_name ? magnifier->target_display_name : "");
01229 }
01230 
01231 static GNOME_Magnifier_ZoomRegion
01232 impl_magnifier_create_zoom_region (PortableServer_Servant servant,
01233                                    const CORBA_float zx,
01234                                    const CORBA_float zy,
01235                                    const GNOME_Magnifier_RectBounds *roi,
01236                                    const GNOME_Magnifier_RectBounds *viewport,
01237                                    CORBA_Environment *ev)
01238 {
01239         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01240         CORBA_any viewport_any;
01241         ZoomRegion *zoom_region = zoom_region_new ();
01242         Bonobo_PropertyBag properties;
01243         GNOME_Magnifier_ZoomRegion retval;
01244 
01245         DBG (fprintf (stderr, "Create zoom region: \tzoom %f,%f, viewport %d,%d to %d,%d\n", (float) zx, (float) zy, viewport->x1, viewport->y1, viewport->x2, viewport->y2));
01246 
01247         /* FIXME:
01248          * shouldn't do this here, since it causes the region to get
01249          * mapped onto the parent, if if it's not explicitly added!
01250          */
01251         DBG(g_message ("creating zoom region with parent %p", magnifier));
01252         zoom_region->priv->parent = magnifier;
01253 
01254         retval = BONOBO_OBJREF (zoom_region);
01255         /* XXX: should check ev after each call, below */
01256         CORBA_exception_init (ev);
01257         GNOME_Magnifier_ZoomRegion_setMagFactor (retval, zx, zy, ev);
01258 
01259         if (ev->_major != CORBA_NO_EXCEPTION)
01260                 fprintf (stderr, "EXCEPTION setMagFactor\n");
01261 
01262         CORBA_exception_init (ev);
01263         properties = GNOME_Magnifier_ZoomRegion_getProperties (retval, ev);
01264         if (ev->_major != CORBA_NO_EXCEPTION)
01265                 fprintf (stderr, "EXCEPTION getProperties\n");
01266 
01267         viewport_any._type = TC_GNOME_Magnifier_RectBounds;
01268         viewport_any._value = (gpointer) viewport;
01269         Bonobo_PropertyBag_setValue (
01270                 properties, "viewport", &viewport_any, ev);
01271 
01272         GNOME_Magnifier_ZoomRegion_setROI (retval, roi, ev);
01273         if (ev->_major != CORBA_NO_EXCEPTION)
01274                 fprintf (stderr, "EXCEPTION setROI\n");
01275 
01276         CORBA_exception_init (ev);
01277 
01278         gtk_widget_set_size_request (magnifier->priv->canvas,
01279                            viewport->x2 - viewport->x1,
01280                            viewport->y2 - viewport->y1);
01281         gtk_widget_show (magnifier->priv->canvas);
01282         gtk_widget_show (magnifier->priv->w);
01283 
01284         bonobo_object_release_unref (properties, ev);
01285         
01286         return CORBA_Object_duplicate (retval, ev);
01287 }
01288 
01289 static
01290 CORBA_boolean
01291 impl_magnifier_add_zoom_region (PortableServer_Servant servant,
01292                                 const GNOME_Magnifier_ZoomRegion region,
01293                                 CORBA_Environment * ev)
01294 {
01295         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01296 
01297         if (!magnifier->source_initialized) 
01298         {
01299                 magnifier_set_extension_listeners (magnifier, magnifier_get_root (magnifier));
01300         }
01301 
01302         /* FIXME: this needs proper lifecycle management */
01303         magnifier->zoom_regions = g_list_append (magnifier->zoom_regions, region);
01304         gmag_gs_check_set_struts (magnifier);
01305 
01306         return CORBA_TRUE;
01307 }
01308 
01309 static Bonobo_PropertyBag
01310 impl_magnifier_get_properties (PortableServer_Servant servant,
01311                                CORBA_Environment *ev)
01312 {
01313         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01314         return bonobo_object_dup_ref (
01315                 BONOBO_OBJREF (magnifier->property_bag), ev);
01316 }
01317 
01318 GNOME_Magnifier_ZoomRegionList *
01319 impl_magnifier_get_zoom_regions (PortableServer_Servant servant,
01320                                  CORBA_Environment * ev)
01321 {
01322         Magnifier *magnifier =
01323                 MAGNIFIER (bonobo_object_from_servant (servant));
01324 
01325         GNOME_Magnifier_ZoomRegionList *list;
01326         CORBA_Object objref;
01327         int i, len;
01328 
01329         len = g_list_length (magnifier->zoom_regions);
01330         list = GNOME_Magnifier_ZoomRegionList__alloc ();
01331         list->_length = len;
01332         list->_buffer =
01333                 GNOME_Magnifier_ZoomRegionList_allocbuf (list->_length);
01334         for (i = 0; i < len; ++i) {
01335                 objref = g_list_nth_data (magnifier->zoom_regions, i);
01336                 list->_buffer [i] =
01337                         CORBA_Object_duplicate (objref, ev);
01338         }
01339         CORBA_sequence_set_release (list, CORBA_TRUE);
01340 
01341         DBG (fprintf (stderr, "Get zoom regions: \t%d\n", len));
01342         
01343         return list; 
01344 }
01345 
01346 static void
01347 impl_magnifier_clear_all_zoom_regions (PortableServer_Servant servant,
01348                                        CORBA_Environment * ev)
01349 {
01350         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01351         fprintf (stderr, "Clear all zoom regions.\n");
01352 
01353         g_list_foreach (magnifier->zoom_regions,
01354                         magnifier_unref_zoom_region, magnifier);
01355         g_list_free (magnifier->zoom_regions);
01356         magnifier->zoom_regions = NULL;
01357 }
01358 
01359 static void
01360 impl_magnifier_dispose (PortableServer_Servant servant,
01361                         CORBA_Environment *ev)
01362 {
01363         magnifier_do_dispose (
01364                 MAGNIFIER (bonobo_object_from_servant (servant)));
01365 }
01366 
01367 static void
01368 magnifier_class_init (MagnifierClass *klass)
01369 {
01370         GObjectClass * object_class = (GObjectClass *) klass;
01371         POA_GNOME_Magnifier_Magnifier__epv *epv = &klass->epv;
01372         parent_class = g_type_class_peek (BONOBO_TYPE_OBJECT); /* needed by BONOBO_CALL_PARENT! */
01373 
01374         object_class->dispose = magnifier_gobject_dispose;
01375 
01376         epv->_set_SourceDisplay = impl_magnifier_set_source_display;
01377         epv->_set_TargetDisplay = impl_magnifier_set_target_display;
01378         epv->_get_SourceDisplay = impl_magnifier_get_source_display;
01379         epv->_get_TargetDisplay = impl_magnifier_get_target_display;
01380         epv->getProperties = impl_magnifier_get_properties;
01381         epv->getZoomRegions = impl_magnifier_get_zoom_regions;
01382         epv->createZoomRegion = impl_magnifier_create_zoom_region;
01383         epv->addZoomRegion = impl_magnifier_add_zoom_region;
01384         epv->clearAllZoomRegions = impl_magnifier_clear_all_zoom_regions;
01385         epv->dispose = impl_magnifier_dispose;
01386 }
01387 
01388 static void
01389 magnifier_properties_init (Magnifier *magnifier)
01390 {
01391         BonoboArg *def;
01392         GNOME_Magnifier_RectBounds rect_bounds;
01393         gchar *display_env;
01394 
01395         magnifier->property_bag =
01396                 bonobo_property_bag_new_closure (
01397                         g_cclosure_new_object (
01398                                 G_CALLBACK (magnifier_get_property),
01399                                 G_OBJECT (magnifier)),
01400                         g_cclosure_new_object (
01401                                 G_CALLBACK (magnifier_set_property),
01402                                 G_OBJECT (magnifier)));
01403 
01404         /* Aggregate so magnifier implements Bonobo_PropertyBag */
01405         bonobo_object_add_interface (BONOBO_OBJECT (magnifier),
01406                                      BONOBO_OBJECT (magnifier->property_bag));
01407 
01408         def = bonobo_arg_new (BONOBO_ARG_STRING);
01409         display_env = getenv ("DISPLAY");
01410         BONOBO_ARG_SET_STRING (def, display_env);
01411 
01412         bonobo_property_bag_add (magnifier->property_bag,
01413                                  "source-display-screen",
01414                                  MAGNIFIER_SOURCE_DISPLAY_PROP,
01415                                  BONOBO_ARG_STRING,
01416                                  def,
01417                                  "source display screen",
01418                                  Bonobo_PROPERTY_WRITEABLE);
01419 
01420         bonobo_property_bag_add (magnifier->property_bag,
01421                                  "target-display-screen",
01422                                  MAGNIFIER_TARGET_DISPLAY_PROP,
01423                                  BONOBO_ARG_STRING,
01424                                  def,
01425                                  "target display screen",
01426                                  Bonobo_PROPERTY_WRITEABLE);
01427 
01428         bonobo_arg_release (def);
01429 
01430         magnifier_init_display (magnifier, display_env, TRUE);
01431         magnifier_init_display (magnifier, display_env, FALSE);
01432 
01433         magnifier_get_display_rect_bounds (magnifier, &rect_bounds, FALSE);
01434         def = bonobo_arg_new_from (TC_GNOME_Magnifier_RectBounds, &rect_bounds);
01435         
01436         bonobo_property_bag_add (magnifier->property_bag,
01437                                  "source-display-bounds",
01438                                  MAGNIFIER_SOURCE_SIZE_PROP,
01439                                  TC_GNOME_Magnifier_RectBounds,
01440                                  def,
01441                                  "source display bounds/size",
01442                                  Bonobo_PROPERTY_READABLE |
01443                                  Bonobo_PROPERTY_WRITEABLE);
01444         bonobo_arg_release (def);
01445         
01446         magnifier_get_display_rect_bounds (magnifier, &rect_bounds, TRUE);
01447         def = bonobo_arg_new_from (TC_GNOME_Magnifier_RectBounds, &rect_bounds);
01448 
01449         bonobo_property_bag_add (magnifier->property_bag,
01450                                  "target-display-bounds",
01451                                  MAGNIFIER_TARGET_SIZE_PROP,
01452                                  TC_GNOME_Magnifier_RectBounds,
01453                                  def,
01454                                  "target display bounds/size",
01455                                  Bonobo_PROPERTY_READABLE |
01456                                  Bonobo_PROPERTY_WRITEABLE);
01457         bonobo_arg_release (def);
01458 
01459         bonobo_property_bag_add (magnifier->property_bag,
01460                                  "cursor-set",
01461                                  MAGNIFIER_CURSOR_SET_PROP,
01462                                  BONOBO_ARG_STRING,
01463                                  NULL,
01464                                  "name of cursor set",
01465                                  Bonobo_PROPERTY_READABLE |
01466                                  Bonobo_PROPERTY_WRITEABLE);
01467 
01468         def = bonobo_arg_new (BONOBO_ARG_INT);
01469         BONOBO_ARG_SET_INT (def, 64);
01470         
01471         bonobo_property_bag_add (magnifier->property_bag,
01472                                  "cursor-size",
01473                                  MAGNIFIER_CURSOR_SIZE_PROP,
01474                                  BONOBO_ARG_INT,
01475                                  def,
01476                                  "cursor size, in pixels",
01477                                  Bonobo_PROPERTY_READABLE |
01478                                  Bonobo_PROPERTY_WRITEABLE);
01479         bonobo_arg_release (def);
01480         
01481         bonobo_property_bag_add (magnifier->property_bag,
01482                                  "cursor-scale-factor",
01483                                  MAGNIFIER_CURSOR_ZOOM_PROP,
01484                                  BONOBO_ARG_FLOAT,
01485                                  NULL,
01486                                  "scale factor for cursors (overrides size)",
01487                                  Bonobo_PROPERTY_READABLE |
01488                                  Bonobo_PROPERTY_WRITEABLE);
01489         
01490         bonobo_property_bag_add (magnifier->property_bag,
01491                                  "cursor-color",
01492                                  MAGNIFIER_CURSOR_COLOR_PROP,
01493                                  TC_CORBA_unsigned_long,
01494                                  NULL,
01495                                  "foreground color for 1-bit cursors, as ARGB",
01496                                  Bonobo_PROPERTY_READABLE |
01497                                  Bonobo_PROPERTY_WRITEABLE);    
01498 
01499         bonobo_property_bag_add (magnifier->property_bag,
01500                                  "cursor-hotspot",
01501                                  MAGNIFIER_CURSOR_HOTSPOT_PROP,
01502                                  TC_GNOME_Magnifier_Point,
01503                                  NULL,
01504                                  "hotspot relative to cursor's upper-left-corner, at default resolition",
01505                                  Bonobo_PROPERTY_READABLE |
01506                                  Bonobo_PROPERTY_WRITEABLE);
01507         
01508         bonobo_property_bag_add (magnifier->property_bag,
01509                                  "cursor-default-size",
01510                                  MAGNIFIER_CURSOR_DEFAULT_SIZE_PROP,
01511                                  BONOBO_ARG_INT,
01512                                  NULL,
01513                                  "default size of current cursor set",
01514                                  Bonobo_PROPERTY_READABLE);
01515 
01516         bonobo_property_bag_add (magnifier->property_bag,
01517                                  "crosswire-size",
01518                                  MAGNIFIER_CROSSWIRE_SIZE_PROP,
01519                                  BONOBO_ARG_INT,
01520                                  NULL,
01521                                  "thickness of crosswire cursor, in target pixels",
01522                                  Bonobo_PROPERTY_READABLE |
01523                                  Bonobo_PROPERTY_WRITEABLE);
01524         
01525         bonobo_property_bag_add (magnifier->property_bag,
01526                                  "crosswire-color",
01527                                  MAGNIFIER_CROSSWIRE_COLOR_PROP,
01528                                  BONOBO_ARG_LONG,
01529                                  NULL,
01530                                  "color of crosswire, as A-RGB; note that alpha is required. (use 0 for XOR wire)",
01531                                  Bonobo_PROPERTY_READABLE |
01532                                  Bonobo_PROPERTY_WRITEABLE);
01533 
01534         bonobo_property_bag_add (magnifier->property_bag,
01535                                  "crosswire-clip",
01536                                  MAGNIFIER_CROSSWIRE_CLIP_PROP,
01537                                  BONOBO_ARG_BOOLEAN,
01538                                  NULL,
01539                                  "whether to inset the cursor over the crosswire or not",
01540                                  Bonobo_PROPERTY_READABLE |
01541                                  Bonobo_PROPERTY_WRITEABLE);
01542 }
01543 
01544 static void
01545 magnifier_init_window (Magnifier *magnifier, GdkScreen *screen)
01546 {
01547         GtkWindowType mag_win_type = GTK_WINDOW_TOPLEVEL;
01548         if (_is_override_redirect) mag_win_type = GTK_WINDOW_POPUP;
01549 
01550         magnifier->priv->w =
01551                 g_object_connect (gtk_widget_new (gtk_window_get_type (),
01552                                                   "user_data", NULL,
01553                                                   "can_focus", FALSE,
01554                                                   "type", mag_win_type,  
01555                                                   "title", "magnifier",
01556                                                   "allow_grow", TRUE,
01557                                                   "allow_shrink", TRUE,
01558                                                   "border_width", 0,
01559                                                   NULL),
01560                                   "signal::realize", magnifier_realize, NULL,
01561                                   "signal::size_allocate", magnifier_size_allocate, NULL,
01562                                   "signal::destroy", magnifier_exit, NULL,
01563                                   NULL);
01564         gtk_window_set_screen (GTK_WINDOW (magnifier->priv->w), screen);
01565         magnifier->priv->canvas = gtk_fixed_new ();
01566         gtk_container_add (GTK_CONTAINER (magnifier->priv->w),
01567                            magnifier->priv->canvas);
01568         magnifier->priv->root = NULL;
01569 }
01570 
01571 static void
01572 magnifier_init (Magnifier *magnifier)
01573 {
01574         magnifier->priv = g_new0 (MagnifierPrivate, 1);
01575         magnifier_properties_init (magnifier);
01576         magnifier->zoom_regions = NULL;
01577         magnifier->source_screen_num = 0;
01578         magnifier->target_screen_num = 0;
01579         magnifier->source_display_name = g_strdup (":0.0");
01580         magnifier->target_display_name = g_strdup (":0.0");
01581         magnifier->cursor_size_x = 0;
01582         magnifier->cursor_size_y = 0;
01583         magnifier->cursor_scale_factor = 1.0F;
01584         magnifier->cursor_color = 0xFF000000;
01585         magnifier->crosswire_size = 1;
01586         magnifier->crosswire_color = 0;
01587         magnifier->crosswire_clip = FALSE;
01588         magnifier->cursor_hotspot.x = 0;
01589         magnifier->cursor_hotspot.y = 0;
01590         magnifier->target_bounds.x1 = 0;
01591         magnifier->target_bounds.y1 = 0;
01592         magnifier->target_bounds.x2 = 0;
01593         magnifier->target_bounds.y2 = 0;
01594         magnifier->priv->cursor = NULL;
01595         magnifier->priv->w = NULL;
01596         magnifier->priv->use_source_cursor = TRUE;
01597         magnifier->priv->cursorlist = NULL;
01598         magnifier->priv->source_drawable = NULL;
01599         magnifier->priv->overlay = NULL;
01600         magnifier_init_window (magnifier, 
01601                                gdk_display_get_screen (magnifier->target_display, 
01602                                                        magnifier->target_screen_num));
01603         magnifier_init_cursor_set (magnifier, "default");
01604 
01605         mag_timing.process = g_timer_new ();
01606         mag_timing.frame = g_timer_new ();
01607         mag_timing.scale = g_timer_new ();
01608         mag_timing.idle = g_timer_new ();
01609 #ifdef DEBUG_CLIENT_CALLS
01610         client_debug = (g_getenv ("MAG_CLIENT_DEBUG") != NULL);
01611 #endif
01612 }
01613 
01614 GdkDrawable *
01615 magnifier_get_cursor (Magnifier *magnifier)
01616 {
01617         if (magnifier->priv->cursor == NULL) {
01618             if ((fixes_event_base == 0) && 
01619                 strcmp (magnifier->cursor_set, "none")) 
01620             {
01621                 GdkPixbuf *pixbuf;
01622                 gchar *default_cursor_filename = 
01623                     g_strconcat (CURSORSDIR, "/", "default-cursor.xpm", NULL);
01624                 pixbuf = gdk_pixbuf_new_from_file (default_cursor_filename, NULL);
01625                 if (pixbuf) 
01626                 {
01627                     magnifier_set_cursor_from_pixbuf (magnifier, pixbuf);
01628                     g_object_unref (pixbuf);
01629                     magnifier_transform_cursor (magnifier);
01630                 }
01631                 g_free (default_cursor_filename);
01632             } else {
01633                 GdkPixbuf *cursor_pixbuf = gmag_cursor_get_source_pixbuf (
01634                         magnifier);
01635                 magnifier_set_cursor_from_pixbuf (magnifier, cursor_pixbuf);
01636                 if (cursor_pixbuf) g_object_unref (cursor_pixbuf);
01637                 magnifier_transform_cursor (magnifier);
01638             }
01639         }
01640         return magnifier->priv->cursor;
01641 }
01642 
01643 Magnifier *
01644 magnifier_new (gboolean override_redirect)
01645 {
01646         Magnifier *mag;
01647         MagLoginHelper *helper;
01648         int ret;
01649 
01650         _is_override_redirect = override_redirect;
01651 
01652         mag = g_object_new (magnifier_get_type(), NULL);
01653 
01654         _this_magnifier = mag; /* FIXME what about multiple instances? */
01655 
01656         helper = g_object_new (mag_login_helper_get_type (), NULL);
01657         mag_login_helper_set_magnifier (helper, mag);
01658 
01659         bonobo_object_add_interface (bonobo_object (mag), 
01660                                      BONOBO_OBJECT (helper));
01661         
01662         ret = bonobo_activation_active_server_register (
01663                 MAGNIFIER_OAFIID, BONOBO_OBJREF (mag));
01664         if (ret != Bonobo_ACTIVATION_REG_SUCCESS) {
01665             if ( ret == Bonobo_ACTIVATION_REG_ALREADY_ACTIVE)
01666             {
01667                 printf("An instance of magnifier is already active. Exiting Program.\n");
01668                 exit(0);
01669             } else
01670                 g_error ("Error registering magnifier server.\n");
01671         }
01672 
01673         g_idle_add (magnifier_reset_struts_at_idle, mag);
01674         g_idle_add (gmag_gs_reset_overlay_at_idle, mag);
01675 
01676         return mag;
01677 }
01678 
01679 BONOBO_TYPE_FUNC_FULL (Magnifier, 
01680                        GNOME_Magnifier_Magnifier,
01681                        BONOBO_TYPE_OBJECT,
01682                        magnifier)
01683 

Generated on Sun Sep 16 11:17:24 2007 for gnome-mag by  doxygen 1.4.7