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         BONOBO_ARG_SET_STRING (arg, display);
01149         
01150         DBG (fprintf (stderr, "Set source display: \t%s\n", display));
01151 
01152         if (strcmp (display, magnifier->source_display_name)) {
01153 
01154             magnifier_set_property (magnifier->property_bag,
01155                                     arg,
01156                                     MAGNIFIER_SOURCE_DISPLAY_PROP,
01157                                     ev,
01158                                     magnifier);
01159         }
01160         else
01161         {
01162             DBG (fprintf (stderr, "Attempt to set source to same value as previous: %s\n",
01163                           display));
01164         }
01165         bonobo_arg_release (arg);
01166 }
01167 
01168 static void
01169 impl_magnifier_set_target_display (PortableServer_Servant servant,
01170                                    const CORBA_char *display,
01171                                    CORBA_Environment *ev)
01172 {
01173         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01174         BonoboArg *arg = bonobo_arg_new (BONOBO_ARG_STRING);
01175         BONOBO_ARG_SET_STRING (arg, display);
01176         
01177         DBG (fprintf (stderr, "Set target display: \t%s\n", display));
01178 
01179         if (strcmp (display, magnifier->target_display_name)) 
01180         {
01181             magnifier_set_property (magnifier->property_bag,
01182                                     arg,
01183                                     MAGNIFIER_TARGET_DISPLAY_PROP,
01184                                     ev,
01185                                     magnifier);
01186         }
01187         else
01188         {
01189             DBG (fprintf (stderr, "Attempt to set target to same value as previous: %s\n",
01190                           display));
01191         }
01192         bonobo_arg_release (arg);
01193 }
01194 
01195 static 
01196 CORBA_string
01197 impl_magnifier_get_source_display (PortableServer_Servant servant,
01198                                    CORBA_Environment *ev)
01199 {
01200         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01201         DBG (fprintf (stderr, "Get source display: \t%s\n", magnifier->source_display_name));
01202 
01203         return CORBA_string_dup (magnifier->source_display_name ? magnifier->source_display_name : "");
01204 }
01205 
01206 static 
01207 CORBA_string
01208 impl_magnifier_get_target_display (PortableServer_Servant servant,
01209                                    CORBA_Environment *ev)
01210 {
01211         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01212         DBG (fprintf (stderr, "Get target display: \t%s\n", 
01213                       magnifier->target_display_name));
01214 
01215         return CORBA_string_dup (magnifier->target_display_name ? magnifier->target_display_name : "");
01216 }
01217 
01218 static GNOME_Magnifier_ZoomRegion
01219 impl_magnifier_create_zoom_region (PortableServer_Servant servant,
01220                                    const CORBA_float zx,
01221                                    const CORBA_float zy,
01222                                    const GNOME_Magnifier_RectBounds *roi,
01223                                    const GNOME_Magnifier_RectBounds *viewport,
01224                                    CORBA_Environment *ev)
01225 {
01226         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01227         CORBA_any viewport_any;
01228         ZoomRegion *zoom_region = zoom_region_new ();
01229         Bonobo_PropertyBag properties;
01230         GNOME_Magnifier_ZoomRegion retval;
01231 
01232         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));
01233 
01234         /* FIXME:
01235          * shouldn't do this here, since it causes the region to get
01236          * mapped onto the parent, if if it's not explicitly added!
01237          */
01238         DBG(g_message ("creating zoom region with parent %p", magnifier));
01239         zoom_region->priv->parent = magnifier;
01240 
01241         retval = BONOBO_OBJREF (zoom_region);
01242         /* XXX: should check ev after each call, below */
01243         CORBA_exception_init (ev);
01244         GNOME_Magnifier_ZoomRegion_setMagFactor (retval, zx, zy, ev);
01245 
01246         if (ev->_major != CORBA_NO_EXCEPTION)
01247                 fprintf (stderr, "EXCEPTION setMagFactor\n");
01248 
01249         CORBA_exception_init (ev);
01250         properties = GNOME_Magnifier_ZoomRegion_getProperties (retval, ev);
01251         if (ev->_major != CORBA_NO_EXCEPTION)
01252                 fprintf (stderr, "EXCEPTION getProperties\n");
01253 
01254         viewport_any._type = TC_GNOME_Magnifier_RectBounds;
01255         viewport_any._value = (gpointer) viewport;
01256         Bonobo_PropertyBag_setValue (
01257                 properties, "viewport", &viewport_any, ev);
01258 
01259         GNOME_Magnifier_ZoomRegion_setROI (retval, roi, ev);
01260         if (ev->_major != CORBA_NO_EXCEPTION)
01261                 fprintf (stderr, "EXCEPTION setROI\n");
01262 
01263         CORBA_exception_init (ev);
01264 
01265         gtk_widget_set_size_request (magnifier->priv->canvas,
01266                            viewport->x2 - viewport->x1,
01267                            viewport->y2 - viewport->y1);
01268         gtk_widget_show (magnifier->priv->canvas);
01269         gtk_widget_show (magnifier->priv->w);
01270 
01271         bonobo_object_release_unref (properties, ev);
01272         
01273         return CORBA_Object_duplicate (retval, ev);
01274 }
01275 
01276 static
01277 CORBA_boolean
01278 impl_magnifier_add_zoom_region (PortableServer_Servant servant,
01279                                 const GNOME_Magnifier_ZoomRegion region,
01280                                 CORBA_Environment * ev)
01281 {
01282         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01283 
01284         if (!magnifier->source_initialized) 
01285         {
01286                 magnifier_set_extension_listeners (magnifier, magnifier_get_root (magnifier));
01287         }
01288 
01289         /* FIXME: this needs proper lifecycle management */
01290         magnifier->zoom_regions = g_list_append (magnifier->zoom_regions, region);
01291         gmag_gs_check_set_struts (magnifier);
01292 
01293         return CORBA_TRUE;
01294 }
01295 
01296 static Bonobo_PropertyBag
01297 impl_magnifier_get_properties (PortableServer_Servant servant,
01298                                CORBA_Environment *ev)
01299 {
01300         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01301         return bonobo_object_dup_ref (
01302                 BONOBO_OBJREF (magnifier->property_bag), ev);
01303 }
01304 
01305 GNOME_Magnifier_ZoomRegionList *
01306 impl_magnifier_get_zoom_regions (PortableServer_Servant servant,
01307                                  CORBA_Environment * ev)
01308 {
01309         Magnifier *magnifier =
01310                 MAGNIFIER (bonobo_object_from_servant (servant));
01311 
01312         GNOME_Magnifier_ZoomRegionList *list;
01313         CORBA_Object objref;
01314         int i, len;
01315 
01316         len = g_list_length (magnifier->zoom_regions);
01317         list = GNOME_Magnifier_ZoomRegionList__alloc ();
01318         list->_length = len;
01319         list->_buffer =
01320                 GNOME_Magnifier_ZoomRegionList_allocbuf (list->_length);
01321         for (i = 0; i < len; ++i) {
01322                 objref = g_list_nth_data (magnifier->zoom_regions, i);
01323                 list->_buffer [i] =
01324                         CORBA_Object_duplicate (objref, ev);
01325         }
01326         CORBA_sequence_set_release (list, CORBA_TRUE);
01327 
01328         DBG (fprintf (stderr, "Get zoom regions: \t%d\n", len));
01329         
01330         return list; 
01331 }
01332 
01333 static void
01334 impl_magnifier_clear_all_zoom_regions (PortableServer_Servant servant,
01335                                        CORBA_Environment * ev)
01336 {
01337         Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant));
01338         fprintf (stderr, "Clear all zoom regions.\n");
01339 
01340         g_list_foreach (magnifier->zoom_regions,
01341                         magnifier_unref_zoom_region, magnifier);
01342         g_list_free (magnifier->zoom_regions);
01343         magnifier->zoom_regions = NULL;
01344 }
01345 
01346 static void
01347 impl_magnifier_dispose (PortableServer_Servant servant,
01348                         CORBA_Environment *ev)
01349 {
01350         magnifier_do_dispose (
01351                 MAGNIFIER (bonobo_object_from_servant (servant)));
01352 }
01353 
01354 static void
01355 magnifier_class_init (MagnifierClass *klass)
01356 {
01357         GObjectClass * object_class = (GObjectClass *) klass;
01358         POA_GNOME_Magnifier_Magnifier__epv *epv = &klass->epv;
01359         parent_class = g_type_class_peek (BONOBO_TYPE_OBJECT); /* needed by BONOBO_CALL_PARENT! */
01360 
01361         object_class->dispose = magnifier_gobject_dispose;
01362 
01363         epv->_set_SourceDisplay = impl_magnifier_set_source_display;
01364         epv->_set_TargetDisplay = impl_magnifier_set_target_display;
01365         epv->_get_SourceDisplay = impl_magnifier_get_source_display;
01366         epv->_get_TargetDisplay = impl_magnifier_get_target_display;
01367         epv->getProperties = impl_magnifier_get_properties;
01368         epv->getZoomRegions = impl_magnifier_get_zoom_regions;
01369         epv->createZoomRegion = impl_magnifier_create_zoom_region;
01370         epv->addZoomRegion = impl_magnifier_add_zoom_region;
01371         epv->clearAllZoomRegions = impl_magnifier_clear_all_zoom_regions;
01372         epv->dispose = impl_magnifier_dispose;
01373 }
01374 
01375 static void
01376 magnifier_properties_init (Magnifier *magnifier)
01377 {
01378         BonoboArg *def;
01379         GNOME_Magnifier_RectBounds rect_bounds;
01380         gchar *display_env;
01381 
01382         magnifier->property_bag =
01383                 bonobo_property_bag_new_closure (
01384                         g_cclosure_new_object (
01385                                 G_CALLBACK (magnifier_get_property),
01386                                 G_OBJECT (magnifier)),
01387                         g_cclosure_new_object (
01388                                 G_CALLBACK (magnifier_set_property),
01389                                 G_OBJECT (magnifier)));
01390 
01391         /* Aggregate so magnifier implements Bonobo_PropertyBag */
01392         bonobo_object_add_interface (BONOBO_OBJECT (magnifier),
01393                                      BONOBO_OBJECT (magnifier->property_bag));
01394 
01395         def = bonobo_arg_new (BONOBO_ARG_STRING);
01396         display_env = getenv ("DISPLAY");
01397         BONOBO_ARG_SET_STRING (def, display_env);
01398 
01399         bonobo_property_bag_add (magnifier->property_bag,
01400                                  "source-display-screen",
01401                                  MAGNIFIER_SOURCE_DISPLAY_PROP,
01402                                  BONOBO_ARG_STRING,
01403                                  def,
01404                                  "source display screen",
01405                                  Bonobo_PROPERTY_WRITEABLE);
01406 
01407         bonobo_property_bag_add (magnifier->property_bag,
01408                                  "target-display-screen",
01409                                  MAGNIFIER_TARGET_DISPLAY_PROP,
01410                                  BONOBO_ARG_STRING,
01411                                  def,
01412                                  "target display screen",
01413                                  Bonobo_PROPERTY_WRITEABLE);
01414 
01415         bonobo_arg_release (def);
01416 
01417         magnifier_init_display (magnifier, display_env, TRUE);
01418         magnifier_init_display (magnifier, display_env, FALSE);
01419 
01420         magnifier_get_display_rect_bounds (magnifier, &rect_bounds, FALSE);
01421         def = bonobo_arg_new_from (TC_GNOME_Magnifier_RectBounds, &rect_bounds);
01422         
01423         bonobo_property_bag_add (magnifier->property_bag,
01424                                  "source-display-bounds",
01425                                  MAGNIFIER_SOURCE_SIZE_PROP,
01426                                  TC_GNOME_Magnifier_RectBounds,
01427                                  def,
01428                                  "source display bounds/size",
01429                                  Bonobo_PROPERTY_READABLE |
01430                                  Bonobo_PROPERTY_WRITEABLE);
01431         bonobo_arg_release (def);
01432         
01433         magnifier_get_display_rect_bounds (magnifier, &rect_bounds, TRUE);
01434         def = bonobo_arg_new_from (TC_GNOME_Magnifier_RectBounds, &rect_bounds);
01435 
01436         bonobo_property_bag_add (magnifier->property_bag,
01437                                  "target-display-bounds",
01438                                  MAGNIFIER_TARGET_SIZE_PROP,
01439                                  TC_GNOME_Magnifier_RectBounds,
01440                                  def,
01441                                  "target display bounds/size",
01442                                  Bonobo_PROPERTY_READABLE |
01443                                  Bonobo_PROPERTY_WRITEABLE);
01444         bonobo_arg_release (def);
01445 
01446         bonobo_property_bag_add (magnifier->property_bag,
01447                                  "cursor-set",
01448                                  MAGNIFIER_CURSOR_SET_PROP,
01449                                  BONOBO_ARG_STRING,
01450                                  NULL,
01451                                  "name of cursor set",
01452                                  Bonobo_PROPERTY_READABLE |
01453                                  Bonobo_PROPERTY_WRITEABLE);
01454 
01455         def = bonobo_arg_new (BONOBO_ARG_INT);
01456         BONOBO_ARG_SET_INT (def, 64);
01457         
01458         bonobo_property_bag_add (magnifier->property_bag,
01459                                  "cursor-size",
01460                                  MAGNIFIER_CURSOR_SIZE_PROP,
01461                                  BONOBO_ARG_INT,
01462                                  def,
01463                                  "cursor size, in pixels",
01464                                  Bonobo_PROPERTY_READABLE |
01465                                  Bonobo_PROPERTY_WRITEABLE);
01466         bonobo_arg_release (def);
01467         
01468         bonobo_property_bag_add (magnifier->property_bag,
01469                                  "cursor-scale-factor",
01470                                  MAGNIFIER_CURSOR_ZOOM_PROP,
01471                                  BONOBO_ARG_FLOAT,
01472                                  NULL,
01473                                  "scale factor for cursors (overrides size)",
01474                                  Bonobo_PROPERTY_READABLE |
01475                                  Bonobo_PROPERTY_WRITEABLE);
01476         
01477         bonobo_property_bag_add (magnifier->property_bag,
01478                                  "cursor-color",
01479                                  MAGNIFIER_CURSOR_COLOR_PROP,
01480                                  TC_CORBA_unsigned_long,
01481                                  NULL,
01482                                  "foreground color for 1-bit cursors, as ARGB",
01483                                  Bonobo_PROPERTY_READABLE |
01484                                  Bonobo_PROPERTY_WRITEABLE);    
01485 
01486         bonobo_property_bag_add (magnifier->property_bag,
01487                                  "cursor-hotspot",
01488                                  MAGNIFIER_CURSOR_HOTSPOT_PROP,
01489                                  TC_GNOME_Magnifier_Point,
01490                                  NULL,
01491                                  "hotspot relative to cursor's upper-left-corner, at default resolition",
01492                                  Bonobo_PROPERTY_READABLE |
01493                                  Bonobo_PROPERTY_WRITEABLE);
01494         
01495         bonobo_property_bag_add (magnifier->property_bag,
01496                                  "cursor-default-size",
01497                                  MAGNIFIER_CURSOR_DEFAULT_SIZE_PROP,
01498                                  BONOBO_ARG_INT,
01499                                  NULL,
01500                                  "default size of current cursor set",
01501                                  Bonobo_PROPERTY_READABLE);
01502 
01503         bonobo_property_bag_add (magnifier->property_bag,
01504                                  "crosswire-size",
01505                                  MAGNIFIER_CROSSWIRE_SIZE_PROP,
01506                                  BONOBO_ARG_INT,
01507                                  NULL,
01508                                  "thickness of crosswire cursor, in target pixels",
01509                                  Bonobo_PROPERTY_READABLE |
01510                                  Bonobo_PROPERTY_WRITEABLE);
01511         
01512         bonobo_property_bag_add (magnifier->property_bag,
01513                                  "crosswire-color",
01514                                  MAGNIFIER_CROSSWIRE_COLOR_PROP,
01515                                  BONOBO_ARG_LONG,
01516                                  NULL,
01517                                  "color of crosswire, as A-RGB; note that alpha is required. (use 0 for XOR wire)",
01518                                  Bonobo_PROPERTY_READABLE |
01519                                  Bonobo_PROPERTY_WRITEABLE);
01520 
01521         bonobo_property_bag_add (magnifier->property_bag,
01522                                  "crosswire-clip",
01523                                  MAGNIFIER_CROSSWIRE_CLIP_PROP,
01524                                  BONOBO_ARG_BOOLEAN,
01525                                  NULL,
01526                                  "whether to inset the cursor over the crosswire or not",
01527                                  Bonobo_PROPERTY_READABLE |
01528                                  Bonobo_PROPERTY_WRITEABLE);
01529 }
01530 
01531 static void
01532 magnifier_init_window (Magnifier *magnifier, GdkScreen *screen)
01533 {
01534         GtkWindowType mag_win_type = GTK_WINDOW_TOPLEVEL;
01535         if (_is_override_redirect) mag_win_type = GTK_WINDOW_POPUP;
01536 
01537         magnifier->priv->w =
01538                 g_object_connect (gtk_widget_new (gtk_window_get_type (),
01539                                                   "user_data", NULL,
01540                                                   "can_focus", FALSE,
01541                                                   "type", mag_win_type,  
01542                                                   "title", "magnifier",
01543                                                   "allow_grow", TRUE,
01544                                                   "allow_shrink", TRUE,
01545                                                   "border_width", 0,
01546                                                   NULL),
01547                                   "signal::realize", magnifier_realize, NULL,
01548                                   "signal::size_allocate", magnifier_size_allocate, NULL,
01549                                   "signal::destroy", magnifier_exit, NULL,
01550                                   NULL);
01551         gtk_window_set_screen (GTK_WINDOW (magnifier->priv->w), screen);
01552         magnifier->priv->canvas = gtk_fixed_new ();
01553         gtk_container_add (GTK_CONTAINER (magnifier->priv->w),
01554                            magnifier->priv->canvas);
01555         magnifier->priv->root = NULL;
01556 }
01557 
01558 static void
01559 magnifier_init (Magnifier *magnifier)
01560 {
01561         magnifier->priv = g_new0 (MagnifierPrivate, 1);
01562         magnifier_properties_init (magnifier);
01563         magnifier->zoom_regions = NULL;
01564         magnifier->source_screen_num = 0;
01565         magnifier->target_screen_num = 0;
01566         magnifier->source_display_name = g_strdup (":0.0");
01567         magnifier->target_display_name = g_strdup (":0.0");
01568         magnifier->cursor_size_x = 0;
01569         magnifier->cursor_size_y = 0;
01570         magnifier->cursor_scale_factor = 1.0F;
01571         magnifier->cursor_color = 0xFF000000;
01572         magnifier->crosswire_size = 1;
01573         magnifier->crosswire_color = 0;
01574         magnifier->crosswire_clip = FALSE;
01575         magnifier->cursor_hotspot.x = 0;
01576         magnifier->cursor_hotspot.y = 0;
01577         magnifier->target_bounds.x1 = 0;
01578         magnifier->target_bounds.y1 = 0;
01579         magnifier->target_bounds.x2 = 0;
01580         magnifier->target_bounds.y2 = 0;
01581         magnifier->priv->cursor = NULL;
01582         magnifier->priv->w = NULL;
01583         magnifier->priv->use_source_cursor = TRUE;
01584         magnifier->priv->cursorlist = NULL;
01585         magnifier->priv->source_drawable = NULL;
01586         magnifier->priv->overlay = NULL;
01587         magnifier_init_window (magnifier, 
01588                                gdk_display_get_screen (magnifier->target_display, 
01589                                                        magnifier->target_screen_num));
01590         magnifier_init_cursor_set (magnifier, "default");
01591 
01592         mag_timing.process = g_timer_new ();
01593         mag_timing.frame = g_timer_new ();
01594         mag_timing.scale = g_timer_new ();
01595         mag_timing.idle = g_timer_new ();
01596 #ifdef DEBUG_CLIENT_CALLS
01597         client_debug = (g_getenv ("MAG_CLIENT_DEBUG") != NULL);
01598 #endif
01599 }
01600 
01601 GdkDrawable *
01602 magnifier_get_cursor (Magnifier *magnifier)
01603 {
01604         if (magnifier->priv->cursor == NULL) {
01605             if ((fixes_event_base == 0) && 
01606                 strcmp (magnifier->cursor_set, "none")) 
01607             {
01608                 GdkPixbuf *pixbuf;
01609                 gchar *default_cursor_filename = 
01610                     g_strconcat (CURSORSDIR, "/", "default-cursor.xpm", NULL);
01611                 pixbuf = gdk_pixbuf_new_from_file (default_cursor_filename, NULL);
01612                 if (pixbuf) 
01613                 {
01614                     magnifier_set_cursor_from_pixbuf (magnifier, pixbuf);
01615                     g_object_unref (pixbuf);
01616                     magnifier_transform_cursor (magnifier);
01617                 }
01618                 g_free (default_cursor_filename);
01619             } else {
01620                 GdkPixbuf *cursor_pixbuf = gmag_cursor_get_source_pixbuf (
01621                         magnifier);
01622                 magnifier_set_cursor_from_pixbuf (magnifier, cursor_pixbuf);
01623                 if (cursor_pixbuf) g_object_unref (cursor_pixbuf);
01624                 magnifier_transform_cursor (magnifier);
01625             }
01626         }
01627         return magnifier->priv->cursor;
01628 }
01629 
01630 Magnifier *
01631 magnifier_new (gboolean override_redirect)
01632 {
01633         Magnifier *mag;
01634         MagLoginHelper *helper;
01635         int ret;
01636 
01637         _is_override_redirect = override_redirect;
01638 
01639         mag = g_object_new (magnifier_get_type(), NULL);
01640 
01641         _this_magnifier = mag; /* FIXME what about multiple instances? */
01642 
01643         helper = g_object_new (mag_login_helper_get_type (), NULL);
01644         mag_login_helper_set_magnifier (helper, mag);
01645 
01646         bonobo_object_add_interface (bonobo_object (mag), 
01647                                      BONOBO_OBJECT (helper));
01648         
01649         ret = bonobo_activation_active_server_register (
01650                 MAGNIFIER_OAFIID, BONOBO_OBJREF (mag));
01651         if (ret != Bonobo_ACTIVATION_REG_SUCCESS) {
01652                 if ( ret == Bonobo_ACTIVATION_REG_ALREADY_ACTIVE) {
01653                         printf("An instance of magnifier is already active. " \
01654                                "Exiting Program.\n");
01655                         exit(0);
01656                 }
01657                 else
01658                         g_error ("Error registering magnifier server.\n");
01659         }
01660 
01661         g_idle_add (magnifier_reset_struts_at_idle, mag);
01662         g_idle_add (gmag_gs_reset_overlay_at_idle, mag);
01663 
01664         return mag;
01665 }
01666 
01667 BONOBO_TYPE_FUNC_FULL (Magnifier, 
01668                        GNOME_Magnifier_Magnifier,
01669                        BONOBO_TYPE_OBJECT,
01670                        magnifier)
01671 

Generated on Tue Apr 24 15:39:22 2007 for gnome-mag by  doxygen 1.5.1