gnome-mag
|
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 #include "magnifier-server.h" 00032 00033 #include <stdlib.h> 00034 #include <string.h> 00035 #include <strings.h> 00036 00037 #include <libbonobo.h> 00038 #include <login-helper/login-helper.h> 00039 00040 #include <dbus/dbus-glib-bindings.h> 00041 00042 #include <gdk-pixbuf/gdk-pixbuf.h> 00043 #include <gdk/gdkx.h> 00044 #include <gdk/gdk.h> 00045 #include <gtk/gtk.h> 00046 00047 /* if you #define this, don't forget to set MAG_CLIENT_DEBUG env variable */ 00048 #define DEBUG_CLIENT_CALLS 00049 00050 #ifdef DEBUG_CLIENT_CALLS 00051 static gboolean client_debug = FALSE; 00052 #define DBG(a) if (client_debug) { (a); } 00053 #else 00054 #define DBG(a) 00055 #endif 00056 00057 typedef struct 00058 { 00059 LoginHelper parent; 00060 Magnifier *mag; 00061 } MagLoginHelper; 00062 00063 typedef struct 00064 { 00065 LoginHelperClass parent_class; 00066 } MagLoginHelperClass; 00067 00068 static GObjectClass *parent_class = NULL; 00069 00070 enum { 00071 MAGNIFIER_SOURCE_DISPLAY_PROP, 00072 MAGNIFIER_TARGET_DISPLAY_PROP, 00073 MAGNIFIER_SOURCE_SIZE_PROP, 00074 MAGNIFIER_TARGET_SIZE_PROP, 00075 MAGNIFIER_CURSOR_SET_PROP, 00076 MAGNIFIER_CURSOR_SIZE_PROP, 00077 MAGNIFIER_CURSOR_ZOOM_PROP, 00078 MAGNIFIER_CURSOR_COLOR_PROP, 00079 MAGNIFIER_CURSOR_HOTSPOT_PROP, 00080 MAGNIFIER_CURSOR_DEFAULT_SIZE_PROP, 00081 MAGNIFIER_CROSSWIRE_SIZE_PROP, 00082 MAGNIFIER_CROSSWIRE_LENGTH_PROP, 00083 MAGNIFIER_CROSSWIRE_CLIP_PROP, 00084 MAGNIFIER_CROSSWIRE_COLOR_PROP 00085 } PropIdx; 00086 00087 typedef struct 00088 { 00089 GNOME_Magnifier_RectBounds rectbounds; 00090 RectBounds dbus_rectbounds; 00091 GNOME_Magnifier_RectBounds viewport; 00092 RectBounds dbus_viewport; 00093 gboolean is_managed; 00094 gint scroll_policy; 00095 gfloat contrast; 00096 gfloat zx; 00097 gfloat zy; 00098 gint32 xalign; 00099 gint32 yalign; 00100 guint32 border_color; 00101 gint32 border_size; 00102 gchar *smoothing_type; 00103 gboolean inverse; 00104 } MagnifierZoomRegionSaveProps; 00105 00106 #ifdef DEBUG_CLIENT_CALLS 00107 gchar* mag_prop_names[MAGNIFIER_CROSSWIRE_COLOR_PROP + 1] = { 00108 "SOURCE_DISPLAY", 00109 "TARGET_DISPLAY", 00110 "SOURCE_SIZE", 00111 "TARGET_SIZE", 00112 "CURSOR_SET", 00113 "CURSOR_SIZE", 00114 "CURSOR_ZOOM", 00115 "CURSOR_COLOR", 00116 "CURSOR_HOTSPOT", 00117 "CURSOR_DEFAULT_SIZE", 00118 "CROSSWIRE_SIZE", 00119 "CROSSWIRE_LENGTH", 00120 "CROSSWIRE_CLIP", 00121 "CROSSWIRE_COLOR" 00122 }; 00123 #endif 00124 00125 static Magnifier *_this_magnifier = NULL; 00126 extern gint fixes_event_base; 00127 00128 static void magnifier_init_cursor_set (Magnifier *magnifier, gchar *cursor_set); 00129 static void magnifier_init_window (Magnifier *magnifier, GdkScreen *screen); 00130 static gboolean magnifier_reset_struts_at_idle (gpointer data); 00131 static void magnifier_init_window (Magnifier *magnifier, GdkScreen *screen); 00132 static void magnifier_adjust_source_size (Magnifier *magnifier); 00133 static gboolean _is_override_redirect = FALSE; 00134 00135 static GHashTable *zoom_hash = NULL; 00136 00137 static Window* 00138 mag_login_helper_get_raise_windows (LoginHelper *helper) 00139 { 00140 Window *mainwin = NULL; 00141 MagLoginHelper *mag_helper = (MagLoginHelper *) helper; 00142 Magnifier *magnifier = MAGNIFIER (mag_helper->mag); 00143 00144 if (magnifier && magnifier->priv && magnifier->priv->w) 00145 { 00146 mainwin = g_new0 (Window, 2); 00147 mainwin[0] = GDK_WINDOW_XWINDOW (gtk_widget_get_window (magnifier->priv->w)); 00148 mainwin[1] = None; 00149 } 00150 return mainwin; 00151 } 00152 00153 static LoginHelperDeviceReqFlags 00154 mag_login_helper_get_device_reqs (LoginHelper *helper) 00155 { 00156 /* means "don't grab the xserver or core pointer", 00157 and "we need to raise windows" */ 00158 return LOGIN_HELPER_GUI_EVENTS | 00159 LOGIN_HELPER_POST_WINDOWS | 00160 LOGIN_HELPER_CORE_POINTER; 00161 } 00162 00163 static gboolean 00164 mag_login_helper_set_safe (LoginHelper *helper, gboolean ignored) 00165 { 00166 return TRUE; 00167 } 00168 00169 static void 00170 mag_login_helper_class_init (MagLoginHelperClass *klass) 00171 { 00172 LoginHelperClass *login_helper_class = LOGIN_HELPER_CLASS(klass); 00173 login_helper_class->get_raise_windows = mag_login_helper_get_raise_windows; 00174 login_helper_class->get_device_reqs = mag_login_helper_get_device_reqs; 00175 login_helper_class->set_safe = mag_login_helper_set_safe; 00176 } 00177 00178 static void 00179 mag_login_helper_init (MagLoginHelper *helper) 00180 { 00181 helper->mag = NULL; /* we set this with mag_login_helper_set_magnifier */ 00182 } 00183 00184 static void 00185 mag_login_helper_set_magnifier (MagLoginHelper *helper, Magnifier *mag) 00186 { 00187 if (helper) 00188 helper->mag = mag; 00189 } 00190 00191 BONOBO_TYPE_FUNC (MagLoginHelper, 00192 LOGIN_HELPER_TYPE, 00193 mag_login_helper) 00194 00195 static gboolean 00196 can_open_display (gchar *display_name) 00197 { 00198 Display *d; 00199 if ((d = XOpenDisplay (display_name))) 00200 { 00201 XCloseDisplay (d); 00202 return TRUE; 00203 } 00204 return FALSE; 00205 } 00206 00207 static void 00208 magnifier_warp_cursor_to_screen (Magnifier *magnifier) 00209 { 00210 int x, y, unused_x, unused_y; 00211 unsigned int mask; 00212 Window root_return, child_return; 00213 00214 if (magnifier->source_display) 00215 { 00216 if (!XQueryPointer (GDK_DISPLAY_XDISPLAY (magnifier->source_display), 00217 GDK_WINDOW_XWINDOW (magnifier->priv->root), 00218 &root_return, 00219 &child_return, 00220 &x, &y, 00221 &unused_x, &unused_y, 00222 &mask)) 00223 { 00224 XWarpPointer (GDK_DISPLAY_XDISPLAY (magnifier->source_display), 00225 None, 00226 GDK_WINDOW_XWINDOW (magnifier->priv->root), 00227 0, 0, 0, 0, 00228 x, y); 00229 XSync (GDK_DISPLAY_XDISPLAY (magnifier->source_display), FALSE); 00230 } 00231 } 00232 } 00233 00234 void 00235 magnifier_zoom_regions_update_pointer (Magnifier *magnifier) 00236 { 00237 GList *list; 00238 00239 g_assert (magnifier); 00240 00241 list = magnifier->zoom_regions; 00242 while (list) { 00243 /* propagate the expose events to the zoom regions */ 00244 GNOME_Magnifier_ZoomRegion zoom_region; 00245 CORBA_Environment ev; 00246 zoom_region = list->data; 00247 CORBA_exception_init (&ev); 00248 if (zoom_region) 00249 GNOME_Magnifier_ZoomRegion_updatePointer ( 00250 CORBA_Object_duplicate (zoom_region, &ev), &ev); 00251 list = g_list_next (list); 00252 } 00253 } 00254 00255 static void 00256 magnifier_zoom_regions_mark_dirty (Magnifier *magnifier, GNOME_Magnifier_RectBounds rect_bounds) 00257 { 00258 GList *list; 00259 00260 g_assert (magnifier); 00261 00262 list = magnifier->zoom_regions; 00263 while (list) 00264 { 00265 /* propagate the expose events to the zoom regions */ 00266 GNOME_Magnifier_ZoomRegion zoom_region; 00267 CORBA_Environment ev; 00268 zoom_region = list->data; 00269 CORBA_exception_init (&ev); 00270 if (zoom_region) 00271 GNOME_Magnifier_ZoomRegion_markDirty (CORBA_Object_duplicate (zoom_region, &ev), 00272 &rect_bounds, 00273 &ev); 00274 list = g_list_next (list); 00275 } 00276 } 00277 00278 void 00279 magnifier_set_cursor_from_pixbuf (Magnifier *magnifier, 00280 GdkPixbuf *cursor_pixbuf) 00281 { 00282 GdkPixmap *pixmap, *mask; 00283 gint width, height; 00284 GdkGC *gc; 00285 GdkDrawable *drawable = gtk_widget_get_window (magnifier->priv->w); 00286 00287 if (magnifier->priv->cursor) { 00288 g_object_unref (magnifier->priv->cursor); 00289 magnifier->priv->cursor = NULL; 00290 } 00291 if (drawable && cursor_pixbuf) { 00292 const gchar *xhot_string = NULL, *yhot_string = NULL; 00293 width = gdk_pixbuf_get_width (cursor_pixbuf); 00294 height = gdk_pixbuf_get_height (cursor_pixbuf); 00295 pixmap = gdk_pixmap_new (drawable, width, height, -1); 00296 gc = gdk_gc_new (pixmap); 00297 if (GDK_IS_DRAWABLE (pixmap)) 00298 gdk_draw_pixbuf (pixmap, gc, cursor_pixbuf, 0, 0, 0, 0, 00299 width, height, GDK_RGB_DITHER_NONE, 00300 0, 0); 00301 else 00302 DBG (g_warning ("empty cursor pixmap created.")); 00303 mask = gdk_pixmap_new (drawable, width, height, 1); 00304 gdk_pixbuf_render_threshold_alpha (cursor_pixbuf, mask, 00305 0, 0, 0, 0, 00306 width, height, 00307 200); 00308 g_object_unref (gc); 00309 magnifier->priv->cursor = pixmap; 00310 magnifier->priv->cursor_mask = mask; 00311 00312 xhot_string = g_object_get_data (G_OBJECT(cursor_pixbuf), "x_hot"); 00313 yhot_string = g_object_get_data (G_OBJECT(cursor_pixbuf), "y_hot"); 00314 00315 if (xhot_string) 00316 magnifier->cursor_hotspot.x = atoi (xhot_string); 00317 if (yhot_string) 00318 magnifier->cursor_hotspot.y = atoi (yhot_string); 00319 if (pixmap) { 00320 gdk_drawable_get_size ( 00321 pixmap, 00322 &magnifier->priv->cursor_default_size_x, 00323 &magnifier->priv->cursor_default_size_y); 00324 magnifier->priv->cursor_hotspot_x = 00325 magnifier->cursor_hotspot.x; 00326 magnifier->priv->cursor_hotspot_y = 00327 magnifier->cursor_hotspot.y; 00328 } 00329 } 00330 } 00331 00332 00333 GdkPixbuf * 00334 magnifier_get_pixbuf_for_name (Magnifier *magnifier, const gchar *cursor_name) 00335 { 00336 GdkPixbuf *retval = NULL; 00337 if (magnifier->priv->cursorlist) 00338 retval = g_hash_table_lookup (magnifier->priv->cursorlist, cursor_name); 00339 if (retval) 00340 g_object_ref (retval); 00341 return retval; 00342 } 00343 00344 void 00345 magnifier_set_cursor_pixmap_by_name (Magnifier *magnifier, 00346 const gchar *cursor_name, 00347 gboolean source_fallback) 00348 { 00349 GdkPixbuf *pixbuf; 00350 /* search local table; if not found, use source screen's cursor if source_fallback is TRUE */ 00351 if ((pixbuf = magnifier_get_pixbuf_for_name (magnifier, cursor_name)) == NULL) { 00352 if (source_fallback == TRUE) 00353 { 00354 pixbuf = gmag_cursor_get_source_pixbuf (magnifier); 00355 } 00356 else 00357 { 00358 pixbuf = magnifier_get_pixbuf_for_name (magnifier, "default"); 00359 } 00360 } 00361 magnifier_set_cursor_from_pixbuf (magnifier, pixbuf); 00362 if (pixbuf) g_object_unref (pixbuf); 00363 } 00364 00365 void 00366 magnifier_notify_damage (Magnifier *magnifier, GdkRectangle *rect) 00367 { 00368 GNOME_Magnifier_RectBounds rect_bounds; 00369 rect_bounds.x1 = rect->x; 00370 rect_bounds.y1 = rect->y; 00371 rect_bounds.x2 = rect->x + rect->width; 00372 rect_bounds.y2 = rect->y + rect->height; 00373 #undef DEBUG_DAMAGE 00374 #ifdef DEBUG_DAMAGE 00375 g_message ("damage"); 00376 g_message ("dirty %d, %d to %d, %d", rect_bounds.x1, rect_bounds.y1, 00377 rect_bounds.x2, rect_bounds.y2); 00378 #endif 00379 magnifier_zoom_regions_mark_dirty (magnifier, rect_bounds); 00380 } 00381 00382 static void 00383 magnifier_set_extension_listeners (Magnifier *magnifier, GdkWindow *root) 00384 { 00385 gmag_gs_client_init (magnifier); 00386 magnifier->source_initialized = TRUE; 00387 } 00388 00389 static void 00390 magnifier_size_allocate (GtkWidget *widget) 00391 { 00392 gmag_gs_check_set_struts (_this_magnifier); 00393 } 00394 00395 static void 00396 magnifier_realize (GtkWidget *widget) 00397 { 00398 gmag_gs_magnifier_realize (widget); 00399 } 00400 00401 GdkWindow* 00402 magnifier_get_root (Magnifier *magnifier) 00403 { 00404 if (!magnifier->priv->root && magnifier->source_display) { 00405 magnifier->priv->root = gdk_screen_get_root_window ( 00406 gdk_display_get_screen (magnifier->source_display, 00407 magnifier->source_screen_num)); 00408 } 00409 return magnifier->priv->root; 00410 } 00411 00412 static gint 00413 magnifier_parse_display_name (Magnifier *magnifier, gchar *full_display_string, 00414 gchar **display_name) 00415 { 00416 gchar *screen_ptr; 00417 gchar **strings; 00418 00419 if (display_name != NULL) { 00420 strings = g_strsplit (full_display_string, ":", 2); 00421 *display_name = strings [0]; 00422 if (strings [1] != NULL) 00423 g_free (strings [1]); 00424 } 00425 00426 screen_ptr = rindex (full_display_string, '.'); 00427 if (screen_ptr != NULL) { 00428 return (gint) strtol (++screen_ptr, NULL, 10); 00429 } 00430 return 0; 00431 } 00432 00433 static void 00434 magnifier_get_display_rect_bounds (Magnifier *magnifier, GNOME_Magnifier_RectBounds *rect_bounds, gboolean is_target) 00435 { 00436 if (is_target) 00437 { 00438 rect_bounds->x1 = 0; 00439 rect_bounds->x2 = gdk_screen_get_width ( 00440 gdk_display_get_screen (magnifier->target_display, 00441 magnifier->target_screen_num)); 00442 rect_bounds->y1 = 0; 00443 rect_bounds->y2 = gdk_screen_get_height ( 00444 gdk_display_get_screen (magnifier->target_display, 00445 magnifier->target_screen_num)); 00446 00447 } 00448 else 00449 { 00450 rect_bounds->x1 = 0; 00451 rect_bounds->x2 = gdk_screen_get_width ( 00452 gdk_display_get_screen (magnifier->source_display, 00453 magnifier->source_screen_num)); 00454 rect_bounds->y1 = 0; 00455 rect_bounds->y2 = gdk_screen_get_height ( 00456 gdk_display_get_screen (magnifier->source_display, 00457 magnifier->source_screen_num)); 00458 00459 } 00460 } 00461 00462 gboolean 00463 magnifier_full_screen_capable (Magnifier *magnifier) 00464 { 00465 if ((strcmp (magnifier->source_display_name, 00466 magnifier->target_display_name) != 0) || 00467 gmag_gs_use_compositor (magnifier)) 00468 return TRUE; 00469 00470 return FALSE; 00471 } 00472 00473 static void 00474 magnifier_adjust_source_size (Magnifier *magnifier) 00475 { 00476 GNOME_Magnifier_RectBounds rect_bounds; 00477 gdouble vfract_top, vfract_bottom, hfract_left, hfract_right; 00478 00479 magnifier_get_display_rect_bounds (magnifier, &rect_bounds, FALSE); 00480 00481 hfract_left = (double) (magnifier->target_bounds.x1) / 00482 (double) rect_bounds.x2; 00483 vfract_top = (double) (magnifier->target_bounds.y1) / 00484 (double) rect_bounds.y2; 00485 hfract_right = (double) (rect_bounds.x2 - 00486 magnifier->target_bounds.x2) / 00487 (double) rect_bounds.x2; 00488 vfract_bottom = (double) (rect_bounds.y2 - 00489 magnifier->target_bounds.y2) / 00490 (double) rect_bounds.y2; 00491 00492 if (magnifier_full_screen_capable (magnifier)) { 00493 /* we make our 'source' rectangle the largest available subsection which we aren't occupying */ 00494 magnifier->source_bounds = rect_bounds; 00495 } else if (MAX (hfract_left, hfract_right) > 00496 MAX (vfract_top, vfract_bottom)) { /* vertical split, 00497 * approximately */ 00498 if (hfract_right > hfract_left) { 00499 magnifier->source_bounds.x1 = 00500 magnifier->target_bounds.x2; 00501 magnifier->source_bounds.x2 = rect_bounds.x2; 00502 } else { 00503 magnifier->source_bounds.x1 = rect_bounds.x1; 00504 magnifier->source_bounds.x2 = 00505 magnifier->target_bounds.x1; 00506 } 00507 magnifier->source_bounds.y1 = rect_bounds.y1; 00508 magnifier->source_bounds.y2 = rect_bounds.y2; 00509 } else { /* more-or-less horizontally split */ 00510 if (vfract_bottom > vfract_top) { 00511 magnifier->source_bounds.y1 = 00512 magnifier->target_bounds.y2; 00513 magnifier->source_bounds.y2 = rect_bounds.y2; 00514 } else { 00515 magnifier->source_bounds.y1 = rect_bounds.y1; 00516 magnifier->source_bounds.y2 = 00517 magnifier->target_bounds.y1; 00518 } 00519 magnifier->source_bounds.x1 = rect_bounds.x1; 00520 magnifier->source_bounds.x2 = rect_bounds.x2; 00521 } 00522 g_message ("set source bounds to %d,%d; %d,%d", 00523 magnifier->source_bounds.x1, magnifier->source_bounds.y1, 00524 magnifier->source_bounds.x2, magnifier->source_bounds.y2); 00525 } 00526 00527 static void 00528 magnifier_unref_zoom_region (gpointer data, gpointer user_data) 00529 { 00530 /* Magnifier *magnifier = user_data; NOT USED */ 00531 CORBA_Environment ev; 00532 GNOME_Magnifier_ZoomRegion zoom_region = data; 00533 CORBA_exception_init (&ev); 00534 00535 DBG(g_message ("unreffing zoom region")); 00536 00537 GNOME_Magnifier_ZoomRegion_dispose (zoom_region, &ev); 00538 if (!BONOBO_EX (&ev)) 00539 Bonobo_Unknown_unref (zoom_region, &ev); 00540 } 00541 00542 static void 00543 magnifier_dbus_unref_zoom_region (gpointer data, gpointer user_data) 00544 { 00545 /* Magnifier *magnifier = user_data; NOT USED */ 00546 ZoomRegion *zoom_region = data; 00547 00548 DBG(g_message ("unreffing zoom region")); 00549 00550 impl_dbus_zoom_region_dispose (zoom_region); 00551 } 00552 00553 static GSList* 00554 magnifier_zoom_regions_save (Magnifier *magnifier) 00555 { 00556 GList *list; 00557 GSList *save_props = NULL; 00558 00559 g_assert (magnifier); 00560 list = magnifier->zoom_regions; 00561 00562 DBG(g_message ("saving %d regions", g_list_length (list))); 00563 00564 while (list) 00565 { 00566 GNOME_Magnifier_ZoomRegion zoom_region; 00567 CORBA_Environment ev; 00568 zoom_region = list->data; 00569 CORBA_exception_init (&ev); 00570 if (zoom_region) 00571 { 00572 Bonobo_PropertyBag properties; 00573 CORBA_any *value; 00574 MagnifierZoomRegionSaveProps *zoomer_props = g_new0 (MagnifierZoomRegionSaveProps, 1); 00575 00576 zoomer_props->rectbounds = GNOME_Magnifier_ZoomRegion_getROI (zoom_region, &ev); 00577 properties = GNOME_Magnifier_ZoomRegion_getProperties (zoom_region, &ev); 00578 value = bonobo_pbclient_get_value (properties, "viewport", TC_GNOME_Magnifier_RectBounds, &ev); 00579 memcpy (&zoomer_props->viewport, value->_value, sizeof (GNOME_Magnifier_RectBounds)); 00580 CORBA_free (value); 00581 zoomer_props->is_managed = bonobo_pbclient_get_boolean (properties, "is-managed", NULL); 00582 zoomer_props->scroll_policy = bonobo_pbclient_get_short (properties, "smooth-scroll-policy", NULL); 00583 zoomer_props->contrast = bonobo_pbclient_get_float (properties, "contrast", NULL); 00584 zoomer_props->zx = bonobo_pbclient_get_float (properties, "mag-factor-x", NULL); 00585 zoomer_props->zy = bonobo_pbclient_get_float (properties, "mag-factor-y", NULL); 00586 zoomer_props->xalign = bonobo_pbclient_get_long (properties, "x-alignment", NULL); 00587 zoomer_props->yalign = bonobo_pbclient_get_long (properties, "y-alignment", NULL); 00588 zoomer_props->border_color = bonobo_pbclient_get_long (properties, "border-color", NULL); 00589 zoomer_props->border_size = bonobo_pbclient_get_long (properties, "border-size", NULL); 00590 zoomer_props->smoothing_type = bonobo_pbclient_get_string (properties, "smoothing-type", NULL); 00591 zoomer_props->inverse = bonobo_pbclient_get_boolean (properties, "inverse-video", NULL); 00592 00593 bonobo_object_release_unref (properties, &ev); 00594 magnifier_unref_zoom_region ((gpointer) zoom_region, NULL); 00595 save_props = g_slist_append (save_props, zoomer_props); 00596 } 00597 list = g_list_next (list); 00598 } 00599 00600 magnifier->zoom_regions = NULL; 00601 magnifier->zoom_regions_dbus = NULL; 00602 00603 return save_props; 00604 } 00605 00606 static void 00607 magnifier_zoom_regions_restore (Magnifier *magnifier, GSList *region_params) 00608 { 00609 GSList *list = region_params; 00610 00611 while (list) 00612 { 00613 CORBA_Environment ev; 00614 MagnifierZoomRegionSaveProps *zoomer_props = list->data; 00615 GNOME_Magnifier_ZoomRegion new_region; 00616 Bonobo_PropertyBag new_properties; 00617 00618 CORBA_exception_init (&ev); 00619 new_region = GNOME_Magnifier_Magnifier_createZoomRegion (BONOBO_OBJREF (magnifier), zoomer_props->zx, zoomer_props->zy, &zoomer_props->rectbounds, &zoomer_props->viewport, &ev); 00620 new_properties = GNOME_Magnifier_ZoomRegion_getProperties (new_region, &ev); 00621 bonobo_pbclient_set_boolean (new_properties, "is-managed", 00622 zoomer_props->is_managed, NULL); 00623 bonobo_pbclient_set_short (new_properties, "smooth-scroll-policy", 00624 zoomer_props->scroll_policy, NULL); 00625 bonobo_pbclient_set_float (new_properties, "contrast", 00626 zoomer_props->contrast, NULL); 00627 /* NOT YET USED 00628 bonobo_pbclient_set_long (new_properties, "x-alignment", 00629 zoomer_props->xalign, NULL); 00630 bonobo_pbclient_set_long (new_properties, "y-alignment", 00631 zoomer_props->yalign, NULL); 00632 */ 00633 bonobo_pbclient_set_long (new_properties, "border-color", 00634 zoomer_props->border_color, NULL); 00635 bonobo_pbclient_set_long (new_properties, "border-size", 00636 zoomer_props->border_size, NULL); 00637 bonobo_pbclient_set_string (new_properties, "smoothing-type", 00638 zoomer_props->smoothing_type, NULL); 00639 bonobo_pbclient_set_boolean (new_properties, "inverse-video", 00640 zoomer_props->inverse, NULL); 00641 GNOME_Magnifier_Magnifier_addZoomRegion (BONOBO_OBJREF (magnifier), new_region, &ev); 00642 g_free (zoomer_props->smoothing_type); 00643 g_free (zoomer_props); 00644 bonobo_object_release_unref (new_properties, &ev); 00645 list = g_slist_next (list); 00646 } 00647 g_slist_free (region_params); 00648 } 00649 00650 static void 00651 magnifier_init_display (Magnifier *magnifier, gchar *display_name, gboolean is_target) 00652 { 00653 if (!can_open_display (display_name)) 00654 return; 00655 00656 if (is_target) 00657 { 00658 magnifier->target_screen_num = 00659 magnifier_parse_display_name (magnifier, 00660 display_name, 00661 NULL); 00662 magnifier->target_display = 00663 gdk_display_open (display_name); 00664 if (magnifier->target_display_name) g_free (magnifier->target_display_name); 00665 magnifier->target_display_name = g_strdup (display_name); 00666 magnifier->priv->root = 00667 gdk_screen_get_root_window ( 00668 gdk_display_get_screen ( 00669 magnifier->target_display, 00670 magnifier->target_screen_num)); 00671 } 00672 else 00673 { 00674 magnifier->source_screen_num = 00675 magnifier_parse_display_name (magnifier, 00676 display_name, 00677 NULL); 00678 magnifier->source_display = 00679 gdk_display_open (display_name); 00680 if (magnifier->source_display) 00681 { 00682 if (magnifier->source_display_name) g_free (magnifier->source_display_name); 00683 magnifier->source_display_name = g_strdup (display_name); 00684 magnifier->priv->root = 00685 gdk_screen_get_root_window ( 00686 gdk_display_get_screen ( 00687 magnifier->source_display, 00688 magnifier->source_screen_num)); 00689 } 00690 } 00691 } 00692 00693 static void 00694 magnifier_exit (GtkObject *object) 00695 { 00696 gtk_main_quit (); 00697 exit (0); 00698 } 00699 00700 #define GET_PIXEL(a,i,j,s,b) \ 00701 (*(guint32 *)(memcpy (b,(a) + ((j) * s + (i) * pixel_size_t), pixel_size_t))) 00702 00703 #define PUT_PIXEL(a,i,j,s,b) \ 00704 (memcpy (a + ((j) * s + (i) * pixel_size_t), &(b), pixel_size_t)) 00705 00706 static void 00707 magnifier_recolor_pixbuf (Magnifier *magnifier, GdkPixbuf *pixbuf) 00708 { 00709 int rowstride = gdk_pixbuf_get_rowstride (pixbuf); 00710 int i, j; 00711 int w = gdk_pixbuf_get_width (pixbuf); 00712 int h = gdk_pixbuf_get_height (pixbuf); 00713 guchar *pixels = gdk_pixbuf_get_pixels (pixbuf); 00714 guint32 pixval = 0, cursor_color = 0; 00715 size_t pixel_size_t = 3; /* FIXME: invalid assumption ? */ 00716 00717 cursor_color = ((magnifier->cursor_color & 0xFF0000) >> 16) + 00718 (magnifier->cursor_color & 0x00FF00) + 00719 ((magnifier->cursor_color & 0x0000FF) << 16); 00720 for (j = 0; j < h; ++j) { 00721 for (i = 0; i < w; ++i) { 00722 pixval = GET_PIXEL (pixels, i, j, rowstride, &pixval); 00723 if ((pixval & 0x808080) == 0) 00724 { 00725 pixval = cursor_color; 00726 PUT_PIXEL (pixels, i, j, rowstride, 00727 pixval); 00728 } 00729 } 00730 } 00731 } 00732 00733 void 00734 magnifier_transform_cursor (Magnifier *magnifier) 00735 { 00736 if (magnifier->priv->cursor) /* don't do this if cursor isn't intialized yet */ 00737 { 00738 int width, height; 00739 int size_x, size_y; 00740 GdkPixbuf *scaled_cursor_pixbuf; 00741 GdkPixbuf *scaled_mask_pixbuf; 00742 GdkPixbuf *scaled_mask_pixbuf_alpha; 00743 GdkPixbuf *cursor_pixbuf; 00744 GdkPixbuf *mask_pixbuf; 00745 GdkPixmap *cursor_pixmap = magnifier->priv->cursor; 00746 GdkPixmap *mask_pixmap = magnifier->priv->cursor_mask; 00747 GdkGC *cgc; 00748 GdkGC *mgc; 00749 00750 if (magnifier->cursor_size_x) 00751 { 00752 size_x = magnifier->cursor_size_x; 00753 size_y = magnifier->cursor_size_y; 00754 } 00755 else 00756 { 00757 size_x = magnifier->priv->cursor_default_size_x * 00758 magnifier->cursor_scale_factor; 00759 size_y = magnifier->priv->cursor_default_size_y * 00760 magnifier->cursor_scale_factor; 00761 } 00762 gdk_drawable_get_size (magnifier->priv->cursor, &width, &height); 00763 if ((size_x == width) && (size_y == height) 00764 && (magnifier->cursor_color == 0xFF000000)) { 00765 return; /* nothing changes */ 00766 } 00767 cgc = gdk_gc_new (cursor_pixmap); 00768 mgc = gdk_gc_new (mask_pixmap); 00769 cursor_pixbuf = gdk_pixbuf_get_from_drawable (NULL, cursor_pixmap, 00770 NULL, 0, 0, 0, 0, 00771 width, height); 00772 if (magnifier->cursor_color != 0xFF000000) 00773 magnifier_recolor_pixbuf (magnifier, cursor_pixbuf); 00774 mask_pixbuf = gdk_pixbuf_get_from_drawable (NULL, 00775 mask_pixmap, 00776 NULL, 0, 0, 0, 0, 00777 width, height); 00778 scaled_cursor_pixbuf = gdk_pixbuf_scale_simple ( 00779 cursor_pixbuf, size_x, size_y, GDK_INTERP_NEAREST); 00780 00781 magnifier->cursor_hotspot.x = magnifier->priv->cursor_hotspot_x * size_x 00782 / magnifier->priv->cursor_default_size_x; 00783 magnifier->cursor_hotspot.y = magnifier->priv->cursor_hotspot_y * size_y 00784 / magnifier->priv->cursor_default_size_y; 00785 00786 scaled_mask_pixbuf = gdk_pixbuf_scale_simple ( 00787 mask_pixbuf, size_x, size_y, GDK_INTERP_NEAREST); 00788 g_object_unref (cursor_pixbuf); 00789 g_object_unref (mask_pixbuf); 00790 g_object_unref (cursor_pixmap); 00791 g_object_unref (mask_pixmap); 00792 magnifier->priv->cursor = gdk_pixmap_new ( 00793 gtk_widget_get_window (magnifier->priv->w), 00794 size_x, size_y, 00795 -1); 00796 if (!GDK_IS_DRAWABLE (magnifier->priv->cursor)) 00797 { 00798 DBG (g_warning ("NULL magnifier cursor pixmap.")); 00799 return; 00800 } 00801 magnifier->priv->cursor_mask = gdk_pixmap_new ( 00802 gtk_widget_get_window (magnifier->priv->w), 00803 size_x, size_y, 00804 1); 00805 if (GDK_IS_DRAWABLE (magnifier->priv->cursor)) { 00806 gdk_draw_pixbuf (magnifier->priv->cursor, 00807 cgc, 00808 scaled_cursor_pixbuf, 00809 0, 0, 0, 0, size_x, size_y, 00810 GDK_RGB_DITHER_NONE, 0, 0 ); 00811 } 00812 else 00813 DBG (g_warning ("cursor pixmap is non-drawable.")); 00814 scaled_mask_pixbuf_alpha = gdk_pixbuf_add_alpha ( 00815 scaled_mask_pixbuf, True, 0, 0, 0); 00816 gdk_pixbuf_render_threshold_alpha (scaled_mask_pixbuf_alpha, 00817 magnifier->priv->cursor_mask, 00818 0, 0, 0, 0, size_x, size_y, 00819 0x80); 00820 g_object_unref (scaled_mask_pixbuf_alpha); 00821 g_object_unref (scaled_cursor_pixbuf); 00822 g_object_unref (scaled_mask_pixbuf); 00823 g_object_unref (mgc); 00824 g_object_unref (cgc); 00825 } 00826 } 00827 00828 static void 00829 magnifier_init_cursor_set (Magnifier *magnifier, gchar *cursor_set) 00830 { 00831 /* 00832 * we check the cursor-set property string here, 00833 * and create/apply the appropriate cursor settings 00834 */ 00835 magnifier->cursor_set = cursor_set; 00836 magnifier->priv->use_source_cursor = 00837 (!strcmp (cursor_set, "default") && 00838 (fixes_event_base != 0)); 00839 if (magnifier->priv->use_source_cursor) return; 00840 00841 if (!strcmp (magnifier->cursor_set, "none")) { 00842 magnifier->priv->cursor = NULL; 00843 return; 00844 } 00845 else 00846 { 00847 GDir *cursor_dir; 00848 const gchar *filename; 00849 gchar *cursor_dirname; 00850 00851 if (magnifier->priv->cursorlist) 00852 { 00853 g_hash_table_destroy (magnifier->priv->cursorlist); 00854 } 00855 magnifier->priv->cursorlist = g_hash_table_new_full (g_str_hash, g_str_equal, 00856 g_free, g_object_unref); 00857 00858 cursor_dirname = g_strconcat (CURSORSDIR, "/", magnifier->cursor_set, NULL); 00859 cursor_dir = g_dir_open (cursor_dirname, 0, NULL); 00860 /* assignment, not comparison, is intentional */ 00861 while (cursor_dir && (filename = g_dir_read_name (cursor_dir)) != NULL) 00862 { 00863 if (filename) 00864 { 00865 gchar *path = g_strconcat (cursor_dirname, "/", filename, NULL); 00866 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (path, NULL); 00867 if (pixbuf) 00868 { 00869 /* add this pixbuf and its name to our list */ 00870 gchar **sv, *cname; 00871 cname = g_path_get_basename (filename); 00872 sv = g_strsplit (cname, ".", 2); 00873 g_hash_table_insert (magnifier->priv->cursorlist, 00874 g_strdup (sv[0]), 00875 pixbuf); 00876 g_free (cname); 00877 g_strfreev (sv); 00878 } 00879 g_free (path); 00880 } 00881 } 00882 g_free (cursor_dirname); 00883 if (cursor_dir) g_dir_close (cursor_dir); 00884 } 00885 /* don't fallover to source cursor here, we haven't initialized X yet */ 00886 magnifier_set_cursor_pixmap_by_name (magnifier, "default", FALSE); 00887 magnifier_transform_cursor (magnifier); 00888 } 00889 00890 static gboolean 00891 magnifier_reset_struts_at_idle (gpointer data) 00892 { 00893 if (data) 00894 { 00895 Magnifier *magnifier = MAGNIFIER (data); 00896 #if GTK_CHECK_VERSION (2,19,5) 00897 if (magnifier->priv && 00898 gtk_widget_get_realized (magnifier->priv->w) && 00899 gmag_gs_check_set_struts (magnifier)) { 00900 return FALSE; 00901 } 00902 #else 00903 if (magnifier->priv && 00904 GTK_WIDGET_REALIZED (magnifier->priv->w) && 00905 gmag_gs_check_set_struts (magnifier)) { 00906 return FALSE; 00907 } 00908 #endif 00909 } 00910 return TRUE; 00911 } 00912 00913 static void 00914 magnifier_get_property (BonoboPropertyBag *bag, 00915 BonoboArg *arg, 00916 guint arg_id, 00917 CORBA_Environment *ev, 00918 gpointer user_data) 00919 { 00920 Magnifier *magnifier = user_data; 00921 int csize = 0; 00922 00923 DBG (fprintf (stderr, "Get property: \t%s\n", mag_prop_names[arg_id])); 00924 00925 switch (arg_id) { 00926 case MAGNIFIER_SOURCE_SIZE_PROP: 00927 BONOBO_ARG_SET_GENERAL (arg, magnifier->source_bounds, 00928 TC_GNOME_Magnifier_RectBounds, 00929 GNOME_Magnifier_RectBounds, NULL); 00930 break; 00931 case MAGNIFIER_TARGET_SIZE_PROP: 00932 BONOBO_ARG_SET_GENERAL (arg, magnifier->target_bounds, 00933 TC_GNOME_Magnifier_RectBounds, 00934 GNOME_Magnifier_RectBounds, NULL); 00935 00936 break; 00937 case MAGNIFIER_CURSOR_SET_PROP: 00938 BONOBO_ARG_SET_STRING (arg, magnifier->cursor_set); 00939 break; 00940 case MAGNIFIER_CURSOR_SIZE_PROP: 00941 BONOBO_ARG_SET_INT (arg, magnifier->cursor_size_x); 00942 BONOBO_ARG_SET_INT (arg, magnifier->cursor_size_y); 00943 break; 00944 case MAGNIFIER_CURSOR_ZOOM_PROP: 00945 BONOBO_ARG_SET_FLOAT (arg, magnifier->cursor_scale_factor); 00946 break; 00947 case MAGNIFIER_CURSOR_COLOR_PROP: 00948 BONOBO_ARG_SET_GENERAL (arg, magnifier->cursor_color, 00949 TC_CORBA_unsigned_long, 00950 CORBA_unsigned_long, NULL); 00951 break; 00952 case MAGNIFIER_CURSOR_HOTSPOT_PROP: 00953 BONOBO_ARG_SET_GENERAL (arg, magnifier->cursor_hotspot, 00954 TC_GNOME_Magnifier_Point, 00955 GNOME_Magnifier_Point, NULL); 00956 00957 break; 00958 case MAGNIFIER_CURSOR_DEFAULT_SIZE_PROP: 00959 if (magnifier->priv->cursor) 00960 gdk_drawable_get_size (magnifier->priv->cursor, 00961 &csize, &csize); 00962 BONOBO_ARG_SET_INT (arg, csize); 00963 break; 00964 case MAGNIFIER_CROSSWIRE_SIZE_PROP: 00965 BONOBO_ARG_SET_INT (arg, magnifier->crosswire_size); 00966 break; 00967 case MAGNIFIER_CROSSWIRE_LENGTH_PROP: 00968 BONOBO_ARG_SET_INT (arg, magnifier->crosswire_length); 00969 break; 00970 case MAGNIFIER_CROSSWIRE_CLIP_PROP: 00971 BONOBO_ARG_SET_BOOLEAN (arg, magnifier->crosswire_clip); 00972 break; 00973 case MAGNIFIER_CROSSWIRE_COLOR_PROP: 00974 BONOBO_ARG_SET_LONG (arg, magnifier->crosswire_color); 00975 break; 00976 case MAGNIFIER_SOURCE_DISPLAY_PROP: 00977 BONOBO_ARG_SET_STRING (arg, magnifier->source_display_name); 00978 break; 00979 case MAGNIFIER_TARGET_DISPLAY_PROP: 00980 BONOBO_ARG_SET_STRING (arg, magnifier->target_display_name); 00981 break; 00982 default: 00983 bonobo_exception_set (ev, ex_Bonobo_PropertyBag_NotFound); 00984 }; 00985 } 00986 00987 gboolean 00988 impl_dbus_magnifier_set_source_display (Magnifier *magnifier, gchar *source_display) 00989 { 00990 gchar *full_display_string = source_display; 00991 if (can_open_display (full_display_string)) 00992 { 00993 GSList *zoom_region_params = NULL; 00994 magnifier->source_screen_num = 00995 magnifier_parse_display_name (magnifier, 00996 full_display_string, 00997 NULL); 00998 magnifier->source_display = 00999 gdk_display_open (full_display_string); 01000 magnifier->source_display_name = g_strdup (full_display_string); 01001 zoom_region_params = magnifier_zoom_regions_save (magnifier); 01002 magnifier->priv->root = 01003 gdk_screen_get_root_window ( 01004 gdk_display_get_screen ( 01005 magnifier->source_display, 01006 magnifier->source_screen_num)); 01007 01008 /* remove the source_drawable, since in the new display the 01009 * composite can be unavailable and the source_drawable is 01010 * where the desktop screen is composed. If this is not 01011 * freed it will be used even if the display doesn't use 01012 * composite what will lead to wrong behavior and crashes. 01013 * If composite is used in the new display this variable is 01014 * re-created */ 01015 if (magnifier->priv->source_drawable) { 01016 g_object_unref (magnifier->priv->source_drawable); 01017 magnifier->priv->source_drawable = NULL; 01018 } 01019 01020 /* attach listeners for DAMAGE, "dirty region", XFIXES 01021 * cursor changes */ 01022 magnifier_set_extension_listeners (magnifier, magnifier_get_root (magnifier)); 01023 magnifier_get_display_rect_bounds (magnifier, &magnifier->source_bounds, FALSE); 01024 magnifier_adjust_source_size (magnifier); 01025 magnifier_zoom_regions_restore (magnifier, zoom_region_params); 01026 magnifier_warp_cursor_to_screen (magnifier); 01027 gmag_gs_check_set_struts (magnifier); 01028 gmag_gs_reset_overlay_at_idle (magnifier); 01029 } 01030 DBG(fprintf (stderr, "Set source display: \t%s\n", full_display_string)); 01031 01032 return TRUE; 01033 } 01034 01035 gchar* 01036 impl_dbus_magnifier_get_source_display (Magnifier *magnifier) 01037 { 01038 return g_strdup (magnifier->source_display_name); 01039 } 01040 01041 gboolean 01042 impl_dbus_magnifier_set_target_display (Magnifier *magnifier, gchar *target_display) 01043 { 01044 gchar *full_display_string = target_display; 01045 if (can_open_display (full_display_string)) 01046 { 01047 magnifier->target_screen_num = 01048 magnifier_parse_display_name (magnifier, 01049 full_display_string, 01050 NULL); 01051 magnifier->target_display = 01052 gdk_display_open (full_display_string); 01053 magnifier->target_display_name = g_strdup (full_display_string); 01054 if (GTK_IS_WINDOW (magnifier->priv->w)) 01055 { 01056 #ifdef REPARENT_GTK_WINDOW_WORKS 01057 gtk_window_set_screen (GTK_WINDOW (magnifier->priv->w), 01058 gdk_display_get_screen ( 01059 magnifier->target_display, 01060 magnifier->target_screen_num)); 01061 #else 01062 GSList *zoom_region_params = NULL; 01063 /* disconnect from the old window's destroy signal */ 01064 g_object_disconnect (magnifier->priv->w, 01065 "any_signal::realize", magnifier_realize, NULL, 01066 "any_signal::size_allocate", magnifier_size_allocate, NULL, 01067 "any_signal::destroy", magnifier_exit, NULL, 01068 NULL); 01069 /* save the old zoom region state */ 01070 zoom_region_params = magnifier_zoom_regions_save (magnifier); 01071 /* destroy the old window */ 01072 gtk_widget_destroy (magnifier->priv->w); 01073 /* and re-initialize... */ 01074 magnifier_init_window (magnifier, gdk_display_get_screen ( 01075 magnifier->target_display, 01076 magnifier->target_screen_num)); 01077 /* restore the zoom regions in their new host magnifier window */ 01078 magnifier_zoom_regions_restore (magnifier, zoom_region_params); 01079 #endif 01080 } 01081 magnifier_get_display_rect_bounds (magnifier, &magnifier->source_bounds, FALSE); 01082 magnifier_init_cursor_set (magnifier, magnifier->cursor_set); /* needed to reset pixmaps */ 01083 if (magnifier->priv->overlay) 01084 gdk_window_move (magnifier->priv->overlay, 01085 magnifier->target_bounds.x1, 01086 magnifier->target_bounds.y1); 01087 else 01088 gtk_window_move (GTK_WINDOW (magnifier->priv->w), 01089 magnifier->target_bounds.x1, 01090 magnifier->target_bounds.y1); 01091 01092 if ((magnifier->target_bounds.x2 - magnifier->target_bounds.x1 > 0) && 01093 (magnifier->target_bounds.y2 - magnifier->target_bounds.y1) > 0) 01094 { 01095 if (magnifier->priv->overlay) 01096 gdk_window_resize ( 01097 magnifier->priv->overlay, 01098 magnifier->target_bounds.x2 - 01099 magnifier->target_bounds.x1, 01100 magnifier->target_bounds.y2 - 01101 magnifier->target_bounds.y1); 01102 gtk_window_resize (GTK_WINDOW (magnifier->priv->w), 01103 magnifier->target_bounds.x2 - magnifier->target_bounds.x1, 01104 magnifier->target_bounds.y2 - magnifier->target_bounds.y1); 01105 DBG(fprintf (stderr, "Set target size: \t%d,%d to %d,%d\n", 01106 magnifier->target_bounds.x1, magnifier->target_bounds.y1, magnifier->target_bounds.x2, magnifier->target_bounds.y2)); 01107 } 01108 /* N. B. we don't reset the target bounds to the limits of the new display, because */ 01109 /* doing so would override the client-specified magnifier size */ 01110 /* magnifier_get_display_rect_bounds (magnifier, &magnifier->target_bounds, TRUE); */ 01111 gmag_gs_check_set_struts (magnifier); 01112 } 01113 DBG(fprintf (stderr, "Set target display: \t%s (screen %d)\n", 01114 full_display_string, magnifier->target_screen_num)); 01115 01116 return TRUE; 01117 } 01118 01119 gchar* 01120 impl_dbus_magnifier_get_target_display (Magnifier *magnifier) 01121 { 01122 return g_strdup (magnifier->target_display_name); 01123 } 01124 01125 gboolean 01126 impl_dbus_magnifier_set_source_size (Magnifier *magnifier, gint32 **bounds) 01127 { 01128 magnifier->source_bounds.x1 = (*bounds)[0]; 01129 magnifier->source_bounds.y1 = (*bounds)[1]; 01130 magnifier->source_bounds.x2 = (*bounds)[2]; 01131 magnifier->source_bounds.y2 = (*bounds)[3]; 01132 DBG (fprintf (stderr, "Set source size: \t%d,%d to %d,%d\n", 01133 magnifier->source_bounds.x1, magnifier->source_bounds.y1, magnifier->source_bounds.x2, magnifier->source_bounds.y2)); 01134 01135 return TRUE; 01136 } 01137 01138 GArray* 01139 impl_dbus_magnifier_get_source_size (Magnifier *magnifier) 01140 { 01141 GArray *ret = g_array_new (FALSE, FALSE, sizeof (gint32)); 01142 01143 g_array_append_val (ret, magnifier->source_bounds.x1); 01144 g_array_append_val (ret, magnifier->source_bounds.y1); 01145 g_array_append_val (ret, magnifier->source_bounds.x2); 01146 g_array_append_val (ret, magnifier->source_bounds.y2); 01147 01148 return ret; 01149 } 01150 01151 gboolean 01152 impl_dbus_magnifier_set_target_size (Magnifier *magnifier, gint32 **bounds) 01153 { 01154 magnifier->target_bounds.x1 = (*bounds)[0]; 01155 magnifier->target_bounds.y1 = (*bounds)[1]; 01156 magnifier->target_bounds.x2 = (*bounds)[2]; 01157 magnifier->target_bounds.y2 = (*bounds)[3]; 01158 01159 if (magnifier->priv->overlay) 01160 gdk_window_move_resize (magnifier->priv->overlay, 01161 magnifier->target_bounds.x1, 01162 magnifier->target_bounds.y1, 01163 magnifier->target_bounds.x2 - 01164 magnifier->target_bounds.x1, 01165 magnifier->target_bounds.y2 - 01166 magnifier->target_bounds.y1); 01167 else 01168 gtk_window_move (GTK_WINDOW (magnifier->priv->w), 01169 magnifier->target_bounds.x1, 01170 magnifier->target_bounds.y1); 01171 01172 gtk_window_resize (GTK_WINDOW (magnifier->priv->w), 01173 magnifier->target_bounds.x2 - magnifier->target_bounds.x1, 01174 magnifier->target_bounds.y2 - magnifier->target_bounds.y1); 01175 gmag_gs_check_set_struts (magnifier); 01176 DBG(fprintf (stderr, "Set target size: \t%d,%d to %d,%d\n", 01177 magnifier->target_bounds.x1, magnifier->target_bounds.y1, magnifier->target_bounds.x2, magnifier->target_bounds.y2)); 01178 if (!strcmp (magnifier->target_display_name, magnifier->source_display_name) && 01179 (magnifier->target_screen_num == magnifier->source_screen_num)) 01180 magnifier_adjust_source_size (magnifier); 01181 01182 return TRUE; 01183 } 01184 01185 GArray* 01186 impl_dbus_magnifier_get_target_size (Magnifier *magnifier) 01187 { 01188 GArray *ret = g_array_new (FALSE, FALSE, sizeof (gint32)); 01189 01190 g_array_append_val (ret, magnifier->target_bounds.x1); 01191 g_array_append_val (ret, magnifier->target_bounds.y1); 01192 g_array_append_val (ret, magnifier->target_bounds.x2); 01193 g_array_append_val (ret, magnifier->target_bounds.y2); 01194 01195 return ret; 01196 } 01197 01198 gboolean 01199 impl_dbus_magnifier_set_cursor_set (Magnifier *magnifier, gchar *cursor_set) 01200 { 01201 magnifier_init_cursor_set (magnifier, g_strdup (cursor_set)); 01202 DBG (fprintf (stderr, "Setting cursor set: \t%s\n", cursor_set)); 01203 01204 return TRUE; 01205 } 01206 01207 gchar* 01208 impl_dbus_magnifier_get_cursor_set (Magnifier *magnifier) 01209 { 01210 return g_strdup (magnifier->cursor_set); 01211 } 01212 01213 gboolean 01214 impl_dbus_magnifier_set_cursor_size (Magnifier *magnifier, gint x, gint y) 01215 { 01216 magnifier->cursor_size_x = x; 01217 magnifier->cursor_size_y = y; 01218 magnifier_transform_cursor (magnifier); 01219 DBG (fprintf (stderr, "Setting cursor size: \t%d\n", magnifier->cursor_size_x)); 01220 01221 return TRUE; 01222 } 01223 01224 GArray* 01225 impl_dbus_magnifier_get_cursor_size (Magnifier *magnifier) 01226 { 01227 GArray *ret = g_array_new (FALSE, FALSE, sizeof (gint)); 01228 01229 g_array_append_val (ret, magnifier->cursor_size_x); 01230 g_array_append_val (ret, magnifier->cursor_size_y); 01231 01232 return ret; 01233 } 01234 01235 gboolean 01236 impl_dbus_magnifier_set_cursor_zoom (Magnifier *magnifier, double factor) 01237 { 01238 magnifier->cursor_scale_factor = factor; 01239 DBG (fprintf (stderr, "Setting cursor scale factor: \t%f\n", magnifier->cursor_scale_factor)); 01240 magnifier_transform_cursor (magnifier); 01241 01242 return TRUE; 01243 } 01244 01245 double 01246 impl_dbus_magnifier_get_cursor_zoom (Magnifier *magnifier) 01247 { 01248 return magnifier->cursor_scale_factor; 01249 } 01250 01251 gboolean 01252 impl_dbus_magnifier_set_cursor_color (Magnifier *magnifier, guint32 color) 01253 { 01254 magnifier->cursor_color = color; 01255 magnifier_transform_cursor (magnifier); 01256 DBG (fprintf (stderr, "Setting cursor color: \t%u\n", (unsigned) magnifier->cursor_color)); 01257 01258 return TRUE; 01259 } 01260 01261 guint32 01262 impl_dbus_magnifier_get_cursor_color (Magnifier *magnifier) 01263 { 01264 return magnifier->cursor_color; 01265 } 01266 01267 gboolean 01268 impl_dbus_magnifier_set_cursor_hotspot (Magnifier *magnifier, gint32 x, gint32 y) 01269 { 01270 magnifier->cursor_hotspot.x = x; 01271 magnifier->cursor_hotspot.y = y; 01272 magnifier_transform_cursor (magnifier); 01273 01274 return TRUE; 01275 } 01276 01277 GArray* 01278 impl_dbus_magnifier_get_cursor_hotspot (Magnifier *magnifier) 01279 { 01280 GArray *ret = g_array_new (FALSE, FALSE, sizeof (gint32)); 01281 01282 g_array_append_val (ret, magnifier->cursor_hotspot.x); 01283 g_array_append_val (ret, magnifier->cursor_hotspot.y); 01284 01285 return ret; 01286 } 01287 01288 gint32 01289 impl_dbus_magnifier_get_cursor_default_size (Magnifier *magnifier) 01290 { 01291 gint32 csize; 01292 01293 if (magnifier->priv->cursor) { 01294 gdk_drawable_get_size (magnifier->priv->cursor, &csize, &csize); 01295 } 01296 01297 return csize; 01298 } 01299 01300 gboolean 01301 impl_dbus_magnifier_set_crosswire_size (Magnifier *magnifier, gint size) 01302 { 01303 magnifier->crosswire_size = size; 01304 DBG (fprintf (stderr, "Setting crosswire size: \t%d\n", magnifier->crosswire_size)); 01305 magnifier_zoom_regions_update_pointer (magnifier); 01306 01307 return TRUE; 01308 } 01309 01310 gint 01311 impl_dbus_magnifier_get_crosswire_size (Magnifier *magnifier) 01312 { 01313 return magnifier->crosswire_size; 01314 } 01315 01316 gboolean 01317 impl_dbus_magnifier_set_crosswire_length (Magnifier *magnifier, gint length) 01318 { 01319 GNOME_Magnifier_RectBounds rect_bounds; 01320 rect_bounds.x1 = 0; 01321 rect_bounds.y1 = 0; 01322 rect_bounds.x2 = 4096; 01323 rect_bounds.y2 = 4096; 01324 01325 magnifier->crosswire_length = length; 01326 DBG (fprintf (stderr, "Setting crosswire length: \t%d\n", magnifier->crosswire_length)); 01327 magnifier_zoom_regions_mark_dirty (magnifier, rect_bounds); 01328 01329 return TRUE; 01330 } 01331 01332 gboolean 01333 impl_dbus_magnifier_set_crosswire_clip (Magnifier *magnifier, gboolean clip) 01334 { 01335 magnifier->crosswire_clip = clip; 01336 DBG (fprintf (stderr, "Setting crosswire clip: \t%s\n", magnifier->crosswire_clip ? "true" : "false")); 01337 magnifier_zoom_regions_update_pointer (magnifier); 01338 01339 return TRUE; 01340 } 01341 01342 gboolean 01343 impl_dbus_magnifier_get_crosswire_clip (Magnifier *magnifier) 01344 { 01345 return magnifier->crosswire_clip; 01346 } 01347 01348 gint 01349 impl_dbus_magnifier_get_crosswire_length (Magnifier *magnifier) { 01350 return magnifier->crosswire_length; 01351 } 01352 01353 gboolean 01354 impl_dbus_magnifier_set_crosswire_color (Magnifier *magnifier, guint32 color) 01355 { 01356 magnifier->crosswire_color = color; 01357 DBG (fprintf (stderr, "Setting crosswire color: \t%ld\n", (long) magnifier->crosswire_color)); 01358 01359 return TRUE; 01360 } 01361 01362 guint32 01363 impl_dbus_magnifier_get_crosswire_color (Magnifier *magnifier) 01364 { 01365 return magnifier->crosswire_color; 01366 } 01367 01368 static void 01369 magnifier_set_property (BonoboPropertyBag *bag, 01370 BonoboArg *arg, 01371 guint arg_id, 01372 CORBA_Environment *ev, 01373 gpointer user_data) 01374 { 01375 Magnifier *magnifier = user_data; 01376 gchar *full_display_string; 01377 01378 GNOME_Magnifier_RectBounds rect_bounds; 01379 rect_bounds.x1 = 0; 01380 rect_bounds.y1 = 0; 01381 rect_bounds.x2 = 4096; 01382 rect_bounds.y2 = 4096; 01383 01384 switch (arg_id) { 01385 case MAGNIFIER_SOURCE_DISPLAY_PROP: 01386 full_display_string = BONOBO_ARG_GET_STRING (arg); 01387 if (can_open_display (full_display_string)) 01388 { 01389 GSList *zoom_region_params = NULL; 01390 magnifier->source_screen_num = 01391 magnifier_parse_display_name (magnifier, 01392 full_display_string, 01393 NULL); 01394 magnifier->source_display = 01395 gdk_display_open (full_display_string); 01396 magnifier->source_display_name = g_strdup (full_display_string); 01397 zoom_region_params = magnifier_zoom_regions_save (magnifier); 01398 magnifier->priv->root = 01399 gdk_screen_get_root_window ( 01400 gdk_display_get_screen ( 01401 magnifier->source_display, 01402 magnifier->source_screen_num)); 01403 01404 /* remove the source_drawable, since in the new display the 01405 * composite can be unavailable and the source_drawable is 01406 * where the desktop screen is composed. If this is not 01407 * freed it will be used even if the display doesn't use 01408 * composite what will lead to wrong behavior and crashes. 01409 * If composite is used in the new display this variable is 01410 * re-created */ 01411 if (magnifier->priv->source_drawable) { 01412 g_object_unref (magnifier->priv->source_drawable); 01413 magnifier->priv->source_drawable = NULL; 01414 } 01415 01416 /* attach listeners for DAMAGE, "dirty region", XFIXES 01417 * cursor changes */ 01418 magnifier_set_extension_listeners (magnifier, magnifier_get_root (magnifier)); 01419 magnifier_get_display_rect_bounds (magnifier, &magnifier->source_bounds, FALSE); 01420 magnifier_adjust_source_size (magnifier); 01421 magnifier_zoom_regions_restore (magnifier, zoom_region_params); 01422 magnifier_warp_cursor_to_screen (magnifier); 01423 gmag_gs_check_set_struts (magnifier); 01424 gmag_gs_reset_overlay_at_idle (magnifier); 01425 } 01426 DBG(fprintf (stderr, "Set source display: \t%s\n", full_display_string)); 01427 break; 01428 case MAGNIFIER_TARGET_DISPLAY_PROP: 01429 full_display_string = BONOBO_ARG_GET_STRING (arg); 01430 if (can_open_display (full_display_string)) 01431 { 01432 magnifier->target_screen_num = 01433 magnifier_parse_display_name (magnifier, 01434 full_display_string, 01435 NULL); 01436 magnifier->target_display = 01437 gdk_display_open (full_display_string); 01438 magnifier->target_display_name = g_strdup (full_display_string); 01439 if (GTK_IS_WINDOW (magnifier->priv->w)) 01440 { 01441 #ifdef REPARENT_GTK_WINDOW_WORKS 01442 gtk_window_set_screen (GTK_WINDOW (magnifier->priv->w), 01443 gdk_display_get_screen ( 01444 magnifier->target_display, 01445 magnifier->target_screen_num)); 01446 #else 01447 GSList *zoom_region_params = NULL; 01448 /* disconnect from the old window's destroy signal */ 01449 g_object_disconnect (magnifier->priv->w, 01450 "any_signal::realize", magnifier_realize, NULL, 01451 "any_signal::size_allocate", magnifier_size_allocate, NULL, 01452 "any_signal::destroy", magnifier_exit, NULL, 01453 NULL); 01454 /* save the old zoom region state */ 01455 zoom_region_params = magnifier_zoom_regions_save (magnifier); 01456 /* destroy the old window */ 01457 gtk_widget_destroy (magnifier->priv->w); 01458 /* and re-initialize... */ 01459 magnifier_init_window (magnifier, gdk_display_get_screen ( 01460 magnifier->target_display, 01461 magnifier->target_screen_num)); 01462 /* restore the zoom regions in their new host magnifier window */ 01463 magnifier_zoom_regions_restore (magnifier, zoom_region_params); 01464 #endif 01465 } 01466 magnifier_get_display_rect_bounds (magnifier, &magnifier->source_bounds, FALSE); 01467 magnifier_init_cursor_set (magnifier, magnifier->cursor_set); /* needed to reset pixmaps */ 01468 if (magnifier->priv->overlay) 01469 gdk_window_move (magnifier->priv->overlay, 01470 magnifier->target_bounds.x1, 01471 magnifier->target_bounds.y1); 01472 else 01473 gtk_window_move (GTK_WINDOW (magnifier->priv->w), 01474 magnifier->target_bounds.x1, 01475 magnifier->target_bounds.y1); 01476 01477 if ((magnifier->target_bounds.x2 - magnifier->target_bounds.x1 > 0) && 01478 (magnifier->target_bounds.y2 - magnifier->target_bounds.y1) > 0) 01479 { 01480 if (magnifier->priv->overlay) 01481 gdk_window_resize ( 01482 magnifier->priv->overlay, 01483 magnifier->target_bounds.x2 - 01484 magnifier->target_bounds.x1, 01485 magnifier->target_bounds.y2 - 01486 magnifier->target_bounds.y1); 01487 gtk_window_resize (GTK_WINDOW (magnifier->priv->w), 01488 magnifier->target_bounds.x2 - magnifier->target_bounds.x1, 01489 magnifier->target_bounds.y2 - magnifier->target_bounds.y1); 01490 DBG(fprintf (stderr, "Set target size: \t%d,%d to %d,%d\n", 01491 magnifier->target_bounds.x1, magnifier->target_bounds.y1, magnifier->target_bounds.x2, magnifier->target_bounds.y2)); 01492 } 01493 /* N. B. we don't reset the target bounds to the limits of the new display, because */ 01494 /* doing so would override the client-specified magnifier size */ 01495 /* magnifier_get_display_rect_bounds (magnifier, &magnifier->target_bounds, TRUE); */ 01496 gmag_gs_check_set_struts (magnifier); 01497 } 01498 DBG(fprintf (stderr, "Set target display: \t%s (screen %d)\n", 01499 full_display_string, magnifier->target_screen_num)); 01500 break; 01501 case MAGNIFIER_SOURCE_SIZE_PROP: 01502 magnifier->source_bounds = BONOBO_ARG_GET_GENERAL (arg, 01503 TC_GNOME_Magnifier_RectBounds, 01504 GNOME_Magnifier_RectBounds, 01505 NULL); 01506 DBG (fprintf (stderr, "Set source size: \t%d,%d to %d,%d\n", 01507 magnifier->source_bounds.x1, magnifier->source_bounds.y1, magnifier->source_bounds.x2, magnifier->source_bounds.y2)); 01508 break; 01509 case MAGNIFIER_TARGET_SIZE_PROP: 01510 magnifier->target_bounds = BONOBO_ARG_GET_GENERAL (arg, 01511 TC_GNOME_Magnifier_RectBounds, 01512 GNOME_Magnifier_RectBounds, 01513 01514 NULL); 01515 if (magnifier->priv->overlay) 01516 gdk_window_move_resize (magnifier->priv->overlay, 01517 magnifier->target_bounds.x1, 01518 magnifier->target_bounds.y1, 01519 magnifier->target_bounds.x2 - 01520 magnifier->target_bounds.x1, 01521 magnifier->target_bounds.y2 - 01522 magnifier->target_bounds.y1); 01523 else 01524 gtk_window_move (GTK_WINDOW (magnifier->priv->w), 01525 magnifier->target_bounds.x1, 01526 magnifier->target_bounds.y1); 01527 01528 gtk_window_resize (GTK_WINDOW (magnifier->priv->w), 01529 magnifier->target_bounds.x2 - magnifier->target_bounds.x1, 01530 magnifier->target_bounds.y2 - magnifier->target_bounds.y1); 01531 gmag_gs_check_set_struts (magnifier); 01532 DBG(fprintf (stderr, "Set target size: \t%d,%d to %d,%d\n", 01533 magnifier->target_bounds.x1, magnifier->target_bounds.y1, magnifier->target_bounds.x2, magnifier->target_bounds.y2)); 01534 if (!strcmp (magnifier->target_display_name, magnifier->source_display_name) && 01535 (magnifier->target_screen_num == magnifier->source_screen_num)) 01536 magnifier_adjust_source_size (magnifier); 01537 break; 01538 case MAGNIFIER_CURSOR_SET_PROP: 01539 magnifier_init_cursor_set (magnifier, g_strdup (BONOBO_ARG_GET_STRING (arg))); 01540 DBG (fprintf (stderr, "Setting cursor set: \t%s\n", BONOBO_ARG_GET_STRING (arg))); 01541 break; 01542 case MAGNIFIER_CURSOR_SIZE_PROP: 01543 magnifier->cursor_size_x = BONOBO_ARG_GET_INT (arg); 01544 magnifier->cursor_size_y = BONOBO_ARG_GET_INT (arg); 01545 magnifier_transform_cursor (magnifier); 01546 DBG (fprintf (stderr, "Setting cursor size: \t%d\n", magnifier->cursor_size_x)); 01547 break; 01548 case MAGNIFIER_CURSOR_ZOOM_PROP: 01549 magnifier->cursor_scale_factor = BONOBO_ARG_GET_FLOAT (arg); 01550 DBG (fprintf (stderr, "Setting cursor scale factor: \t%f\n", (float) magnifier->cursor_scale_factor)); 01551 magnifier_transform_cursor (magnifier); 01552 break; 01553 case MAGNIFIER_CURSOR_COLOR_PROP: 01554 magnifier->cursor_color = BONOBO_ARG_GET_GENERAL (arg, 01555 TC_CORBA_unsigned_long, 01556 CORBA_unsigned_long, 01557 NULL); 01558 magnifier_transform_cursor (magnifier); 01559 DBG (fprintf (stderr, "Setting cursor color: \t%u\n", (unsigned) magnifier->cursor_color)); 01560 break; 01561 case MAGNIFIER_CURSOR_HOTSPOT_PROP: 01562 magnifier->cursor_hotspot = BONOBO_ARG_GET_GENERAL (arg, 01563 TC_GNOME_Magnifier_Point, 01564 GNOME_Magnifier_Point, 01565 NULL); 01566 /* TODO: notify zoomers */ 01567 /* FIXME: don't call init_cursor, it overwrites this property! */ 01568 magnifier_transform_cursor (magnifier); 01569 break; 01570 case MAGNIFIER_CURSOR_DEFAULT_SIZE_PROP: 01571 bonobo_exception_set (ev, ex_Bonobo_PropertyBag_ReadOnly); 01572 break; 01573 case MAGNIFIER_CROSSWIRE_SIZE_PROP: 01574 magnifier->crosswire_size = BONOBO_ARG_GET_INT (arg); 01575 DBG (fprintf (stderr, "Setting crosswire size: \t%d\n", magnifier->crosswire_size)); 01576 magnifier_zoom_regions_update_pointer (magnifier); 01577 break; 01578 case MAGNIFIER_CROSSWIRE_LENGTH_PROP: 01579 magnifier->crosswire_length = BONOBO_ARG_GET_INT (arg); 01580 DBG (fprintf (stderr, "Setting crosswire length: \t%d\n", magnifier->crosswire_length)); 01581 /* FIXME: The call below forces the repaint of all the screen, 01582 * but I can't figure a better solution right now to the case 01583 * where the crosswire lenght decrease */ 01584 magnifier_zoom_regions_mark_dirty (magnifier, rect_bounds); 01585 break; 01586 case MAGNIFIER_CROSSWIRE_CLIP_PROP: 01587 magnifier->crosswire_clip = BONOBO_ARG_GET_BOOLEAN (arg); 01588 DBG (fprintf (stderr, "Setting crosswire clip: \t%s\n", magnifier->crosswire_clip ? "true" : "false")); 01589 magnifier_zoom_regions_update_pointer (magnifier); 01590 break; 01591 case MAGNIFIER_CROSSWIRE_COLOR_PROP: 01592 magnifier->crosswire_color = BONOBO_ARG_GET_LONG (arg); 01593 DBG (fprintf (stderr, "Setting crosswire size: \t%ld\n", (long) magnifier->crosswire_color)); 01594 break; 01595 default: 01596 bonobo_exception_set (ev, ex_Bonobo_PropertyBag_NotFound); 01597 break; 01598 }; 01599 } 01600 01601 static void 01602 magnifier_do_dispose (Magnifier *magnifier) 01603 { 01604 /* FIXME: this is dead ropey code structuring */ 01605 bonobo_activation_active_server_unregister ( 01606 MAGNIFIER_OAFIID, BONOBO_OBJREF (magnifier)); 01607 01608 if (magnifier->zoom_regions_dbus) 01609 g_list_free (magnifier->zoom_regions_dbus); 01610 if (magnifier->zoom_regions) 01611 g_list_free (magnifier->zoom_regions); 01612 magnifier->zoom_regions = NULL; 01613 magnifier->zoom_regions_dbus = NULL; 01614 01615 bonobo_main_quit (); 01616 } 01617 01618 static void 01619 magnifier_gobject_dispose (GObject *object) 01620 { 01621 magnifier_do_dispose (MAGNIFIER (object)); 01622 01623 BONOBO_CALL_PARENT (G_OBJECT_CLASS, dispose, (object)); 01624 } 01625 01626 static inline 01627 CORBA_boolean 01628 impl_magnifier_support_colorblind_filters (PortableServer_Servant _servant G_GNUC_UNUSED, 01629 CORBA_Environment *ev G_GNUC_UNUSED) 01630 { 01631 #ifdef HAVE_COLORBLIND 01632 return CORBA_TRUE; 01633 #else 01634 return CORBA_FALSE; 01635 #endif 01636 } 01637 01638 static void 01639 impl_magnifier_hide_cursor (PortableServer_Servant servant, 01640 CORBA_Environment *ev) 01641 { 01642 Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant)); 01643 01644 gmag_gs_hide_cursor (magnifier); 01645 } 01646 01647 static void 01648 impl_magnifier_show_cursor (PortableServer_Servant servant, 01649 CORBA_Environment *ev) 01650 { 01651 Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant)); 01652 01653 gmag_gs_show_cursor (magnifier); 01654 } 01655 01656 static 01657 CORBA_boolean 01658 impl_magnifier_full_screen_capable (PortableServer_Servant servant, 01659 CORBA_Environment * ev) 01660 { 01661 Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant)); 01662 01663 if ((strcmp (magnifier->source_display_name, 01664 magnifier->target_display_name) != 0) || 01665 gmag_gs_use_compositor (magnifier)) 01666 return CORBA_TRUE; 01667 01668 return CORBA_FALSE; 01669 } 01670 01671 gboolean 01672 impl_dbus_magnifier_full_screen_capable (Magnifier *magnifier) 01673 { 01674 if ((strcmp (magnifier->source_display_name, 01675 magnifier->target_display_name) != 0) || 01676 gmag_gs_use_compositor (magnifier)) { 01677 return TRUE; 01678 } 01679 01680 return FALSE; 01681 } 01682 01683 gboolean 01684 impl_dbus_magnifier_hide_cursor (Magnifier *magnifier) 01685 { 01686 gmag_gs_hide_cursor (magnifier); 01687 01688 return TRUE; 01689 } 01690 01691 gboolean 01692 impl_dbus_magnifier_show_cursor (Magnifier *magnifier) 01693 { 01694 gmag_gs_show_cursor (magnifier); 01695 01696 return TRUE; 01697 } 01698 01699 gboolean 01700 impl_dbus_magnifier_support_colorblind_filters (Magnifier *magnifier) 01701 { 01702 #ifdef HAVE_COLORBLIND 01703 return TRUE; 01704 #else 01705 return FALSE; 01706 #endif 01707 } 01708 01709 gchar* 01710 impl_dbus_magnifier_create_zoom_region (Magnifier *magnifier, 01711 const double zx, 01712 const double zy, 01713 const gint32 **roi, 01714 const gint32 **viewport) 01715 { 01716 ZoomRegion *zoom_region = zoom_region_new(); 01717 01718 DBG (fprintf (stderr, "Create zoom region: \tzoom %f,%f, viewport %d,%d to %d,%d\n", (float) zx, (float) zy, (*viewport)[0]/*x1*/, (*viewport)[1]/*y1*/, (*viewport)[2]/*x2*/, (*viewport)[3]/*y3*/)); 01719 01720 /* FIXME: 01721 * shouldn't do this here, since it causes the region to get 01722 * mapped onto the parent, if if it's not explicitly added! 01723 */ 01724 DBG(g_message ("creating zoom region with parent %p", magnifier)); 01725 zoom_region->priv->parent = magnifier; 01726 01727 impl_dbus_zoom_region_set_mag_factor (zoom_region, zx, zy); 01728 01729 impl_dbus_zoom_region_move_resize (zoom_region, viewport); 01730 01731 impl_dbus_zoom_region_set_roi (zoom_region, roi); 01732 01733 gtk_widget_set_size_request (magnifier->priv->canvas, 01734 (*viewport)[2] - (*viewport)[0], 01735 (*viewport)[3] - (*viewport)[1]); 01736 gtk_widget_show (magnifier->priv->canvas); 01737 gtk_widget_show (magnifier->priv->w); 01738 01739 g_hash_table_insert (zoom_hash, g_strdup(zoom_region->object_path), zoom_region); 01740 01741 return g_strdup (zoom_region->object_path); 01742 } 01743 01744 gchar** 01745 impl_dbus_magnifier_get_zoom_regions (Magnifier *magnifier) 01746 { 01747 ZoomRegion *zoom_region; 01748 gchar **list; 01749 int i, len; 01750 01751 len = g_list_length (magnifier->zoom_regions); 01752 list = g_malloc0 (sizeof (gchar *) * len); 01753 for (i = 0; i < len; ++i) { 01754 zoom_region = g_list_nth_data (magnifier->zoom_regions_dbus, i); 01755 list[i] = g_strdup (zoom_region->object_path); 01756 } 01757 01758 DBG (fprintf (stderr, "Get zoom regions: \t%d\n", len)); 01759 01760 return list; 01761 } 01762 01763 gboolean 01764 impl_dbus_magnifier_add_zoom_region (Magnifier *magnifier, gchar *zoom_region_path) 01765 { 01766 if (!magnifier->source_initialized) 01767 { 01768 magnifier_set_extension_listeners (magnifier, magnifier_get_root (magnifier)); 01769 } 01770 01771 /* FIXME: this needs proper lifecycle management */ 01772 ZoomRegion *zoom_region = g_hash_table_lookup (zoom_hash, zoom_region_path); 01773 magnifier->zoom_regions = g_list_append (magnifier->zoom_regions, BONOBO_OBJREF (zoom_region)); 01774 magnifier->zoom_regions_dbus = g_list_append (magnifier->zoom_regions_dbus, zoom_region); 01775 g_hash_table_remove (zoom_hash, zoom_region_path); 01776 gmag_gs_check_set_struts (magnifier); 01777 01778 return TRUE; 01779 } 01780 01781 gboolean 01782 impl_dbus_magnifier_clear_all_zoom_regions (Magnifier *magnifier) 01783 { 01784 g_list_foreach (magnifier->zoom_regions_dbus, 01785 magnifier_dbus_unref_zoom_region, magnifier); 01786 g_list_foreach (magnifier->zoom_regions, 01787 magnifier_unref_zoom_region, magnifier); 01788 g_list_free (magnifier->zoom_regions); 01789 g_list_free (magnifier->zoom_regions_dbus); 01790 magnifier->zoom_regions = NULL; 01791 magnifier->zoom_regions_dbus = NULL; 01792 01793 return TRUE; 01794 } 01795 01796 gboolean 01797 impl_dbus_magnifier_dispose (Magnifier *magnifier) 01798 { 01799 magnifier_do_dispose (magnifier); 01800 01801 return TRUE; 01802 } 01803 01804 static void 01805 impl_magnifier_set_source_display (PortableServer_Servant servant, 01806 const CORBA_char *display, 01807 CORBA_Environment *ev) 01808 { 01809 Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant)); 01810 BonoboArg *arg = bonobo_arg_new (BONOBO_ARG_STRING); 01811 gchar *full_display_string; 01812 01813 full_display_string = g_strdup (display); 01814 if (strcmp (full_display_string, "") == 0) 01815 full_display_string = (gchar *) g_getenv ("DISPLAY"); 01816 01817 BONOBO_ARG_SET_STRING (arg, full_display_string); 01818 01819 DBG (fprintf (stderr, "Set source display: \t%s\n", 01820 full_display_string)); 01821 01822 if (strcmp (full_display_string, magnifier->source_display_name)) { 01823 magnifier_set_property (magnifier->property_bag, 01824 arg, 01825 MAGNIFIER_SOURCE_DISPLAY_PROP, 01826 ev, 01827 magnifier); 01828 } 01829 else 01830 { 01831 DBG (fprintf (stderr, "Attempt to set source to same value as previous: %s\n", 01832 full_display_string)); 01833 } 01834 bonobo_arg_release (arg); 01835 } 01836 01837 static void 01838 impl_magnifier_set_target_display (PortableServer_Servant servant, 01839 const CORBA_char *display, 01840 CORBA_Environment *ev) 01841 { 01842 Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant)); 01843 BonoboArg *arg = bonobo_arg_new (BONOBO_ARG_STRING); 01844 gchar *full_display_string; 01845 01846 full_display_string = g_strdup (display); 01847 if (strcmp (full_display_string, "") == 0) 01848 full_display_string = (gchar *) g_getenv ("DISPLAY"); 01849 01850 BONOBO_ARG_SET_STRING (arg, full_display_string); 01851 01852 DBG (fprintf (stderr, "Set target display: \t%s\n", 01853 full_display_string)); 01854 01855 if (strcmp (full_display_string, magnifier->target_display_name)) 01856 { 01857 magnifier_set_property (magnifier->property_bag, 01858 arg, 01859 MAGNIFIER_TARGET_DISPLAY_PROP, 01860 ev, 01861 magnifier); 01862 } 01863 else 01864 { 01865 DBG (fprintf (stderr, "Attempt to set target to same value as previous: %s\n", 01866 full_display_string)); 01867 } 01868 bonobo_arg_release (arg); 01869 } 01870 01871 static 01872 CORBA_string 01873 impl_magnifier_get_source_display (PortableServer_Servant servant, 01874 CORBA_Environment *ev) 01875 { 01876 Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant)); 01877 DBG (fprintf (stderr, "Get source display: \t%s\n", magnifier->source_display_name)); 01878 01879 return CORBA_string_dup (magnifier->source_display_name ? magnifier->source_display_name : ""); 01880 } 01881 01882 static 01883 CORBA_string 01884 impl_magnifier_get_target_display (PortableServer_Servant servant, 01885 CORBA_Environment *ev) 01886 { 01887 Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant)); 01888 DBG (fprintf (stderr, "Get target display: \t%s\n", 01889 magnifier->target_display_name)); 01890 01891 return CORBA_string_dup (magnifier->target_display_name ? magnifier->target_display_name : ""); 01892 } 01893 01894 static GNOME_Magnifier_ZoomRegion 01895 impl_magnifier_create_zoom_region (PortableServer_Servant servant, 01896 const CORBA_float zx, 01897 const CORBA_float zy, 01898 const GNOME_Magnifier_RectBounds *roi, 01899 const GNOME_Magnifier_RectBounds *viewport, 01900 CORBA_Environment *ev) 01901 { 01902 Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant)); 01903 CORBA_any viewport_any; 01904 ZoomRegion *zoom_region = zoom_region_new (); 01905 Bonobo_PropertyBag properties; 01906 GNOME_Magnifier_ZoomRegion retval; 01907 01908 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)); 01909 01910 /* FIXME: 01911 * shouldn't do this here, since it causes the region to get 01912 * mapped onto the parent, if if it's not explicitly added! 01913 */ 01914 DBG(g_message ("creating zoom region with parent %p", magnifier)); 01915 zoom_region->priv->parent = magnifier; 01916 01917 retval = BONOBO_OBJREF (zoom_region); 01918 01919 /* XXX: should check ev after each call, below */ 01920 CORBA_exception_init (ev); 01921 GNOME_Magnifier_ZoomRegion_setMagFactor (retval, zx, zy, ev); 01922 01923 if (ev->_major != CORBA_NO_EXCEPTION) 01924 fprintf (stderr, "EXCEPTION setMagFactor\n"); 01925 01926 CORBA_exception_init (ev); 01927 properties = GNOME_Magnifier_ZoomRegion_getProperties (retval, ev); 01928 if (ev->_major != CORBA_NO_EXCEPTION) 01929 fprintf (stderr, "EXCEPTION getProperties\n"); 01930 01931 viewport_any._type = TC_GNOME_Magnifier_RectBounds; 01932 viewport_any._value = (gpointer) viewport; 01933 Bonobo_PropertyBag_setValue ( 01934 properties, "viewport", &viewport_any, ev); 01935 01936 GNOME_Magnifier_ZoomRegion_setROI (retval, roi, ev); 01937 if (ev->_major != CORBA_NO_EXCEPTION) 01938 fprintf (stderr, "EXCEPTION setROI\n"); 01939 01940 CORBA_exception_init (ev); 01941 01942 gtk_widget_set_size_request (magnifier->priv->canvas, 01943 viewport->x2 - viewport->x1, 01944 viewport->y2 - viewport->y1); 01945 gtk_widget_show (magnifier->priv->canvas); 01946 gtk_widget_show (magnifier->priv->w); 01947 01948 bonobo_object_release_unref (properties, ev); 01949 01950 return CORBA_Object_duplicate (retval, ev); 01951 } 01952 01953 static 01954 CORBA_boolean 01955 impl_magnifier_add_zoom_region (PortableServer_Servant servant, 01956 const GNOME_Magnifier_ZoomRegion region, 01957 CORBA_Environment * ev) 01958 { 01959 Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant)); 01960 01961 if (!magnifier->source_initialized) 01962 { 01963 magnifier_set_extension_listeners (magnifier, magnifier_get_root (magnifier)); 01964 } 01965 01966 /* FIXME: this needs proper lifecycle management */ 01967 magnifier->zoom_regions = g_list_append (magnifier->zoom_regions, region); 01968 gmag_gs_check_set_struts (magnifier); 01969 01970 return CORBA_TRUE; 01971 } 01972 01973 static Bonobo_PropertyBag 01974 impl_magnifier_get_properties (PortableServer_Servant servant, 01975 CORBA_Environment *ev) 01976 { 01977 Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant)); 01978 return bonobo_object_dup_ref ( 01979 BONOBO_OBJREF (magnifier->property_bag), ev); 01980 } 01981 01982 GNOME_Magnifier_ZoomRegionList * 01983 impl_magnifier_get_zoom_regions (PortableServer_Servant servant, 01984 CORBA_Environment * ev) 01985 { 01986 Magnifier *magnifier = 01987 MAGNIFIER (bonobo_object_from_servant (servant)); 01988 01989 GNOME_Magnifier_ZoomRegionList *list; 01990 CORBA_Object objref; 01991 int i, len; 01992 01993 len = g_list_length (magnifier->zoom_regions); 01994 list = GNOME_Magnifier_ZoomRegionList__alloc (); 01995 list->_length = len; 01996 list->_buffer = 01997 GNOME_Magnifier_ZoomRegionList_allocbuf (list->_length); 01998 for (i = 0; i < len; ++i) { 01999 objref = g_list_nth_data (magnifier->zoom_regions, i); 02000 list->_buffer [i] = 02001 CORBA_Object_duplicate (objref, ev); 02002 } 02003 CORBA_sequence_set_release (list, CORBA_TRUE); 02004 02005 DBG (fprintf (stderr, "Get zoom regions: \t%d\n", len)); 02006 02007 return list; 02008 } 02009 02010 static void 02011 impl_magnifier_clear_all_zoom_regions (PortableServer_Servant servant, 02012 CORBA_Environment * ev) 02013 { 02014 Magnifier *magnifier = MAGNIFIER (bonobo_object_from_servant (servant)); 02015 fprintf (stderr, "Clear all zoom regions.\n"); 02016 02017 g_list_foreach (magnifier->zoom_regions, 02018 magnifier_unref_zoom_region, magnifier); 02019 g_list_free (magnifier->zoom_regions); 02020 magnifier->zoom_regions = NULL; 02021 magnifier->zoom_regions_dbus = NULL; 02022 } 02023 02024 static void 02025 impl_magnifier_dispose (PortableServer_Servant servant, 02026 CORBA_Environment *ev) 02027 { 02028 magnifier_do_dispose ( 02029 MAGNIFIER (bonobo_object_from_servant (servant))); 02030 } 02031 02032 static void 02033 magnifier_class_init (MagnifierClass *klass) 02034 { 02035 GObjectClass * object_class = (GObjectClass *) klass; 02036 POA_GNOME_Magnifier_Magnifier__epv *epv = &klass->epv; 02037 parent_class = g_type_class_peek (BONOBO_TYPE_OBJECT); /* needed by BONOBO_CALL_PARENT! */ 02038 02039 object_class->dispose = magnifier_gobject_dispose; 02040 02041 epv->fullScreenCapable = impl_magnifier_full_screen_capable; 02042 epv->hideCursor = impl_magnifier_hide_cursor; 02043 epv->showCursor = impl_magnifier_show_cursor; 02044 epv->supportColorblindFilters = impl_magnifier_support_colorblind_filters; 02045 epv->_set_SourceDisplay = impl_magnifier_set_source_display; 02046 epv->_set_TargetDisplay = impl_magnifier_set_target_display; 02047 epv->_get_SourceDisplay = impl_magnifier_get_source_display; 02048 epv->_get_TargetDisplay = impl_magnifier_get_target_display; 02049 epv->getProperties = impl_magnifier_get_properties; 02050 epv->getZoomRegions = impl_magnifier_get_zoom_regions; 02051 epv->createZoomRegion = impl_magnifier_create_zoom_region; 02052 epv->addZoomRegion = impl_magnifier_add_zoom_region; 02053 epv->clearAllZoomRegions = impl_magnifier_clear_all_zoom_regions; 02054 epv->dispose = impl_magnifier_dispose; 02055 } 02056 02057 static void 02058 magnifier_properties_init (Magnifier *magnifier) 02059 { 02060 BonoboArg *def; 02061 GNOME_Magnifier_RectBounds rect_bounds; 02062 gchar *display_env; 02063 02064 magnifier->property_bag = 02065 bonobo_property_bag_new_closure ( 02066 g_cclosure_new_object ( 02067 G_CALLBACK (magnifier_get_property), 02068 G_OBJECT (magnifier)), 02069 g_cclosure_new_object ( 02070 G_CALLBACK (magnifier_set_property), 02071 G_OBJECT (magnifier))); 02072 /* Aggregate so magnifier implements Bonobo_PropertyBag */ 02073 bonobo_object_add_interface (BONOBO_OBJECT (magnifier), 02074 BONOBO_OBJECT (magnifier->property_bag)); 02075 02076 def = bonobo_arg_new (BONOBO_ARG_STRING); 02077 display_env = getenv ("DISPLAY"); 02078 BONOBO_ARG_SET_STRING (def, display_env); 02079 02080 bonobo_property_bag_add (magnifier->property_bag, 02081 "source-display-screen", 02082 MAGNIFIER_SOURCE_DISPLAY_PROP, 02083 BONOBO_ARG_STRING, 02084 def, 02085 "source display screen", 02086 Bonobo_PROPERTY_WRITEABLE); 02087 02088 bonobo_property_bag_add (magnifier->property_bag, 02089 "target-display-screen", 02090 MAGNIFIER_TARGET_DISPLAY_PROP, 02091 BONOBO_ARG_STRING, 02092 def, 02093 "target display screen", 02094 Bonobo_PROPERTY_WRITEABLE); 02095 02096 bonobo_arg_release (def); 02097 02098 magnifier_init_display (magnifier, display_env, TRUE); 02099 magnifier_init_display (magnifier, display_env, FALSE); 02100 02101 magnifier_get_display_rect_bounds (magnifier, &rect_bounds, FALSE); 02102 def = bonobo_arg_new_from (TC_GNOME_Magnifier_RectBounds, &rect_bounds); 02103 02104 bonobo_property_bag_add (magnifier->property_bag, 02105 "source-display-bounds", 02106 MAGNIFIER_SOURCE_SIZE_PROP, 02107 TC_GNOME_Magnifier_RectBounds, 02108 def, 02109 "source display bounds/size", 02110 Bonobo_PROPERTY_READABLE | 02111 Bonobo_PROPERTY_WRITEABLE); 02112 bonobo_arg_release (def); 02113 02114 magnifier_get_display_rect_bounds (magnifier, &rect_bounds, TRUE); 02115 def = bonobo_arg_new_from (TC_GNOME_Magnifier_RectBounds, &rect_bounds); 02116 02117 bonobo_property_bag_add (magnifier->property_bag, 02118 "target-display-bounds", 02119 MAGNIFIER_TARGET_SIZE_PROP, 02120 TC_GNOME_Magnifier_RectBounds, 02121 def, 02122 "target display bounds/size", 02123 Bonobo_PROPERTY_READABLE | 02124 Bonobo_PROPERTY_WRITEABLE); 02125 bonobo_arg_release (def); 02126 02127 bonobo_property_bag_add (magnifier->property_bag, 02128 "cursor-set", 02129 MAGNIFIER_CURSOR_SET_PROP, 02130 BONOBO_ARG_STRING, 02131 NULL, 02132 "name of cursor set", 02133 Bonobo_PROPERTY_READABLE | 02134 Bonobo_PROPERTY_WRITEABLE); 02135 02136 def = bonobo_arg_new (BONOBO_ARG_INT); 02137 BONOBO_ARG_SET_INT (def, 64); 02138 02139 bonobo_property_bag_add (magnifier->property_bag, 02140 "cursor-size", 02141 MAGNIFIER_CURSOR_SIZE_PROP, 02142 BONOBO_ARG_INT, 02143 def, 02144 "cursor size, in pixels", 02145 Bonobo_PROPERTY_READABLE | 02146 Bonobo_PROPERTY_WRITEABLE); 02147 bonobo_arg_release (def); 02148 02149 bonobo_property_bag_add (magnifier->property_bag, 02150 "cursor-scale-factor", 02151 MAGNIFIER_CURSOR_ZOOM_PROP, 02152 BONOBO_ARG_FLOAT, 02153 NULL, 02154 "scale factor for cursors (overrides size)", 02155 Bonobo_PROPERTY_READABLE | 02156 Bonobo_PROPERTY_WRITEABLE); 02157 02158 bonobo_property_bag_add (magnifier->property_bag, 02159 "cursor-color", 02160 MAGNIFIER_CURSOR_COLOR_PROP, 02161 TC_CORBA_unsigned_long, 02162 NULL, 02163 "foreground color for 1-bit cursors, as ARGB", 02164 Bonobo_PROPERTY_READABLE | 02165 Bonobo_PROPERTY_WRITEABLE); 02166 02167 bonobo_property_bag_add (magnifier->property_bag, 02168 "cursor-hotspot", 02169 MAGNIFIER_CURSOR_HOTSPOT_PROP, 02170 TC_GNOME_Magnifier_Point, 02171 NULL, 02172 "hotspot relative to cursor's upper-left-corner, at default resolition", 02173 Bonobo_PROPERTY_READABLE | 02174 Bonobo_PROPERTY_WRITEABLE); 02175 02176 bonobo_property_bag_add (magnifier->property_bag, 02177 "cursor-default-size", 02178 MAGNIFIER_CURSOR_DEFAULT_SIZE_PROP, 02179 BONOBO_ARG_INT, 02180 NULL, 02181 "default size of current cursor set", 02182 Bonobo_PROPERTY_READABLE); 02183 02184 bonobo_property_bag_add (magnifier->property_bag, 02185 "crosswire-size", 02186 MAGNIFIER_CROSSWIRE_SIZE_PROP, 02187 BONOBO_ARG_INT, 02188 NULL, 02189 "thickness of crosswire cursor, in target pixels", 02190 Bonobo_PROPERTY_READABLE | 02191 Bonobo_PROPERTY_WRITEABLE); 02192 02193 bonobo_property_bag_add (magnifier->property_bag, 02194 "crosswire-length", 02195 MAGNIFIER_CROSSWIRE_LENGTH_PROP, 02196 BONOBO_ARG_INT, 02197 NULL, 02198 "length of crosswire cursor, in target pixels", 02199 Bonobo_PROPERTY_READABLE | 02200 Bonobo_PROPERTY_WRITEABLE); 02201 02202 bonobo_property_bag_add (magnifier->property_bag, 02203 "crosswire-color", 02204 MAGNIFIER_CROSSWIRE_COLOR_PROP, 02205 BONOBO_ARG_LONG, 02206 NULL, 02207 "color of crosswire, as A-RGB; note that alpha is required. (use 0 for XOR wire)", 02208 Bonobo_PROPERTY_READABLE | 02209 Bonobo_PROPERTY_WRITEABLE); 02210 02211 bonobo_property_bag_add (magnifier->property_bag, 02212 "crosswire-clip", 02213 MAGNIFIER_CROSSWIRE_CLIP_PROP, 02214 BONOBO_ARG_BOOLEAN, 02215 NULL, 02216 "whether to inset the cursor over the crosswire or not", 02217 Bonobo_PROPERTY_READABLE | 02218 Bonobo_PROPERTY_WRITEABLE); 02219 } 02220 02221 static void 02222 magnifier_init_window (Magnifier *magnifier, GdkScreen *screen) 02223 { 02224 GtkWindowType mag_win_type = GTK_WINDOW_TOPLEVEL; 02225 if (_is_override_redirect || gmag_gs_use_compositor (magnifier)) 02226 mag_win_type = GTK_WINDOW_POPUP; 02227 02228 magnifier->priv->w = 02229 g_object_connect (gtk_widget_new (gtk_window_get_type (), 02230 "user_data", NULL, 02231 "can_focus", FALSE, 02232 "type", mag_win_type, 02233 "title", "magnifier", 02234 "allow_grow", TRUE, 02235 "allow_shrink", TRUE, 02236 "border_width", 0, 02237 NULL), 02238 "signal::realize", magnifier_realize, NULL, 02239 "signal::size_allocate", magnifier_size_allocate, NULL, 02240 "signal::destroy", magnifier_exit, NULL, 02241 NULL); 02242 gtk_window_set_screen (GTK_WINDOW (magnifier->priv->w), screen); 02243 magnifier->priv->canvas = gtk_fixed_new (); 02244 gtk_container_add (GTK_CONTAINER (magnifier->priv->w), 02245 magnifier->priv->canvas); 02246 magnifier->priv->root = NULL; 02247 } 02248 02249 static void 02250 magnifier_init (Magnifier *magnifier) 02251 { 02252 magnifier->priv = g_new0 (MagnifierPrivate, 1); 02253 magnifier_properties_init (magnifier); 02254 magnifier->zoom_regions = NULL; 02255 magnifier->zoom_regions_dbus = NULL; 02256 magnifier->source_screen_num = 0; 02257 magnifier->target_screen_num = 0; 02258 magnifier->source_display_name = g_strdup (":0.0"); 02259 magnifier->target_display_name = g_strdup (":0.0"); 02260 magnifier->cursor_size_x = 0; 02261 magnifier->cursor_size_y = 0; 02262 magnifier->cursor_scale_factor = 1.0F; 02263 magnifier->cursor_color = 0xFF000000; 02264 magnifier->crosswire_size = 1; 02265 magnifier->crosswire_length = 0; 02266 magnifier->crosswire_color = 0; 02267 magnifier->crosswire_clip = FALSE; 02268 magnifier->cursor_hotspot.x = 0; 02269 magnifier->cursor_hotspot.y = 0; 02270 magnifier->target_bounds.x1 = 0; 02271 magnifier->target_bounds.y1 = 0; 02272 magnifier->target_bounds.x2 = 0; 02273 magnifier->target_bounds.y2 = 0; 02274 magnifier->priv->cursor = NULL; 02275 magnifier->priv->w = NULL; 02276 magnifier->priv->use_source_cursor = TRUE; 02277 magnifier->priv->cursorlist = NULL; 02278 magnifier->priv->source_drawable = NULL; 02279 magnifier->priv->overlay = NULL; 02280 magnifier_init_window (magnifier, 02281 gdk_display_get_screen (magnifier->target_display, 02282 magnifier->target_screen_num)); 02283 magnifier_init_cursor_set (magnifier, "default"); 02284 02285 mag_timing.process = g_timer_new (); 02286 mag_timing.frame = g_timer_new (); 02287 mag_timing.scale = g_timer_new (); 02288 mag_timing.idle = g_timer_new (); 02289 #ifdef DEBUG_CLIENT_CALLS 02290 client_debug = (g_getenv ("MAG_CLIENT_DEBUG") != NULL); 02291 #endif 02292 02293 zoom_hash = g_hash_table_new (g_str_hash, g_str_equal); 02294 } 02295 02296 GdkDrawable * 02297 magnifier_get_cursor (Magnifier *magnifier) 02298 { 02299 if (magnifier->priv->cursor == NULL) { 02300 if ((fixes_event_base == 0) && 02301 strcmp (magnifier->cursor_set, "none")) 02302 { 02303 GdkPixbuf *pixbuf; 02304 gchar *default_cursor_filename = 02305 g_strconcat (CURSORSDIR, "/", "default-cursor.xpm", NULL); 02306 pixbuf = gdk_pixbuf_new_from_file (default_cursor_filename, NULL); 02307 if (pixbuf) 02308 { 02309 magnifier_set_cursor_from_pixbuf (magnifier, pixbuf); 02310 g_object_unref (pixbuf); 02311 magnifier_transform_cursor (magnifier); 02312 } 02313 g_free (default_cursor_filename); 02314 } else { 02315 GdkPixbuf *cursor_pixbuf = gmag_cursor_get_source_pixbuf ( 02316 magnifier); 02317 magnifier_set_cursor_from_pixbuf (magnifier, cursor_pixbuf); 02318 if (cursor_pixbuf) g_object_unref (cursor_pixbuf); 02319 magnifier_transform_cursor (magnifier); 02320 } 02321 } 02322 return magnifier->priv->cursor; 02323 } 02324 02325 Magnifier * 02326 magnifier_new (gboolean override_redirect) 02327 { 02328 Magnifier *mag; 02329 MagLoginHelper *helper; 02330 GError *error = NULL; 02331 MagnifierClass *klass = NULL; 02332 DBusGProxy *driver_proxy; 02333 guint request_req; 02334 int ret; 02335 02336 _is_override_redirect = override_redirect; 02337 02338 mag = g_object_new (magnifier_get_type(), NULL); 02339 02340 _this_magnifier = mag; /* FIXME what about multiple instances? */ 02341 02342 helper = g_object_new (mag_login_helper_get_type (), NULL); 02343 mag_login_helper_set_magnifier (helper, mag); 02344 02345 bonobo_object_add_interface (bonobo_object (mag), 02346 BONOBO_OBJECT (helper)); 02347 02348 ret = bonobo_activation_active_server_register ( 02349 MAGNIFIER_OAFIID, BONOBO_OBJREF (mag)); 02350 if (ret != Bonobo_ACTIVATION_REG_SUCCESS) { 02351 if ( ret == Bonobo_ACTIVATION_REG_ALREADY_ACTIVE) 02352 { 02353 printf("An instance of magnifier is already active. Exiting Program.\n"); 02354 exit(0); 02355 } else 02356 g_error ("Error registering magnifier server.\n"); 02357 } 02358 02359 klass = MAGNIFIER_GET_CLASS (mag); 02360 02361 klass->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); 02362 if (klass->connection == NULL) { 02363 g_warning ("Unable to connect to dbus: %s", error->message); 02364 g_error_free (error); 02365 return NULL; 02366 } 02367 02368 dbus_g_object_type_install_info (MAGNIFIER_TYPE, &dbus_glib_impl_dbus_magnifier_object_info); 02369 02370 dbus_g_connection_register_g_object (klass->connection, "/org/freedesktop/gnome/Magnifier", 02371 G_OBJECT (_this_magnifier)); 02372 02373 driver_proxy = dbus_g_proxy_new_for_name (klass->connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, 02374 DBUS_INTERFACE_DBUS); 02375 02376 if (!org_freedesktop_DBus_request_name (driver_proxy, "org.freedesktop.gnome.Magnifier", 0, &request_req, 02377 &error)) { 02378 g_warning ("Unable to register service: %s", error->message); 02379 g_error_free (error); 02380 } 02381 02382 g_timeout_add (500, magnifier_reset_struts_at_idle, mag); 02383 g_timeout_add (500, gmag_gs_reset_overlay_at_idle, mag); 02384 02385 return mag; 02386 } 02387 02388 BONOBO_TYPE_FUNC_FULL (Magnifier, 02389 GNOME_Magnifier_Magnifier, 02390 BONOBO_TYPE_OBJECT, 02391 magnifier) 02392