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 
00947                     /* remove the source_drawable, since in the new display the
00948                      * composite can be unavailable and the source_drawable is
00949                      * where the desktop screen is composed. If this is not
00950                      * freed it will be used even if the display doesn't use
00951                      * composite what will lead to wrong behavior and crashes.
00952                      * If composite is used in the new display this variable is
00953                      * re-created */
00954                     if (magnifier->priv->source_drawable) {
00955                             g_object_unref (magnifier->priv->source_drawable);
00956                             magnifier->priv->source_drawable = NULL;
00957                     }
00958 
00959                     /* If the COMPOSITE extension was not available in the
00960                      * previous display the MAGNIFIER_IGNORE_COMPOSITE
00961                      * variable is setted. We must unset it to be sure that we
00962                      * will make use of this extension if it's present in the
00963                      * new display.
00964                      */
00965                     g_unsetenv ("MAGNIFIER_IGNORE_COMPOSITE");
00966 
00967                     /* attach listeners for DAMAGE, "dirty region", XFIXES
00968                      * cursor changes */
00969                     magnifier_set_extension_listeners (magnifier, magnifier_get_root (magnifier));
00970                     magnifier_get_display_rect_bounds (magnifier, &magnifier->source_bounds, FALSE);
00971                     magnifier_zoom_regions_restore (magnifier, zoom_region_params);
00972                     magnifier_warp_cursor_to_screen (magnifier);
00973                     gmag_gs_check_set_struts (magnifier);
00974                 }
00975                 DBG(fprintf (stderr, "Set source display: \t%s\n", full_display_string));
00976                 break;
00977         case MAGNIFIER_TARGET_DISPLAY_PROP:
00978                 full_display_string = BONOBO_ARG_GET_STRING (arg);
00979                 if (can_open_display (full_display_string))
00980                 {
00981                     magnifier->target_screen_num =
00982                         magnifier_parse_display_name (magnifier,
00983                                                       full_display_string,
00984                                                       NULL);
00985                     magnifier->target_display =
00986                         gdk_display_open (full_display_string);
00987                     magnifier->target_display_name = g_strdup (full_display_string);
00988                     if (GTK_IS_WINDOW (magnifier->priv->w)) 
00989                     {
00990 #ifdef REPARENT_GTK_WINDOW_WORKS
00991                         gtk_window_set_screen (GTK_WINDOW (magnifier->priv->w), 
00992                                                gdk_display_get_screen (
00993                                                    magnifier->target_display,
00994                                                    magnifier->target_screen_num));
00995 #else
00996                         GSList *zoom_region_params = NULL;
00997                         /* disconnect from the old window's destroy signal */
00998                         g_object_disconnect (magnifier->priv->w,
00999                                   "any_signal::realize", magnifier_realize, NULL,
01000                                   "any_signal::size_allocate", magnifier_size_allocate, NULL,
01001                                   "any_signal::destroy", magnifier_exit, NULL,
01002                                   NULL);
01003                         /* save the old zoom region state */
01004                         zoom_region_params = magnifier_zoom_regions_save (magnifier);
01005                         /* destroy the old window */
01006                         gtk_widget_destroy (magnifier->priv->w);
01007                         /* and re-initialize... */
01008                         magnifier_init_window (magnifier, gdk_display_get_screen (
01009                                                    magnifier->target_display,
01010                                                    magnifier->target_screen_num));
01011                         /* restore the zoom regions in their new host magnifier window */
01012                         magnifier_zoom_regions_restore (magnifier, zoom_region_params);
01013 #endif
01014                     }
01015                     magnifier_get_display_rect_bounds (magnifier, &magnifier->source_bounds, FALSE);
01016                     magnifier_init_cursor_set (magnifier, magnifier->cursor_set); /* needed to reset pixmaps */
01017                     if (magnifier->priv->overlay)
01018                             gdk_window_move (magnifier->priv->overlay,
01019                                              magnifier->target_bounds.x1,
01020                                              magnifier->target_bounds.y1);
01021                     else
01022                             gtk_window_move (GTK_WINDOW (magnifier->priv->w),
01023                                              magnifier->target_bounds.x1,
01024                                              magnifier->target_bounds.y1);
01025                     
01026                     if ((magnifier->target_bounds.x2 - magnifier->target_bounds.x1 > 0) &&
01027                         (magnifier->target_bounds.y2 - magnifier->target_bounds.y1) > 0)
01028                     {
01029                             if (magnifier->priv->overlay)
01030                                     gdk_window_resize (
01031                                             magnifier->priv->overlay,
01032                                             magnifier->target_bounds.x2 -
01033                                             magnifier->target_bounds.x1,
01034                                             magnifier->target_bounds.y2 -
01035                                             magnifier->target_bounds.y1);
01036                         gtk_window_resize (GTK_WINDOW (magnifier->priv->w),
01037                                        magnifier->target_bounds.x2 - magnifier->target_bounds.x1,
01038                                        magnifier->target_bounds.y2 - magnifier->target_bounds.y1);
01039                     DBG(fprintf (stderr, "Set target size: \t%d,%d to %d,%d\n", 
01040                              magnifier->target_bounds.x1, magnifier->target_bounds.y1, magnifier->target_bounds.x2, magnifier->target_bounds.y2));
01041                     }
01042                     /* N. B. we don't reset the target bounds to the limits of the new display, because */
01043                     /* doing so would override the client-specified magnifier size */
01044                     /* magnifier_get_display_rect_bounds (magnifier, &magnifier->target_bounds, TRUE); */
01045                     gmag_gs_check_set_struts (magnifier);
01046                 }
01047                 DBG(fprintf (stderr, "Set target display: \t%s (screen %d)\n", 
01048                               full_display_string, magnifier->target_screen_num));
01049                 break;
01050         case MAGNIFIER_SOURCE_SIZE_PROP:
01051                 magnifier->source_bounds = BONOBO_ARG_GET_GENERAL (arg,
01052                                                                    TC_GNOME_Magnifier_RectBounds,
01053                                                                    GNOME_Magnifier_RectBounds,
01054                                                                    NULL);
01055                 DBG (fprintf (stderr, "Set source size: \t%d,%d to %d,%d\n", 
01056                               magnifier->source_bounds.x1, magnifier->source_bounds.y1, magnifier->source_bounds.x2, magnifier->source_bounds.y2));
01057                 break;
01058         case MAGNIFIER_TARGET_SIZE_PROP:
01059                 magnifier->target_bounds = BONOBO_ARG_GET_GENERAL (arg,
01060                                                                    TC_GNOME_Magnifier_RectBounds,
01061                                                                    GNOME_Magnifier_RectBounds,
01062                                 
01063                                    NULL);
01064                 if (magnifier->priv->overlay)
01065                         gdk_window_move_resize (magnifier->priv->overlay,
01066                                                 magnifier->target_bounds.x1,
01067                                                 magnifier->target_bounds.y1,
01068                                                 magnifier->target_bounds.x2 -
01069                                                 magnifier->target_bounds.x1,
01070                                                 magnifier->target_bounds.y2 -
01071                                                 magnifier->target_bounds.y1);
01072                 else
01073                         gtk_window_move (GTK_WINDOW (magnifier->priv->w),
01074                                          magnifier->target_bounds.x1,
01075                                          magnifier->target_bounds.y1);
01076                 
01077                 gtk_window_resize (GTK_WINDOW (magnifier->priv->w),
01078                                    magnifier->target_bounds.x2 - magnifier->target_bounds.x1,
01079                                    magnifier->target_bounds.y2 - magnifier->target_bounds.y1);
01080                 gmag_gs_check_set_struts (magnifier);
01081                 DBG(fprintf (stderr, "Set target size: \t%d,%d to %d,%d\n", 
01082                               magnifier->target_bounds.x1, magnifier->target_bounds.y1, magnifier->target_bounds.x2, magnifier->target_bounds.y2));
01083                 if (!strcmp (magnifier->target_display_name, magnifier->source_display_name) && 
01084                     (magnifier->target_screen_num == magnifier->source_screen_num)) 
01085                     magnifier_adjust_source_size (magnifier);
01086                 break;
01087         case MAGNIFIER_CURSOR_SET_PROP:
01088                 magnifier_init_cursor_set (magnifier, g_strdup (BONOBO_ARG_GET_STRING (arg)));
01089                 DBG (fprintf (stderr, "Setting cursor set: \t%s\n", BONOBO_ARG_GET_STRING (arg)));
01090                 break;
01091         case MAGNIFIER_CURSOR_SIZE_PROP:
01092                 magnifier->cursor_size_x = BONOBO_ARG_GET_INT (arg);
01093                 magnifier->cursor_size_y = BONOBO_ARG_GET_INT (arg);
01094                 magnifier_transform_cursor (magnifier);
01095                 DBG (fprintf (stderr, "Setting cursor size: \t%d\n", magnifier->cursor_size_x));
01096                 break;
01097         case MAGNIFIER_CURSOR_ZOOM_PROP:
01098                 magnifier->cursor_scale_factor = BONOBO_ARG_GET_FLOAT (arg);
01099                 DBG (fprintf (stderr, "Setting cursor scale factor: \t%f\n", (float) magnifier->cursor_scale_factor));
01100                 magnifier_transform_cursor (magnifier);
01101                 break;
01102         case MAGNIFIER_CURSOR_COLOR_PROP:
01103                 magnifier->cursor_color = BONOBO_ARG_GET_GENERAL (arg,
01104                                                                   TC_CORBA_unsigned_long, 
01105                                                                   CORBA_unsigned_long, 
01106                                                                   NULL);
01107                 magnifier_transform_cursor (magnifier);
01108                 DBG (fprintf (stderr, "Setting cursor color: \t%u\n", (unsigned) magnifier->cursor_color));
01109                 break;
01110         case MAGNIFIER_CURSOR_HOTSPOT_PROP:
01111                 magnifier->cursor_hotspot = BONOBO_ARG_GET_GENERAL (arg,
01112                                                                     TC_GNOME_Magnifier_Point,
01113                                                                     GNOME_Magnifier_Point,
01114                                                                     NULL);
01115                 /* TODO: notify zoomers */
01116                 /* FIXME: don't call init_cursor, it overwrites this property! */
01117                 magnifier_transform_cursor (magnifier); 
01118                 break;
01119         case MAGNIFIER_CURSOR_DEFAULT_SIZE_PROP:
01120                 bonobo_exception_set (ev, ex_Bonobo_PropertyBag_ReadOnly);
01121                 break;
01122         case MAGNIFIER_CROSSWIRE_SIZE_PROP:
01123                 magnifier->crosswire_size = BONOBO_ARG_GET_INT (arg);
01124                 DBG (fprintf (stderr, "Setting crosswire size: \t%d\n", magnifier->crosswire_size));
01125                 /* TODO: notify zoomers */
01126                 break;
01127         case MAGNIFIER_CROSSWIRE_CLIP_PROP:
01128                 magnifier->crosswire_clip = BONOBO_ARG_GET_BOOLEAN (arg);
01129                 DBG (fprintf (stderr, "Setting crosswire clip: \t%s\n", magnifier->crosswire_clip ? "true" : "false"));
01130                 break;
01131         case MAGNIFIER_CROSSWIRE_COLOR_PROP:
01132                 magnifier->crosswire_color = BONOBO_ARG_GET_LONG (arg);
01133                 DBG (fprintf (stderr, "Setting crosswire size: \t%ld\n", (long) magnifier->crosswire_color));
01134                 break;
01135         default:
01136                 bonobo_exception_set (ev, ex_Bonobo_PropertyBag_NotFound);
01137                 break;
01138         };
01139 }
01140 
01141 static void
01142 magnifier_do_dispose (Magnifier *magnifier)
01143 {
01144         /* FIXME: this is dead ropey code structuring */
01145         bonobo_activation_active_server_unregister (
01146                 MAGNIFIER_OAFIID, BONOBO_OBJREF (magnifier));
01147 
01148         if (magnifier->zoom_regions)
01149                 g_list_free (magnifier->zoom_regions);
01150         magnifier->zoom_regions = NULL;
01151         
01152         bonobo_main_quit ();
01153 }
01154 
01155 static void
01156 magnifier_gobject_dispose (GObject *object)
01157 {
01158         magnifier_do_dispose (MAGNIFIER (object));
01159 
01160         BONOBO_CALL_PARENT (G_OBJECT_CLASS, dispose, (object));
01161 }
01162 
01163 static void
01164 impl_magnifier_set_source_display (PortableServer_Servant servant,
01165                                    const CORBA_char *display,
01166                                    CORBA_Environment *ev)
01167 {
01168         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01169         BonoboArg *arg = bonobo_arg_new (BONOBO_ARG_STRING);
01170         gchar *full_display_string;
01171 
01172         full_display_string = g_strdup (display);
01173         if (strcmp (full_display_string, "") == 0)
01174                 full_display_string = (gchar *) g_getenv ("DISPLAY");
01175 
01176         BONOBO_ARG_SET_STRING (arg, full_display_string);
01177         
01178         DBG (fprintf (stderr, "Set source display: \t%s\n",
01179                       full_display_string));
01180 
01181         if (strcmp (full_display_string, magnifier->source_display_name)) {
01182             magnifier_set_property (magnifier->property_bag,
01183                                     arg,
01184                                     MAGNIFIER_SOURCE_DISPLAY_PROP,
01185                                     ev,
01186                                     magnifier);
01187         }
01188         else
01189         {
01190             DBG (fprintf (stderr, "Attempt to set source to same value as previous: %s\n",
01191                           full_display_string));
01192         }
01193         bonobo_arg_release (arg);
01194 }
01195 
01196 static void
01197 impl_magnifier_set_target_display (PortableServer_Servant servant,
01198                                    const CORBA_char *display,
01199                                    CORBA_Environment *ev)
01200 {
01201         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01202         BonoboArg *arg = bonobo_arg_new (BONOBO_ARG_STRING);
01203         gchar *full_display_string;
01204 
01205         full_display_string = g_strdup (display);
01206         if (strcmp (full_display_string, "") == 0)
01207                 full_display_string = (gchar *) g_getenv ("DISPLAY");
01208 
01209         BONOBO_ARG_SET_STRING (arg, full_display_string);
01210         
01211         DBG (fprintf (stderr, "Set target display: \t%s\n",
01212                       full_display_string));
01213 
01214         if (strcmp (full_display_string, magnifier->target_display_name)) 
01215         {
01216             magnifier_set_property (magnifier->property_bag,
01217                                     arg,
01218                                     MAGNIFIER_TARGET_DISPLAY_PROP,
01219                                     ev,
01220                                     magnifier);
01221         }
01222         else
01223         {
01224             DBG (fprintf (stderr, "Attempt to set target to same value as previous: %s\n",
01225                           full_display_string));
01226         }
01227         bonobo_arg_release (arg);
01228 }
01229 
01230 static 
01231 CORBA_string
01232 impl_magnifier_get_source_display (PortableServer_Servant servant,
01233                                    CORBA_Environment *ev)
01234 {
01235         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01236         DBG (fprintf (stderr, "Get source display: \t%s\n", magnifier->source_display_name));
01237 
01238         return CORBA_string_dup (magnifier->source_display_name ? magnifier->source_display_name : "");
01239 }
01240 
01241 static 
01242 CORBA_string
01243 impl_magnifier_get_target_display (PortableServer_Servant servant,
01244                                    CORBA_Environment *ev)
01245 {
01246         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01247         DBG (fprintf (stderr, "Get target display: \t%s\n", 
01248                       magnifier->target_display_name));
01249 
01250         return CORBA_string_dup (magnifier->target_display_name ? magnifier->target_display_name : "");
01251 }
01252 
01253 static GNOME_Magnifier_ZoomRegion
01254 impl_magnifier_create_zoom_region (PortableServer_Servant servant,
01255                                    const CORBA_float zx,
01256                                    const CORBA_float zy,
01257                                    const GNOME_Magnifier_RectBounds *roi,
01258                                    const GNOME_Magnifier_RectBounds *viewport,
01259                                    CORBA_Environment *ev)
01260 {
01261         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01262         CORBA_any viewport_any;
01263         ZoomRegion *zoom_region = zoom_region_new ();
01264         Bonobo_PropertyBag properties;
01265         GNOME_Magnifier_ZoomRegion retval;
01266 
01267         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));
01268 
01269         /* FIXME:
01270          * shouldn't do this here, since it causes the region to get
01271          * mapped onto the parent, if if it's not explicitly added!
01272          */
01273         DBG(g_message ("creating zoom region with parent %p", magnifier));
01274         zoom_region->priv->parent = magnifier;
01275 
01276         retval = BONOBO_OBJREF (zoom_region);
01277 
01278         /* XXX: should check ev after each call, below */
01279         CORBA_exception_init (ev);
01280         GNOME_Magnifier_ZoomRegion_setMagFactor (retval, zx, zy, ev);
01281 
01282         if (ev->_major != CORBA_NO_EXCEPTION)
01283                 fprintf (stderr, "EXCEPTION setMagFactor\n");
01284 
01285         CORBA_exception_init (ev);
01286         properties = GNOME_Magnifier_ZoomRegion_getProperties (retval, ev);
01287         if (ev->_major != CORBA_NO_EXCEPTION)
01288                 fprintf (stderr, "EXCEPTION getProperties\n");
01289 
01290         viewport_any._type = TC_GNOME_Magnifier_RectBounds;
01291         viewport_any._value = (gpointer) viewport;
01292         Bonobo_PropertyBag_setValue (
01293                 properties, "viewport", &viewport_any, ev);
01294 
01295         GNOME_Magnifier_ZoomRegion_setROI (retval, roi, ev);
01296         if (ev->_major != CORBA_NO_EXCEPTION)
01297                 fprintf (stderr, "EXCEPTION setROI\n");
01298 
01299         CORBA_exception_init (ev);
01300 
01301         gtk_widget_set_size_request (magnifier->priv->canvas,
01302                            viewport->x2 - viewport->x1,
01303                            viewport->y2 - viewport->y1);
01304         gtk_widget_show (magnifier->priv->canvas);
01305         gtk_widget_show (magnifier->priv->w);
01306 
01307         bonobo_object_release_unref (properties, ev);
01308         
01309         return CORBA_Object_duplicate (retval, ev);
01310 }
01311 
01312 static
01313 CORBA_boolean
01314 impl_magnifier_add_zoom_region (PortableServer_Servant servant,
01315                                 const GNOME_Magnifier_ZoomRegion region,
01316                                 CORBA_Environment * ev)
01317 {
01318         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01319 
01320         if (!magnifier->source_initialized) 
01321         {
01322                 magnifier_set_extension_listeners (magnifier, magnifier_get_root (magnifier));
01323         }
01324 
01325         /* FIXME: this needs proper lifecycle management */
01326         magnifier->zoom_regions = g_list_append (magnifier->zoom_regions, region);
01327         gmag_gs_check_set_struts (magnifier);
01328 
01329         return CORBA_TRUE;
01330 }
01331 
01332 static Bonobo_PropertyBag
01333 impl_magnifier_get_properties (PortableServer_Servant servant,
01334                                CORBA_Environment *ev)
01335 {
01336         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01337         return bonobo_object_dup_ref (
01338                 BONOBO_OBJREF (magnifier->property_bag), ev);
01339 }
01340 
01341 GNOME_Magnifier_ZoomRegionList *
01342 impl_magnifier_get_zoom_regions (PortableServer_Servant servant,
01343                                  CORBA_Environment * ev)
01344 {
01345         Magnifier *magnifier =
01346                 MAGNIFIER (bonobo_object_from_servant (servant));
01347 
01348         GNOME_Magnifier_ZoomRegionList *list;
01349         CORBA_Object objref;
01350         int i, len;
01351 
01352         len = g_list_length (magnifier->zoom_regions);
01353         list = GNOME_Magnifier_ZoomRegionList__alloc ();
01354         list->_length = len;
01355         list->_buffer =
01356                 GNOME_Magnifier_ZoomRegionList_allocbuf (list->_length);
01357         for (i = 0; i < len; ++i) {
01358                 objref = g_list_nth_data (magnifier->zoom_regions, i);
01359                 list->_buffer [i] =
01360                         CORBA_Object_duplicate (objref, ev);
01361         }
01362         CORBA_sequence_set_release (list, CORBA_TRUE);
01363 
01364         DBG (fprintf (stderr, "Get zoom regions: \t%d\n", len));
01365         
01366         return list; 
01367 }
01368 
01369 static void
01370 impl_magnifier_clear_all_zoom_regions (PortableServer_Servant servant,
01371                                        CORBA_Environment * ev)
01372 {
01373         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01374         fprintf (stderr, "Clear all zoom regions.\n");
01375 
01376         g_list_foreach (magnifier->zoom_regions,
01377                         magnifier_unref_zoom_region, magnifier);
01378         g_list_free (magnifier->zoom_regions);
01379         magnifier->zoom_regions = NULL;
01380 }
01381 
01382 static void
01383 impl_magnifier_dispose (PortableServer_Servant servant,
01384                         CORBA_Environment *ev)
01385 {
01386         magnifier_do_dispose (
01387                 MAGNIFIER (bonobo_object_from_servant (servant)));
01388 }
01389 
01390 static void
01391 magnifier_class_init (MagnifierClass *klass)
01392 {
01393         GObjectClass * object_class = (GObjectClass *) klass;
01394         POA_GNOME_Magnifier_Magnifier__epv *epv = &klass->epv;
01395         parent_class = g_type_class_peek (BONOBO_TYPE_OBJECT); /* needed by BONOBO_CALL_PARENT! */
01396 
01397         object_class->dispose = magnifier_gobject_dispose;
01398 
01399         epv->_set_SourceDisplay = impl_magnifier_set_source_display;
01400         epv->_set_TargetDisplay = impl_magnifier_set_target_display;
01401         epv->_get_SourceDisplay = impl_magnifier_get_source_display;
01402         epv->_get_TargetDisplay = impl_magnifier_get_target_display;
01403         epv->getProperties = impl_magnifier_get_properties;
01404         epv->getZoomRegions = impl_magnifier_get_zoom_regions;
01405         epv->createZoomRegion = impl_magnifier_create_zoom_region;
01406         epv->addZoomRegion = impl_magnifier_add_zoom_region;
01407         epv->clearAllZoomRegions = impl_magnifier_clear_all_zoom_regions;
01408         epv->dispose = impl_magnifier_dispose;
01409 }
01410 
01411 static void
01412 magnifier_properties_init (Magnifier *magnifier)
01413 {
01414         BonoboArg *def;
01415         GNOME_Magnifier_RectBounds rect_bounds;
01416         gchar *display_env;
01417 
01418         magnifier->property_bag =
01419                 bonobo_property_bag_new_closure (
01420                         g_cclosure_new_object (
01421                                 G_CALLBACK (magnifier_get_property),
01422                                 G_OBJECT (magnifier)),
01423                         g_cclosure_new_object (
01424                                 G_CALLBACK (magnifier_set_property),
01425                                 G_OBJECT (magnifier)));
01426 
01427         /* Aggregate so magnifier implements Bonobo_PropertyBag */
01428         bonobo_object_add_interface (BONOBO_OBJECT (magnifier),
01429                                      BONOBO_OBJECT (magnifier->property_bag));
01430 
01431         def = bonobo_arg_new (BONOBO_ARG_STRING);
01432         display_env = getenv ("DISPLAY");
01433         BONOBO_ARG_SET_STRING (def, display_env);
01434 
01435         bonobo_property_bag_add (magnifier->property_bag,
01436                                  "source-display-screen",
01437                                  MAGNIFIER_SOURCE_DISPLAY_PROP,
01438                                  BONOBO_ARG_STRING,
01439                                  def,
01440                                  "source display screen",
01441                                  Bonobo_PROPERTY_WRITEABLE);
01442 
01443         bonobo_property_bag_add (magnifier->property_bag,
01444                                  "target-display-screen",
01445                                  MAGNIFIER_TARGET_DISPLAY_PROP,
01446                                  BONOBO_ARG_STRING,
01447                                  def,
01448                                  "target display screen",
01449                                  Bonobo_PROPERTY_WRITEABLE);
01450 
01451         bonobo_arg_release (def);
01452 
01453         magnifier_init_display (magnifier, display_env, TRUE);
01454         magnifier_init_display (magnifier, display_env, FALSE);
01455 
01456         magnifier_get_display_rect_bounds (magnifier, &rect_bounds, FALSE);
01457         def = bonobo_arg_new_from (TC_GNOME_Magnifier_RectBounds, &rect_bounds);
01458         
01459         bonobo_property_bag_add (magnifier->property_bag,
01460                                  "source-display-bounds",
01461                                  MAGNIFIER_SOURCE_SIZE_PROP,
01462                                  TC_GNOME_Magnifier_RectBounds,
01463                                  def,
01464                                  "source display bounds/size",
01465                                  Bonobo_PROPERTY_READABLE |
01466                                  Bonobo_PROPERTY_WRITEABLE);
01467         bonobo_arg_release (def);
01468         
01469         magnifier_get_display_rect_bounds (magnifier, &rect_bounds, TRUE);
01470         def = bonobo_arg_new_from (TC_GNOME_Magnifier_RectBounds, &rect_bounds);
01471 
01472         bonobo_property_bag_add (magnifier->property_bag,
01473                                  "target-display-bounds",
01474                                  MAGNIFIER_TARGET_SIZE_PROP,
01475                                  TC_GNOME_Magnifier_RectBounds,
01476                                  def,
01477                                  "target display bounds/size",
01478                                  Bonobo_PROPERTY_READABLE |
01479                                  Bonobo_PROPERTY_WRITEABLE);
01480         bonobo_arg_release (def);
01481 
01482         bonobo_property_bag_add (magnifier->property_bag,
01483                                  "cursor-set",
01484                                  MAGNIFIER_CURSOR_SET_PROP,
01485                                  BONOBO_ARG_STRING,
01486                                  NULL,
01487                                  "name of cursor set",
01488                                  Bonobo_PROPERTY_READABLE |
01489                                  Bonobo_PROPERTY_WRITEABLE);
01490 
01491         def = bonobo_arg_new (BONOBO_ARG_INT);
01492         BONOBO_ARG_SET_INT (def, 64);
01493         
01494         bonobo_property_bag_add (magnifier->property_bag,
01495                                  "cursor-size",
01496                                  MAGNIFIER_CURSOR_SIZE_PROP,
01497                                  BONOBO_ARG_INT,
01498                                  def,
01499                                  "cursor size, in pixels",
01500                                  Bonobo_PROPERTY_READABLE |
01501                                  Bonobo_PROPERTY_WRITEABLE);
01502         bonobo_arg_release (def);
01503         
01504         bonobo_property_bag_add (magnifier->property_bag,
01505                                  "cursor-scale-factor",
01506                                  MAGNIFIER_CURSOR_ZOOM_PROP,
01507                                  BONOBO_ARG_FLOAT,
01508                                  NULL,
01509                                  "scale factor for cursors (overrides size)",
01510                                  Bonobo_PROPERTY_READABLE |
01511                                  Bonobo_PROPERTY_WRITEABLE);
01512         
01513         bonobo_property_bag_add (magnifier->property_bag,
01514                                  "cursor-color",
01515                                  MAGNIFIER_CURSOR_COLOR_PROP,
01516                                  TC_CORBA_unsigned_long,
01517                                  NULL,
01518                                  "foreground color for 1-bit cursors, as ARGB",
01519                                  Bonobo_PROPERTY_READABLE |
01520                                  Bonobo_PROPERTY_WRITEABLE);    
01521 
01522         bonobo_property_bag_add (magnifier->property_bag,
01523                                  "cursor-hotspot",
01524                                  MAGNIFIER_CURSOR_HOTSPOT_PROP,
01525                                  TC_GNOME_Magnifier_Point,
01526                                  NULL,
01527                                  "hotspot relative to cursor's upper-left-corner, at default resolition",
01528                                  Bonobo_PROPERTY_READABLE |
01529                                  Bonobo_PROPERTY_WRITEABLE);
01530         
01531         bonobo_property_bag_add (magnifier->property_bag,
01532                                  "cursor-default-size",
01533                                  MAGNIFIER_CURSOR_DEFAULT_SIZE_PROP,
01534                                  BONOBO_ARG_INT,
01535                                  NULL,
01536                                  "default size of current cursor set",
01537                                  Bonobo_PROPERTY_READABLE);
01538 
01539         bonobo_property_bag_add (magnifier->property_bag,
01540                                  "crosswire-size",
01541                                  MAGNIFIER_CROSSWIRE_SIZE_PROP,
01542                                  BONOBO_ARG_INT,
01543                                  NULL,
01544                                  "thickness of crosswire cursor, in target pixels",
01545                                  Bonobo_PROPERTY_READABLE |
01546                                  Bonobo_PROPERTY_WRITEABLE);
01547         
01548         bonobo_property_bag_add (magnifier->property_bag,
01549                                  "crosswire-color",
01550                                  MAGNIFIER_CROSSWIRE_COLOR_PROP,
01551                                  BONOBO_ARG_LONG,
01552                                  NULL,
01553                                  "color of crosswire, as A-RGB; note that alpha is required. (use 0 for XOR wire)",
01554                                  Bonobo_PROPERTY_READABLE |
01555                                  Bonobo_PROPERTY_WRITEABLE);
01556 
01557         bonobo_property_bag_add (magnifier->property_bag,
01558                                  "crosswire-clip",
01559                                  MAGNIFIER_CROSSWIRE_CLIP_PROP,
01560                                  BONOBO_ARG_BOOLEAN,
01561                                  NULL,
01562                                  "whether to inset the cursor over the crosswire or not",
01563                                  Bonobo_PROPERTY_READABLE |
01564                                  Bonobo_PROPERTY_WRITEABLE);
01565 }
01566 
01567 static void
01568 magnifier_init_window (Magnifier *magnifier, GdkScreen *screen)
01569 {
01570         GtkWindowType mag_win_type = GTK_WINDOW_TOPLEVEL;
01571         if (_is_override_redirect) mag_win_type = GTK_WINDOW_POPUP;
01572 
01573         magnifier->priv->w =
01574                 g_object_connect (gtk_widget_new (gtk_window_get_type (),
01575                                                   "user_data", NULL,
01576                                                   "can_focus", FALSE,
01577                                                   "type", mag_win_type,  
01578                                                   "title", "magnifier",
01579                                                   "allow_grow", TRUE,
01580                                                   "allow_shrink", TRUE,
01581                                                   "border_width", 0,
01582                                                   NULL),
01583                                   "signal::realize", magnifier_realize, NULL,
01584                                   "signal::size_allocate", magnifier_size_allocate, NULL,
01585                                   "signal::destroy", magnifier_exit, NULL,
01586                                   NULL);
01587         gtk_window_set_screen (GTK_WINDOW (magnifier->priv->w), screen);
01588         magnifier->priv->canvas = gtk_fixed_new ();
01589         gtk_container_add (GTK_CONTAINER (magnifier->priv->w),
01590                            magnifier->priv->canvas);
01591         magnifier->priv->root = NULL;
01592 }
01593 
01594 static void
01595 magnifier_init (Magnifier *magnifier)
01596 {
01597         magnifier->priv = g_new0 (MagnifierPrivate, 1);
01598         magnifier_properties_init (magnifier);
01599         magnifier->zoom_regions = NULL;
01600         magnifier->source_screen_num = 0;
01601         magnifier->target_screen_num = 0;
01602         magnifier->source_display_name = g_strdup (":0.0");
01603         magnifier->target_display_name = g_strdup (":0.0");
01604         magnifier->cursor_size_x = 0;
01605         magnifier->cursor_size_y = 0;
01606         magnifier->cursor_scale_factor = 1.0F;
01607         magnifier->cursor_color = 0xFF000000;
01608         magnifier->crosswire_size = 1;
01609         magnifier->crosswire_color = 0;
01610         magnifier->crosswire_clip = FALSE;
01611         magnifier->cursor_hotspot.x = 0;
01612         magnifier->cursor_hotspot.y = 0;
01613         magnifier->target_bounds.x1 = 0;
01614         magnifier->target_bounds.y1 = 0;
01615         magnifier->target_bounds.x2 = 0;
01616         magnifier->target_bounds.y2 = 0;
01617         magnifier->priv->cursor = NULL;
01618         magnifier->priv->w = NULL;
01619         magnifier->priv->use_source_cursor = TRUE;
01620         magnifier->priv->cursorlist = NULL;
01621         magnifier->priv->source_drawable = NULL;
01622         magnifier->priv->overlay = NULL;
01623         magnifier_init_window (magnifier, 
01624                                gdk_display_get_screen (magnifier->target_display, 
01625                                                        magnifier->target_screen_num));
01626         magnifier_init_cursor_set (magnifier, "default");
01627 
01628         mag_timing.process = g_timer_new ();
01629         mag_timing.frame = g_timer_new ();
01630         mag_timing.scale = g_timer_new ();
01631         mag_timing.idle = g_timer_new ();
01632 #ifdef DEBUG_CLIENT_CALLS
01633         client_debug = (g_getenv ("MAG_CLIENT_DEBUG") != NULL);
01634 #endif
01635 }
01636 
01637 GdkDrawable *
01638 magnifier_get_cursor (Magnifier *magnifier)
01639 {
01640         if (magnifier->priv->cursor == NULL) {
01641             if ((fixes_event_base == 0) && 
01642                 strcmp (magnifier->cursor_set, "none")) 
01643             {
01644                 GdkPixbuf *pixbuf;
01645                 gchar *default_cursor_filename = 
01646                     g_strconcat (CURSORSDIR, "/", "default-cursor.xpm", NULL);
01647                 pixbuf = gdk_pixbuf_new_from_file (default_cursor_filename, NULL);
01648                 if (pixbuf) 
01649                 {
01650                     magnifier_set_cursor_from_pixbuf (magnifier, pixbuf);
01651                     g_object_unref (pixbuf);
01652                     magnifier_transform_cursor (magnifier);
01653                 }
01654                 g_free (default_cursor_filename);
01655             } else {
01656                 GdkPixbuf *cursor_pixbuf = gmag_cursor_get_source_pixbuf (
01657                         magnifier);
01658                 magnifier_set_cursor_from_pixbuf (magnifier, cursor_pixbuf);
01659                 if (cursor_pixbuf) g_object_unref (cursor_pixbuf);
01660                 magnifier_transform_cursor (magnifier);
01661             }
01662         }
01663         return magnifier->priv->cursor;
01664 }
01665 
01666 Magnifier *
01667 magnifier_new (gboolean override_redirect)
01668 {
01669         Magnifier *mag;
01670         MagLoginHelper *helper;
01671         int ret;
01672 
01673         _is_override_redirect = override_redirect;
01674 
01675         mag = g_object_new (magnifier_get_type(), NULL);
01676 
01677         _this_magnifier = mag; /* FIXME what about multiple instances? */
01678 
01679         helper = g_object_new (mag_login_helper_get_type (), NULL);
01680         mag_login_helper_set_magnifier (helper, mag);
01681 
01682         bonobo_object_add_interface (bonobo_object (mag), 
01683                                      BONOBO_OBJECT (helper));
01684         
01685         ret = bonobo_activation_active_server_register (
01686                 MAGNIFIER_OAFIID, BONOBO_OBJREF (mag));
01687         if (ret != Bonobo_ACTIVATION_REG_SUCCESS) {
01688             if ( ret == Bonobo_ACTIVATION_REG_ALREADY_ACTIVE)
01689             {
01690                 printf("An instance of magnifier is already active. Exiting Program.\n");
01691                 exit(0);
01692             } else
01693                 g_error ("Error registering magnifier server.\n");
01694         }
01695 
01696         g_timeout_add (500, magnifier_reset_struts_at_idle, mag);
01697         g_timeout_add (500, gmag_gs_reset_overlay_at_idle, mag);
01698 
01699         return mag;
01700 }
01701 
01702 BONOBO_TYPE_FUNC_FULL (Magnifier, 
01703                        GNOME_Magnifier_Magnifier,
01704                        BONOBO_TYPE_OBJECT,
01705                        magnifier)
01706 

Generated on Sat Jan 12 14:30:52 2008 for gnome-mag by  doxygen 1.5.2