/** * gdk_x11_screen_get_window_manager_name: * @screen: a #GdkScreen * * Returns the name of the window manager for @screen. * * Return value: the name of the window manager screen @screen, or * "unknown" if the window manager is unknown. The string is owned by GDK * and should not be freed. * * Since: 2.2 **/ const char* gdk_x11_screen_get_window_manager_name (GdkScreen *screen) { GdkX11Screen *x11_screen; GdkDisplay *display; x11_screen = GDK_X11_SCREEN (screen); display = x11_screen->display; if (!G_LIKELY (GDK_X11_DISPLAY (display)->trusted_client)) return x11_screen->window_manager_name; fetch_net_wm_check_window (screen); if (x11_screen->need_refetch_wm_name) { /* Get the name of the window manager */ x11_screen->need_refetch_wm_name = FALSE; g_free (x11_screen->window_manager_name); x11_screen->window_manager_name = g_strdup ("unknown"); if (x11_screen->wmspec_check_window != None) { Atom type; gint format; gulong n_items; gulong bytes_after; gchar *name; name = NULL; gdk_x11_display_error_trap_push (display); XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), x11_screen->wmspec_check_window, gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_NAME"), 0, G_MAXLONG, False, gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), &type, &format, &n_items, &bytes_after, (guchar **)&name); gdk_x11_display_error_trap_pop_ignored (display); if (name != NULL) { g_free (x11_screen->window_manager_name); x11_screen->window_manager_name = g_strdup (name); XFree (name); } } } return GDK_X11_SCREEN (screen)->window_manager_name; }
static gint gdk_x11_screen_get_height_mm (GdkScreen *screen) { g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); return HeightMMOfScreen (GDK_X11_SCREEN (screen)->xscreen); }
static GdkDisplay * gdk_x11_screen_get_display (GdkScreen *screen) { g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); return GDK_X11_SCREEN (screen)->display; }
static gint gdk_x11_screen_get_n_monitors (GdkScreen *screen) { g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); return GDK_X11_SCREEN (screen)->n_monitors; }
static GdkWindow * gdk_x11_screen_get_root_window (GdkScreen *screen) { g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); return GDK_X11_SCREEN (screen)->root_window; }
static gint gdk_x11_screen_get_width (GdkScreen *screen) { g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); return WidthOfScreen (GDK_X11_SCREEN (screen)->xscreen); }
static gint gdk_x11_screen_get_primary_monitor (GdkScreen *screen) { g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); return GDK_X11_SCREEN (screen)->primary_monitor; }
GdkScreen * _gdk_x11_screen_new (GdkDisplay *display, gint screen_number) { GdkScreen *screen; GdkX11Screen *x11_screen; GdkX11Display *display_x11 = GDK_X11_DISPLAY (display); screen = g_object_new (GDK_TYPE_X11_SCREEN, NULL); x11_screen = GDK_X11_SCREEN (screen); x11_screen->display = display; x11_screen->xdisplay = display_x11->xdisplay; x11_screen->xscreen = ScreenOfDisplay (display_x11->xdisplay, screen_number); x11_screen->screen_num = screen_number; x11_screen->xroot_window = RootWindow (display_x11->xdisplay,screen_number); x11_screen->wmspec_check_window = None; /* we want this to be always non-null */ x11_screen->window_manager_name = g_strdup ("unknown"); init_multihead (screen); init_randr_support (screen); _gdk_x11_screen_init_visuals (screen); _gdk_x11_screen_init_root_window (screen); return screen; }
static gboolean gdk_x11_screen_is_composited (GdkScreen *screen) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); return x11_screen->is_composited; }
static GdkVisual * gdk_x11_screen_get_rgba_visual (GdkScreen *screen) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); return x11_screen->rgba_visual; }
static void update_bounding_box (GdkScreen *screen) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); GdkX11Display *x11_display = GDK_X11_DISPLAY (x11_screen->display); gint i, x1, y1, x2, y2; x1 = y1 = G_MAXINT; x2 = y2 = G_MININT; for (i = 0; i < x11_display->monitors->len; i++) { GdkX11Monitor *monitor = x11_display->monitors->pdata[i]; GdkRectangle geometry; gdk_monitor_get_geometry (GDK_MONITOR (monitor), &geometry); x1 = MIN (x1, geometry.x); y1 = MIN (y1, geometry.y); x2 = MAX (x2, geometry.x + geometry.width); y2 = MAX (y2, geometry.y + geometry.height); } x11_screen->width = x2 - x1; x11_screen->height = y2 - y1; }
static void process_monitors_change (GdkScreen *screen) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); gint n_monitors; gint primary_monitor; GdkX11Monitor *monitors; gboolean changed; primary_monitor = x11_screen->primary_monitor; n_monitors = x11_screen->n_monitors; monitors = x11_screen->monitors; x11_screen->n_monitors = 0; x11_screen->monitors = NULL; init_multihead (screen); changed = !compare_monitors (monitors, n_monitors, x11_screen->monitors, x11_screen->n_monitors) || x11_screen->primary_monitor != primary_monitor; free_monitors (monitors, n_monitors); if (changed) g_signal_emit_by_name (screen, "monitors-changed"); }
static guint32 get_netwm_cardinal_property (GdkScreen *screen, const gchar *name) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); GdkAtom atom; guint32 prop = 0; Atom type; gint format; gulong nitems; gulong bytes_after; guchar *data; atom = gdk_atom_intern_static_string (name); if (!gdk_x11_screen_supports_net_wm_hint (screen, atom)) return 0; XGetWindowProperty (x11_screen->xdisplay, x11_screen->xroot_window, gdk_x11_get_xatom_by_name_for_display (GDK_SCREEN_DISPLAY (screen), name), 0, G_MAXLONG, False, XA_CARDINAL, &type, &format, &nitems, &bytes_after, &data); if (type == XA_CARDINAL) { prop = *(gulong *)data; XFree (data); } return prop; }
static gboolean gdk_x11_screen_get_setting (GdkScreen *screen, const gchar *name, GValue *value) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); const GValue *setting; if (x11_screen->xsettings == NULL) goto out; setting = g_hash_table_lookup (x11_screen->xsettings, name); if (setting == NULL) goto out; if (!g_value_transform (setting, value)) { g_warning ("Cannot transform xsetting %s of type %s to type %s\n", name, g_type_name (G_VALUE_TYPE (setting)), g_type_name (G_VALUE_TYPE (value))); goto out; } return TRUE; out: return _gdk_x11_get_xft_setting (screen, name, value); }
static void gdk_x11_screen_dispose (GObject *object) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (object); int i; for (i = 0; i < 32; ++i) { if (x11_screen->subwindow_gcs[i]) { XFreeGC (x11_screen->xdisplay, x11_screen->subwindow_gcs[i]); x11_screen->subwindow_gcs[i] = 0; } } _gdk_x11_xsettings_finish (x11_screen); if (x11_screen->root_window) _gdk_window_destroy (x11_screen->root_window, TRUE); for (i = 0; i < x11_screen->nvisuals; i++) g_object_run_dispose (G_OBJECT (x11_screen->visuals[i])); G_OBJECT_CLASS (gdk_x11_screen_parent_class)->dispose (object); x11_screen->xdisplay = NULL; x11_screen->xscreen = NULL; x11_screen->screen_num = -1; x11_screen->xroot_window = None; x11_screen->wmspec_check_window = None; }
void _gdk_x11_screen_get_edge_monitors (GdkScreen *screen, gint *top, gint *bottom, gint *left, gint *right) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); gint top_most_pos = x11_screen->height; gint left_most_pos = x11_screen->width; gint bottom_most_pos = 0; gint right_most_pos = 0; gint i; #ifdef HAVE_XFREE_XINERAMA XineramaScreenInfo *x_monitors; int x_n_monitors; #endif *top = *bottom = *left = *right = -1; #ifdef HAVE_XFREE_XINERAMA if (!XineramaIsActive (x11_screen->xdisplay)) return; x_monitors = XineramaQueryScreens (x11_screen->xdisplay, &x_n_monitors); if (x_n_monitors <= 0 || x_monitors == NULL) { if (x_monitors) XFree (x_monitors); return; } for (i = 0; i < x_n_monitors; i++) { if (left && left_most_pos > x_monitors[i].x_org) { left_most_pos = x_monitors[i].x_org; *left = i; } if (right && right_most_pos < x_monitors[i].x_org + x_monitors[i].width) { right_most_pos = x_monitors[i].x_org + x_monitors[i].width; *right = i; } if (top && top_most_pos > x_monitors[i].y_org) { top_most_pos = x_monitors[i].y_org; *top = i; } if (bottom && bottom_most_pos < x_monitors[i].y_org + x_monitors[i].height) { bottom_most_pos = x_monitors[i].y_org + x_monitors[i].height; *bottom = i; } } XFree (x_monitors); #endif }
static void gdk_x11_screen_dispose (GObject *object) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (object); int i; for (i = 0; i < 32; ++i) { if (x11_screen->subwindow_gcs[i]) { XFreeGC (x11_screen->xdisplay, x11_screen->subwindow_gcs[i]); x11_screen->subwindow_gcs[i] = 0; } } _gdk_x11_screen_events_uninit (GDK_SCREEN (object)); if (x11_screen->root_window) _gdk_window_destroy (x11_screen->root_window, TRUE); G_OBJECT_CLASS (gdk_x11_screen_parent_class)->dispose (object); x11_screen->xdisplay = NULL; x11_screen->xscreen = NULL; x11_screen->screen_num = -1; x11_screen->xroot_window = None; x11_screen->wmspec_check_window = None; }
static gint gdk_x11_screen_get_number (GdkScreen *screen) { g_return_val_if_fail (GDK_IS_SCREEN (screen), 0); return GDK_X11_SCREEN (screen)->screen_num; }
gboolean _gdk_x11_window_simulate_button (GdkWindow *window, gint x, gint y, guint button, /*1..3*/ GdkModifierType modifiers, GdkEventType button_pressrelease) { GdkScreen *screen; XButtonEvent xev = { 0, /* type */ 0, /* serial */ 1, /* send_event */ }; gboolean success; g_return_val_if_fail (button_pressrelease == GDK_BUTTON_PRESS || button_pressrelease == GDK_BUTTON_RELEASE, FALSE); g_return_val_if_fail (window != NULL, FALSE); if (!GDK_WINDOW_IS_MAPPED (window)) return FALSE; screen = gdk_window_get_screen (window); if (x < 0 && y < 0) { x = window->width / 2; y = window->height / 2; } /* Convert to impl coordinates */ x = x + window->abs_x; y = y + window->abs_y; xev.type = button_pressrelease == GDK_BUTTON_PRESS ? ButtonPress : ButtonRelease; xev.display = GDK_WINDOW_XDISPLAY (window); xev.window = GDK_WINDOW_XID (window); xev.root = RootWindow (xev.display, GDK_X11_SCREEN (screen)->screen_num); xev.subwindow = 0; xev.time = 0; xev.x = x; xev.y = y; xev.x_root = 0; xev.y_root = 0; xev.state = modifiers; xev.button = button; gdk_x11_display_error_trap_push (GDK_WINDOW_DISPLAY (window)); xev.same_screen = XTranslateCoordinates (xev.display, xev.window, xev.root, xev.x, xev.y, &xev.x_root, &xev.y_root, &xev.subwindow); if (!xev.subwindow) xev.subwindow = xev.window; success = xev.same_screen; success &= 0 != XWarpPointer (xev.display, None, xev.window, 0, 0, 0, 0, xev.x, xev.y); success &= 0 != XSendEvent (xev.display, xev.window, True, button_pressrelease == GDK_BUTTON_PRESS ? ButtonPressMask : ButtonReleaseMask, (XEvent*) &xev); XSync (xev.display, False); success &= 0 == gdk_x11_display_error_trap_pop(GDK_WINDOW_DISPLAY (window)); return success; }
static gint gdk_x11_screen_get_monitor_scale_factor (GdkScreen *screen, gint monitor_num) { GdkX11Screen *screen_x11 = GDK_X11_SCREEN (screen); return screen_x11->window_scale; }
static gchar * gdk_x11_screen_get_monitor_plug_name (GdkScreen *screen, gint monitor_num) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); return g_strdup (x11_screen->monitors[monitor_num].output_name); }
static gint gdk_x11_screen_get_monitor_height_mm (GdkScreen *screen, gint monitor_num) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); return x11_screen->monitors[monitor_num].height_mm; }
/* * It is important that we first request the selection * notification, and then setup the initial state of * is_composited to avoid a race condition here. */ void _gdk_x11_screen_setup (GdkScreen *screen) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); gdk_display_request_selection_notification (x11_screen->display, gdk_x11_xatom_to_atom_for_display (x11_screen->display, get_cm_atom (x11_screen))); x11_screen->is_composited = check_is_composited (x11_screen->display, x11_screen); }
/* * It is important that we first request the selection * notification, and then setup the initial state of * is_composited to avoid a race condition here. */ void _gdk_x11_screen_setup (GdkScreen *screen) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); x11_screen->cm_selection_atom = make_cm_atom (x11_screen->screen_num); gdk_display_request_selection_notification (x11_screen->display, x11_screen->cm_selection_atom); x11_screen->is_composited = check_is_composited (x11_screen->display, x11_screen); }
static void deinit_multihead (GdkScreen *screen) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); free_monitors (x11_screen->monitors, x11_screen->n_monitors); x11_screen->n_monitors = 0; x11_screen->monitors = NULL; }
void _gdk_x11_screen_get_edge_monitors (GdkScreen *screen, gint *top, gint *bottom, gint *left, gint *right) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); gint top_most_pos = HeightOfScreen (GDK_X11_SCREEN (screen)->xscreen); gint left_most_pos = WidthOfScreen (GDK_X11_SCREEN (screen)->xscreen); gint bottom_most_pos = 0; gint right_most_pos = 0; gint monitor_num; for (monitor_num = 0; monitor_num < x11_screen->n_monitors; monitor_num++) { gint monitor_x = x11_screen->monitors[monitor_num].geometry.x; gint monitor_y = x11_screen->monitors[monitor_num].geometry.y; gint monitor_max_x = monitor_x + x11_screen->monitors[monitor_num].geometry.width; gint monitor_max_y = monitor_y + x11_screen->monitors[monitor_num].geometry.height; if (left && left_most_pos > monitor_x) { left_most_pos = monitor_x; *left = monitor_num; } if (right && right_most_pos < monitor_max_x) { right_most_pos = monitor_max_x; *right = monitor_num; } if (top && top_most_pos > monitor_y) { top_most_pos = monitor_y; *top = monitor_num; } if (bottom && bottom_most_pos < monitor_max_y) { bottom_most_pos = monitor_max_y; *bottom = monitor_num; } } }
static void fetch_net_wm_check_window (GdkScreen *screen) { GdkX11Screen *x11_screen; GdkDisplay *display; Window window; GTimeVal tv; gint error; x11_screen = GDK_X11_SCREEN (screen); display = x11_screen->display; g_return_if_fail (GDK_X11_DISPLAY (display)->trusted_client); if (x11_screen->wmspec_check_window != None) return; /* already have it */ g_get_current_time (&tv); if (ABS (tv.tv_sec - x11_screen->last_wmspec_check_time) < 15) return; /* we've checked recently */ window = get_net_supporting_wm_check (x11_screen, x11_screen->xroot_window); if (window == None) return; if (window != get_net_supporting_wm_check (x11_screen, window)) return; gdk_x11_display_error_trap_push (display); /* Find out if this WM goes away, so we can reset everything. */ XSelectInput (x11_screen->xdisplay, window, StructureNotifyMask); error = gdk_x11_display_error_trap_pop (display); if (!error) { /* We check the window property again because after XGetWindowProperty() * and before XSelectInput() the window may have been recycled in such a * way that XSelectInput() doesn't fail but the window is no longer what * we want. */ if (window != get_net_supporting_wm_check (x11_screen, window)) return; x11_screen->wmspec_check_window = window; x11_screen->last_wmspec_check_time = tv.tv_sec; x11_screen->need_refetch_net_supported = TRUE; x11_screen->need_refetch_wm_name = TRUE; /* Careful, reentrancy */ _gdk_x11_screen_window_manager_changed (screen); } }
static gboolean gdk_x11_screen_is_composited (GdkScreen *screen) { GdkX11Screen *x11_screen; g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE); x11_screen = GDK_X11_SCREEN (screen); return x11_screen->is_composited; }
static GdkVisual * gdk_x11_screen_get_rgba_visual (GdkScreen *screen) { GdkX11Screen *x11_screen; g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); x11_screen = GDK_X11_SCREEN (screen); return x11_screen->rgba_visual; }
static void _gdk_x11_screen_events_uninit (GdkScreen *screen) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); if (x11_screen->xsettings_client) { xsettings_client_destroy (x11_screen->xsettings_client); x11_screen->xsettings_client = NULL; } }