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 void add_startup_timeout (GdkX11Screen *screen, const char *startup_id) { StartupTimeoutData *data; StartupNotificationData *sn_data; data = g_object_get_data (G_OBJECT (screen), "appinfo-startup-data"); if (data == NULL) { data = g_new (StartupTimeoutData, 1); data->contexts = NULL; data->timeout_id = 0; g_object_set_data_full (G_OBJECT (screen), "appinfo-startup-data", data, free_startup_timeout); } sn_data = g_new (StartupNotificationData, 1); sn_data->display = g_object_ref (GDK_SCREEN_DISPLAY (screen)); sn_data->startup_id = g_strdup (startup_id); g_get_current_time (&sn_data->time); data->contexts = g_slist_prepend (data->contexts, sn_data); if (data->timeout_id == 0) { data->timeout_id = g_timeout_add_seconds (STARTUP_TIMEOUT_LENGTH_SECONDS, startup_timeout, data); g_source_set_name_by_id (data->timeout_id, "[gtk+] startup_timeout"); } }
static void init_randr_support (GdkX11Screen *x11_screen) { /* NB: This is also needed for XSettings, so don't remove. */ XSelectInput (GDK_SCREEN_XDISPLAY (x11_screen), x11_screen->xroot_window, StructureNotifyMask); #ifdef HAVE_RANDR if (!GDK_X11_DISPLAY (GDK_SCREEN_DISPLAY (x11_screen))->have_randr12) return; XRRSelectInput (GDK_SCREEN_XDISPLAY (x11_screen), x11_screen->xroot_window, RRScreenChangeNotifyMask | RRCrtcChangeNotifyMask | RROutputPropertyNotifyMask); #endif }
void _gdk_x11_screen_size_changed (GdkX11Screen *screen, const XEvent *event) { #ifdef HAVE_RANDR GdkX11Display *display_x11; display_x11 = GDK_X11_DISPLAY (GDK_SCREEN_DISPLAY (screen)); if (display_x11->have_randr13 && event->type == ConfigureNotify) return; XRRUpdateConfiguration ((XEvent *) event); #else if (event->type != ConfigureNotify) return; #endif process_monitors_change (screen); }
static int get_current_desktop (GdkX11Screen *screen) { Display *display; Window win; Atom current_desktop, type; int format; unsigned long n_items, bytes_after; unsigned char *data_return = NULL; int workspace = 0; if (!gdk_x11_screen_supports_net_wm_hint (screen, g_intern_static_string ("_NET_CURRENT_DESKTOP"))) return workspace; display = GDK_DISPLAY_XDISPLAY (GDK_SCREEN_DISPLAY (screen)); win = XRootWindow (display, gdk_x11_screen_get_screen_number (screen)); current_desktop = XInternAtom (display, "_NET_CURRENT_DESKTOP", True); XGetWindowProperty (display, win, current_desktop, 0, G_MAXLONG, False, XA_CARDINAL, &type, &format, &n_items, &bytes_after, &data_return); if (type == XA_CARDINAL && format == 32 && n_items > 0) workspace = ((long *) data_return)[0]; if (data_return) XFree (data_return); return workspace; }
static gboolean init_randr13 (GdkX11Screen *x11_screen, gboolean *changed) { #ifdef HAVE_RANDR GdkDisplay *display = GDK_SCREEN_DISPLAY (x11_screen); GdkX11Display *x11_display = GDK_X11_DISPLAY (display); XRRScreenResources *resources; RROutput primary_output = None; RROutput first_output = None; int i; int old_primary; if (!x11_display->have_randr13) return FALSE; resources = XRRGetScreenResourcesCurrent (x11_screen->xdisplay, x11_screen->xroot_window); if (!resources) return FALSE; for (i = 0; i < x11_display->monitors->len; i++) { GdkX11Monitor *monitor = x11_display->monitors->pdata[i]; monitor->add = FALSE; monitor->remove = TRUE; } for (i = 0; i < resources->noutput; ++i) { RROutput output = resources->outputs[i]; XRROutputInfo *output_info = XRRGetOutputInfo (x11_screen->xdisplay, resources, output); if (output_info->connection == RR_Disconnected) { XRRFreeOutputInfo (output_info); continue; } if (output_info->crtc) { GdkX11Monitor *monitor; XRRCrtcInfo *crtc = XRRGetCrtcInfo (x11_screen->xdisplay, resources, output_info->crtc); char *name; GdkRectangle geometry; GdkRectangle newgeo; int j; int refresh_rate = 0; for (j = 0; j < resources->nmode; j++) { XRRModeInfo *xmode = &resources->modes[j]; if (xmode->id == crtc->mode) { if (xmode->hTotal != 0 && xmode->vTotal != 0) refresh_rate = (1000 * xmode->dotClock) / (xmode->hTotal * xmode->vTotal); break; } } monitor = find_monitor_by_output (x11_display, output); if (monitor) monitor->remove = FALSE; else { monitor = g_object_new (gdk_x11_monitor_get_type (), "display", display, NULL); monitor->output = output; monitor->add = TRUE; g_ptr_array_add (x11_display->monitors, monitor); } gdk_monitor_get_geometry (GDK_MONITOR (monitor), &geometry); name = g_strndup (output_info->name, output_info->nameLen); newgeo.x = crtc->x / x11_screen->surface_scale; newgeo.y = crtc->y / x11_screen->surface_scale; newgeo.width = crtc->width / x11_screen->surface_scale; newgeo.height = crtc->height / x11_screen->surface_scale; if (newgeo.x != geometry.x || newgeo.y != geometry.y || newgeo.width != geometry.width || newgeo.height != geometry.height || output_info->mm_width != gdk_monitor_get_width_mm (GDK_MONITOR (monitor)) || output_info->mm_height != gdk_monitor_get_height_mm (GDK_MONITOR (monitor)) || g_strcmp0 (name, gdk_monitor_get_model (GDK_MONITOR (monitor))) != 0) *changed = TRUE; gdk_monitor_set_position (GDK_MONITOR (monitor), newgeo.x, newgeo.y); gdk_monitor_set_size (GDK_MONITOR (monitor), newgeo.width, newgeo.height); g_object_notify (G_OBJECT (monitor), "workarea"); gdk_monitor_set_physical_size (GDK_MONITOR (monitor), output_info->mm_width, output_info->mm_height); gdk_monitor_set_subpixel_layout (GDK_MONITOR (monitor), translate_subpixel_order (output_info->subpixel_order)); gdk_monitor_set_refresh_rate (GDK_MONITOR (monitor), refresh_rate); gdk_monitor_set_scale_factor (GDK_MONITOR (monitor), x11_screen->surface_scale); gdk_monitor_set_model (GDK_MONITOR (monitor), name); g_free (name); XRRFreeCrtcInfo (crtc); } XRRFreeOutputInfo (output_info); } if (resources->noutput > 0) first_output = resources->outputs[0]; XRRFreeScreenResources (resources); /* Which usable multihead data is not returned in non RandR 1.2+ X driver? */ for (i = x11_display->monitors->len - 1; i >= 0; i--) { GdkX11Monitor *monitor = x11_display->monitors->pdata[i]; if (monitor->add) { gdk_display_monitor_added (display, GDK_MONITOR (monitor)); *changed = TRUE; } else if (monitor->remove) { g_object_ref (monitor); g_ptr_array_remove (x11_display->monitors, monitor); gdk_display_monitor_removed (display, GDK_MONITOR (monitor)); g_object_unref (monitor); *changed = TRUE; } } old_primary = x11_display->primary_monitor; x11_display->primary_monitor = 0; primary_output = XRRGetOutputPrimary (x11_screen->xdisplay, x11_screen->xroot_window); for (i = 0; i < x11_display->monitors->len; ++i) { GdkX11Monitor *monitor = x11_display->monitors->pdata[i]; if (monitor->output == primary_output) { x11_display->primary_monitor = i; break; } /* No RandR1.3+ available or no primary set, fall back to prefer LVDS as primary if present */ if (primary_output == None && g_ascii_strncasecmp (gdk_monitor_get_model (GDK_MONITOR (monitor)), "LVDS", 4) == 0) { x11_display->primary_monitor = i; break; } /* No primary specified and no LVDS found */ if (monitor->output == first_output) x11_display->primary_monitor = i; } if (x11_display->primary_monitor != old_primary) *changed = TRUE; return x11_display->monitors->len > 0; #endif return FALSE; }