static gboolean device_has_property (XDevice *device, const char *property_name) { GdkDisplay *display; Atom realtype, prop; int realformat; unsigned long nitems, bytes_after; unsigned char *data; display = gdk_display_get_default (); prop = XInternAtom (GDK_DISPLAY_XDISPLAY (display), property_name, True); if (!prop) return FALSE; gdk_x11_display_error_trap_push (display); if ((XGetDeviceProperty (GDK_DISPLAY_XDISPLAY (display), device, prop, 0, 1, False, XA_INTEGER, &realtype, &realformat, &nitems, &bytes_after, &data) == Success) && (realtype != None)) { gdk_x11_display_error_trap_pop_ignored (display); XFree (data); return TRUE; } gdk_x11_display_error_trap_pop_ignored (display); return FALSE; }
static void draw_background (MateBGCrossfade *fade) { if (fade->priv->widget != NULL) { gtk_widget_queue_draw (fade->priv->widget); } else if (gdk_window_get_window_type (fade->priv->window) != GDK_WINDOW_ROOT) { cairo_t *cr; cairo_region_t *region; GdkDrawingContext *draw_context; region = gdk_window_get_visible_region (fade->priv->window); draw_context = gdk_window_begin_draw_frame (fade->priv->window, region); cr = gdk_drawing_context_get_cairo_context (draw_context); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_source_surface (cr, fade->priv->fading_surface, 0, 0); cairo_paint (cr); gdk_window_end_draw_frame (fade->priv->window, draw_context); cairo_region_destroy (region); } else { Display *xdisplay = GDK_WINDOW_XDISPLAY (fade->priv->window); GdkDisplay *display; display = gdk_display_get_default (); gdk_x11_display_error_trap_push (display); XGrabServer (xdisplay); XClearWindow (xdisplay, GDK_WINDOW_XID (fade->priv->window)); send_root_property_change_notification (fade); XFlush (xdisplay); XUngrabServer (xdisplay); gdk_x11_display_error_trap_pop_ignored (display); } }
static Window get_net_supporting_wm_check (GdkX11Screen *screen, Window window) { GdkDisplay *display; Atom type; gint format; gulong n_items; gulong bytes_after; guchar *data; Window value; display = screen->display; type = None; data = NULL; value = None; gdk_x11_display_error_trap_push (display); XGetWindowProperty (screen->xdisplay, window, gdk_x11_get_xatom_by_name_for_display (display, "_NET_SUPPORTING_WM_CHECK"), 0, G_MAXLONG, False, XA_WINDOW, &type, &format, &n_items, &bytes_after, &data); gdk_x11_display_error_trap_pop_ignored (display); if (type == XA_WINDOW) value = *(Window *)data; if (data) XFree (data); return value; }
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; }
/** * 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; }
/* This function queries the _XROOTPMAP_ID property from the root window * to determine the current root window background pixmap and returns a * surface to draw directly to it. * If _XROOTPMAP_ID is not set, then NULL returned. */ static cairo_surface_t * get_root_pixmap_id_surface (GdkDisplay *display) { GdkScreen *screen; Display *xdisplay; Visual *xvisual; Window xroot; Atom type; int format, result; unsigned long nitems, bytes_after; unsigned char *data; cairo_surface_t *surface = NULL; g_return_val_if_fail (display != NULL, NULL); screen = gdk_display_get_default_screen (display); xdisplay = GDK_DISPLAY_XDISPLAY (display); xvisual = GDK_VISUAL_XVISUAL (gdk_screen_get_system_visual (screen)); xroot = RootWindow (xdisplay, GDK_SCREEN_XNUMBER (screen)); result = XGetWindowProperty (xdisplay, xroot, gdk_x11_get_xatom_by_name ("_XROOTPMAP_ID"), 0L, 1L, False, XA_PIXMAP, &type, &format, &nitems, &bytes_after, &data); if (result != Success || type != XA_PIXMAP || format != 32 || nitems != 1) { XFree (data); data = NULL; } if (data != NULL) { Pixmap pixmap = *(Pixmap *) data; Window root_ret; int x_ret, y_ret; unsigned int w_ret, h_ret, bw_ret, depth_ret; gdk_x11_display_error_trap_push (display); if (XGetGeometry (xdisplay, pixmap, &root_ret, &x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret)) { surface = cairo_xlib_surface_create (xdisplay, pixmap, xvisual, w_ret, h_ret); } gdk_x11_display_error_trap_pop_ignored (display); XFree (data); } gdk_display_flush (display); return surface; }
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); } }
/** * gdk_x11_xatom_to_atom_for_display: * @display: (type GdkX11Display): A #GdkDisplay * @xatom: an X atom * * Convert from an X atom for a #GdkDisplay to the corresponding * #GdkAtom. * * Return value: (transfer none): the corresponding #GdkAtom. * * Since: 2.2 **/ GdkAtom gdk_x11_xatom_to_atom_for_display (GdkDisplay *display, Atom xatom) { GdkX11Display *display_x11; GdkAtom virtual_atom = GDK_NONE; g_return_val_if_fail (GDK_IS_DISPLAY (display), GDK_NONE); if (xatom == None) return GDK_NONE; if (gdk_display_is_closed (display)) return GDK_NONE; display_x11 = GDK_X11_DISPLAY (display); if (xatom < G_N_ELEMENTS (xatoms_offset) - N_CUSTOM_PREDEFINED) return INDEX_TO_ATOM (xatom); if (display_x11->atom_to_virtual) virtual_atom = GDK_POINTER_TO_ATOM (g_hash_table_lookup (display_x11->atom_to_virtual, GUINT_TO_POINTER (xatom))); if (!virtual_atom) { /* If this atom doesn't exist, we'll die with an X error unless * we take precautions */ char *name; gdk_x11_display_error_trap_push (display); name = XGetAtomName (GDK_DISPLAY_XDISPLAY (display), xatom); if (gdk_x11_display_error_trap_pop (display)) { g_warning (G_STRLOC " invalid X atom: %ld", xatom); } else { virtual_atom = gdk_atom_intern (name, FALSE); XFree (name); insert_atom_pair (display, virtual_atom, xatom); } } return virtual_atom; }
guint gsd_power_enable_screensaver_watchdog (void) { int dummy; guint id; /* Make sure that Xorg's DPMS extension never gets in our * way. The defaults are now applied in Fedora 20 from * being "0" by default to being "600" by default */ gdk_x11_display_error_trap_push (gdk_display_get_default ()); if (DPMSQueryExtension(GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &dummy, &dummy)) DPMSSetTimeouts (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), 0, 0, 0); gdk_x11_display_error_trap_pop_ignored (gdk_display_get_default ()); id = g_timeout_add_seconds (XSCREENSAVER_WATCHDOG_TIMEOUT, disable_builtin_screensaver, NULL); g_source_set_name_by_id (id, "[gnome-settings-daemon] disable_builtin_screensaver"); return id; }
static void on_realize (GtkWidget *dialog, gpointer data) { Window xid; xid = (Window) GPOINTER_TO_INT (data); #if GTK_CHECK_VERSION(3, 22, 0) gdk_x11_display_error_trap_push (gtk_widget_get_display (dialog)); #else gdk_error_trap_push (); #endif XSetTransientForHint (gdk_x11_get_default_xdisplay (), GDK_WINDOW_XID (gtk_widget_get_window (dialog)), xid); #if GTK_CHECK_VERSION(3, 22, 0) gdk_x11_display_error_trap_pop_ignored (gtk_widget_get_display (dialog)); #else gdk_error_trap_pop_ignored (); #endif }
gint _gdk_x11_display_send_xevent (GdkDisplay *display, Window window, gboolean propagate, glong event_mask, XEvent *event_send) { gboolean result; if (gdk_display_is_closed (display)) return FALSE; gdk_x11_display_error_trap_push (display); result = XSendEvent (GDK_DISPLAY_XDISPLAY (display), window, propagate, event_mask, event_send); XSync (GDK_DISPLAY_XDISPLAY (display), False); if (gdk_x11_display_error_trap_pop (display)) return FALSE; return result; }
XDevice* device_is_touchpad (XDeviceInfo *deviceinfo) { GdkDisplay *display; XDevice *device; display = gdk_display_get_default (); if (deviceinfo->type != XInternAtom (GDK_DISPLAY_XDISPLAY (display), XI_TOUCHPAD, True)) return NULL; gdk_x11_display_error_trap_push (display); device = XOpenDevice (GDK_DISPLAY_XDISPLAY (display), deviceinfo->id); if (gdk_x11_display_error_trap_pop (display) || (device == NULL)) return NULL; if (device_has_property (device, "libinput Tapping Enabled") || device_has_property (device, "Synaptics Off")) { return device; } XCloseDevice (GDK_DISPLAY_XDISPLAY (display), device); return NULL; }
static gboolean is_shift_pressed (void) { gboolean ret; GdkDisplay *display; XkbStateRec state; Bool status; ret = FALSE; display = gdk_display_get_default (); gdk_x11_display_error_trap_push (display); status = XkbGetState (GDK_DISPLAY_XDISPLAY (display), XkbUseCoreKbd, &state); gdk_x11_display_error_trap_pop_ignored (display); if (status == Success) { ret = state.mods & ShiftMask; } return ret; }
/** * _gtk_xembed_send_message: * @recipient: (allow-none): window to which to send the window, or %NULL * in which case nothing will be sent * @message: type of message * @detail: detail field of message * @data1: data1 field of message * @data2: data2 field of message * * Sends a generic XEMBED message to a particular window. **/ void _gtk_xembed_send_message (GdkWindow *recipient, XEmbedMessageType message, glong detail, glong data1, glong data2) { GdkDisplay *display; XClientMessageEvent xclient; if (!recipient) return; g_return_if_fail (GDK_IS_WINDOW (recipient)); display = gdk_window_get_display (recipient); GTK_NOTE (PLUGSOCKET, g_message ("Sending %s", _gtk_xembed_message_name (message))); memset (&xclient, 0, sizeof (xclient)); xclient.window = GDK_WINDOW_XID (recipient); xclient.type = ClientMessage; xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_XEMBED"); xclient.format = 32; xclient.data.l[0] = gtk_xembed_get_time (); xclient.data.l[1] = message; xclient.data.l[2] = detail; xclient.data.l[3] = data1; xclient.data.l[4] = data2; gdk_x11_display_error_trap_push (display); XSendEvent (GDK_WINDOW_XDISPLAY(recipient), GDK_WINDOW_XID (recipient), False, NoEventMask, (XEvent *)&xclient); gdk_x11_display_error_trap_pop_ignored (display); }
static void fetch_net_wm_check_window (GdkScreen *screen) { GdkX11Screen *x11_screen; GdkDisplay *display; Atom type; gint format; gulong n_items; gulong bytes_after; guchar *data; Window *xwindow; GTimeVal tv; gint error; x11_screen = GDK_X11_SCREEN (screen); display = x11_screen->display; g_return_if_fail (GDK_X11_DISPLAY (display)->trusted_client); g_get_current_time (&tv); if (ABS (tv.tv_sec - x11_screen->last_wmspec_check_time) < 15) return; /* we've checked recently */ x11_screen->last_wmspec_check_time = tv.tv_sec; data = NULL; XGetWindowProperty (x11_screen->xdisplay, x11_screen->xroot_window, gdk_x11_get_xatom_by_name_for_display (display, "_NET_SUPPORTING_WM_CHECK"), 0, G_MAXLONG, False, XA_WINDOW, &type, &format, &n_items, &bytes_after, &data); if (type != XA_WINDOW) { if (data) XFree (data); return; } xwindow = (Window *)data; if (x11_screen->wmspec_check_window == *xwindow) { XFree (xwindow); return; } gdk_x11_display_error_trap_push (display); /* Find out if this WM goes away, so we can reset everything. */ XSelectInput (x11_screen->xdisplay, *xwindow, StructureNotifyMask); error = gdk_x11_display_error_trap_pop (display); if (!error) { x11_screen->wmspec_check_window = *xwindow; x11_screen->need_refetch_net_supported = TRUE; x11_screen->need_refetch_wm_name = TRUE; /* Careful, reentrancy */ _gdk_x11_screen_window_manager_changed (GDK_SCREEN (x11_screen)); } else if (error == BadWindow) { /* Leftover property, try again immediately, new wm may be starting up */ x11_screen->last_wmspec_check_time = 0; } XFree (xwindow); }
int main (int argc, char **argv) { GdkDisplay *display = NULL; int estatus; char *child_argv[] = { LIBEXECDIR "/cinnamon-session-check-accelerated-helper", NULL }; Window rootwin; glong is_accelerated; GError *error = NULL; gtk_init (NULL, NULL); display = gdk_display_get_default (); rootwin = gdk_x11_get_default_root_xwindow (); is_accelerated_atom = gdk_x11_get_xatom_by_name_for_display (display, "_CINNAMON_SESSION_ACCELERATED"); { Atom type; gint format; gulong nitems; gulong bytes_after; guchar *data; read: gdk_x11_display_error_trap_push (display); XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), rootwin, is_accelerated_atom, 0, G_MAXLONG, False, XA_CARDINAL, &type, &format, &nitems, &bytes_after, &data); gdk_x11_display_error_trap_pop_ignored (display); if (type == XA_CARDINAL) { glong *is_accelerated_ptr = (glong*) data; if (*is_accelerated_ptr == ACCEL_CHECK_RUNNING) { /* Test in progress, wait */ if (wait_for_property_notify ()) goto read; /* else fall through and do the check ourselves */ } else { return (*is_accelerated_ptr == 0 ? 1 : 0); } } } /* We don't have the property or it's the wrong type. * Try to compute it now. */ /* First indicate that a test is in progress */ is_accelerated = ACCEL_CHECK_RUNNING; XChangeProperty (GDK_DISPLAY_XDISPLAY (display), rootwin, is_accelerated_atom, XA_CARDINAL, 32, PropModeReplace, (guchar *) &is_accelerated, 1); gdk_display_sync (display); estatus = 1; if (!g_spawn_sync (NULL, (char**)child_argv, NULL, 0, NULL, NULL, NULL, NULL, &estatus, &error)) { is_accelerated = FALSE; g_printerr ("cinnamon-session-check-accelerated: Failed to run helper: %s\n", error->message); g_clear_error (&error); } else { is_accelerated = (estatus == 0); if (!is_accelerated) g_printerr ("cinnamon-session-check-accelerated: Helper exited with code %d\n", estatus); } XChangeProperty (GDK_DISPLAY_XDISPLAY (display), rootwin, is_accelerated_atom, XA_CARDINAL, 32, PropModeReplace, (guchar *) &is_accelerated, 1); gdk_display_sync (display); return is_accelerated ? 0 : 1; }
static gboolean init_randr15 (GdkScreen *screen, gboolean *changed) { #ifdef HAVE_RANDR15 GdkDisplay *display = gdk_screen_get_display (screen); GdkX11Display *x11_display = GDK_X11_DISPLAY (display); GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); XRRScreenResources *resources; RROutput primary_output = None; RROutput first_output = None; int i; gboolean randr12_compat = FALSE; XRRMonitorInfo *rr_monitors; int num_rr_monitors; int old_primary; if (!x11_display->have_randr15) return FALSE; resources = XRRGetScreenResourcesCurrent (x11_screen->xdisplay, x11_screen->xroot_window); if (!resources) return FALSE; rr_monitors = XRRGetMonitors (x11_screen->xdisplay, x11_screen->xroot_window, True, &num_rr_monitors); if (!rr_monitors) 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 < num_rr_monitors; i++) { RROutput output = rr_monitors[i].outputs[0]; XRROutputInfo *output_info; GdkX11Monitor *monitor; GdkRectangle geometry; GdkRectangle newgeo; char *name; int refresh_rate = 0; gdk_x11_display_error_trap_push (display); output_info = XRRGetOutputInfo (x11_screen->xdisplay, resources, output); if (gdk_x11_display_error_trap_pop (display)) continue; if (output_info == NULL) continue; /* Non RandR1.2+ X driver have output name "default" */ randr12_compat |= !g_strcmp0 (output_info->name, "default"); if (output_info->connection == RR_Disconnected) { XRRFreeOutputInfo (output_info); continue; } if (first_output == None) first_output = output; if (output_info->crtc) { XRRCrtcInfo *crtc = XRRGetCrtcInfo (x11_screen->xdisplay, resources, output_info->crtc); int j; 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; } } XRRFreeCrtcInfo (crtc); } monitor = find_monitor_by_output (x11_display, output); if (monitor) monitor->remove = FALSE; else { monitor = g_object_new (GDK_TYPE_X11_MONITOR, "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 = rr_monitors[i].x / x11_screen->window_scale; newgeo.y = rr_monitors[i].y / x11_screen->window_scale; newgeo.width = rr_monitors[i].width / x11_screen->window_scale; newgeo.height = rr_monitors[i].height / x11_screen->window_scale; if (newgeo.x != geometry.x || newgeo.y != geometry.y || newgeo.width != geometry.width || newgeo.height != geometry.height || rr_monitors[i].mwidth != gdk_monitor_get_width_mm (GDK_MONITOR (monitor)) || rr_monitors[i].mheight != gdk_monitor_get_height_mm (GDK_MONITOR (monitor)) || g_strcmp0 (name, gdk_monitor_get_model (GDK_MONITOR (monitor)))) *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), rr_monitors[i].mwidth, rr_monitors[i].mheight); 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->window_scale); gdk_monitor_set_model (GDK_MONITOR (monitor), name); g_free (name); if (rr_monitors[i].primary) primary_output = monitor->output; XRRFreeOutputInfo (output_info); } XRRFreeMonitors (rr_monitors); XRRFreeScreenResources (resources); /* non RandR 1.2+ X driver doesn't return any usable multihead data */ if (randr12_compat) { for (i = 0; i < x11_display->monitors->len; i++) { GdkX11Monitor *monitor = x11_display->monitors->pdata[i]; if (monitor->remove) gdk_display_monitor_removed (display, GDK_MONITOR (monitor)); } g_ptr_array_remove_range (x11_display->monitors, 0, x11_display->monitors->len); return FALSE; } 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; 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; }
gboolean _gdk_x11_window_simulate_key (GdkWindow *window, gint x, gint y, guint keyval, GdkModifierType modifiers, GdkEventType key_pressrelease) { GdkScreen *screen; GdkKeymapKey *keys = NULL; gboolean success; gint n_keys = 0; XKeyEvent xev = { 0, /* type */ 0, /* serial */ 1, /* send_event */ }; g_return_val_if_fail (key_pressrelease == GDK_KEY_PRESS || key_pressrelease == GDK_KEY_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 = key_pressrelease == GDK_KEY_PRESS ? KeyPress : KeyRelease; 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 = MAX (x, 0); xev.y = MAX (y, 0); xev.x_root = 0; xev.y_root = 0; xev.state = modifiers; xev.keycode = 0; success = gdk_keymap_get_entries_for_keyval (gdk_keymap_get_for_display (gdk_window_get_display (window)), keyval, &keys, &n_keys); success &= n_keys > 0; if (success) { gint i; for (i = 0; i < n_keys; i++) if (keys[i].group == 0 && (keys[i].level == 0 || keys[i].level == 1)) { xev.keycode = keys[i].keycode; if (keys[i].level == 1) { /* Assume shift takes us to level 1 */ xev.state |= GDK_SHIFT_MASK; } break; } if (i >= n_keys) /* no match for group==0 and level==0 or 1 */ xev.keycode = keys[0].keycode; } g_free (keys); if (!success) return FALSE; 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; if (x >= 0 && y >= 0) success &= 0 != XWarpPointer (xev.display, None, xev.window, 0, 0, 0, 0, xev.x, xev.y); success &= 0 != XSendEvent (xev.display, xev.window, True, key_pressrelease == GDK_KEY_PRESS ? KeyPressMask : KeyReleaseMask, (XEvent*) &xev); XSync (xev.display, False); success &= 0 == gdk_x11_display_error_trap_pop (GDK_WINDOW_DISPLAY (window)); return success; }
static void read_settings (GdkX11Screen *x11_screen, gboolean do_notify) { GdkScreen *screen = GDK_SCREEN (x11_screen); Atom type; int format; unsigned long n_items; unsigned long bytes_after; unsigned char *data; int result; GHashTable *old_list = x11_screen->xsettings; GValue value = G_VALUE_INIT; GValue *setting, *copy; x11_screen->xsettings = NULL; if (x11_screen->xsettings_manager_window) { GdkDisplay *display = x11_screen->display; Atom xsettings_atom = gdk_x11_get_xatom_by_name_for_display (display, "_XSETTINGS_SETTINGS"); gdk_x11_display_error_trap_push (display); result = XGetWindowProperty (gdk_x11_display_get_xdisplay (display), gdk_x11_window_get_xid (x11_screen->xsettings_manager_window), xsettings_atom, 0, LONG_MAX, False, xsettings_atom, &type, &format, &n_items, &bytes_after, &data); gdk_x11_display_error_trap_pop_ignored (display); if (result == Success && type != None) { if (type != xsettings_atom) { g_warning ("Invalid type for XSETTINGS property: %s", gdk_x11_get_xatom_name_for_display (display, type)); } else if (format != 8) { g_warning ("Invalid format for XSETTINGS property: %d", format); } else x11_screen->xsettings = parse_settings (data, n_items); XFree (data); } } /* Since we support scaling we look at the specific Gdk/UnscaledDPI setting if it exists and use that instead of Xft/DPI if it is set */ if (x11_screen->xsettings && !x11_screen->fixed_window_scale) { setting = g_hash_table_lookup (x11_screen->xsettings, "gdk-unscaled-dpi"); if (setting) { copy = g_new0 (GValue, 1); g_value_init (copy, G_VALUE_TYPE (setting)); g_value_copy (setting, copy); g_hash_table_insert (x11_screen->xsettings, "gtk-xft-dpi", copy); } } if (do_notify) notify_changes (x11_screen, old_list); if (old_list) g_hash_table_unref (old_list); g_value_init (&value, G_TYPE_INT); if (!screen->resolution_set) { /* This code is duplicated with gtksettings.c:settings_update_resolution(). * The update of the screen resolution needs to happen immediately when * gdk_x11_display_set_window_scale() is called, and not wait for events * to be processed, so we can't always handling it in gtksettings.c. * But we can't always handle it here because the DPI can be set through * GtkSettings, which we don't have access to. */ int dpi_int = 0; double dpi; const char *scale_env; double scale; if (gdk_screen_get_setting (GDK_SCREEN (x11_screen), "gtk-xft-dpi", &value)) dpi_int = g_value_get_int (&value); if (dpi_int > 0) dpi = dpi_int / 1024.; else dpi = -1.; scale_env = g_getenv ("GDK_DPI_SCALE"); if (scale_env) { scale = g_ascii_strtod (scale_env, NULL); if (scale != 0 && dpi > 0) dpi *= scale; } _gdk_screen_set_resolution (screen, dpi); } if (!x11_screen->fixed_window_scale && gdk_screen_get_setting (GDK_SCREEN (x11_screen), "gdk-window-scaling-factor", &value)) _gdk_x11_screen_set_window_scale (x11_screen, g_value_get_int (&value)); }