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