GtkWidget * na_tray_child_new (GdkScreen *screen, Window icon_window) { XWindowAttributes window_attributes; Display *xdisplay; NaTrayChild *child; GdkVisual *visual; gboolean visual_has_alpha; int red_prec, green_prec, blue_prec, depth; int result; g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); g_return_val_if_fail (icon_window != None, NULL); xdisplay = GDK_SCREEN_XDISPLAY (screen); /* We need to determine the visual of the window we are embedding and create * the socket in the same visual. */ gdk_error_trap_push (); result = XGetWindowAttributes (xdisplay, icon_window, &window_attributes); gdk_error_trap_pop_ignored (); if (!result) /* Window already gone */ return NULL; visual = gdk_x11_screen_lookup_visual (screen, window_attributes.visual->visualid); if (!visual) /* Icon window is on another screen? */ return NULL; child = g_object_new (NA_TYPE_TRAY_CHILD, NULL); child->icon_window = icon_window; gtk_widget_set_visual (GTK_WIDGET (child), visual); /* We have alpha if the visual has something other than red, green, * and blue */ gdk_visual_get_red_pixel_details (visual, NULL, NULL, &red_prec); gdk_visual_get_green_pixel_details (visual, NULL, NULL, &green_prec); gdk_visual_get_blue_pixel_details (visual, NULL, NULL, &blue_prec); depth = gdk_visual_get_depth (visual); visual_has_alpha = red_prec + blue_prec + green_prec < depth; child->has_alpha = (visual_has_alpha && gdk_display_supports_composite (gdk_screen_get_display (screen))); child->composited = child->has_alpha; return GTK_WIDGET (child); }
static void init_randr_support (GdkScreen *screen) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); XSelectInput (GDK_SCREEN_XDISPLAY (screen), x11_screen->xroot_window, StructureNotifyMask); #ifdef HAVE_RANDR if (!GDK_X11_DISPLAY (gdk_screen_get_display (screen))->have_randr12) return; XRRSelectInput (GDK_SCREEN_XDISPLAY (screen), x11_screen->xroot_window, RRScreenChangeNotifyMask | RRCrtcChangeNotifyMask | RROutputPropertyNotifyMask); #endif }
static void gdk_x11_draw_rectangle (GdkDrawable *drawable, GdkGC *gc, gboolean filled, gint x, gint y, gint width, gint height) { GdkDrawableImplX11 *impl; impl = GDK_DRAWABLE_IMPL_X11 (drawable); if (filled) XFillRectangle (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid, GDK_GC_GET_XGC (gc), x, y, width, height); else XDrawRectangle (GDK_SCREEN_XDISPLAY (impl->screen), impl->xid, GDK_GC_GET_XGC (gc), x, y, width, height); }
WidgetBackingStoreGtkX11::WidgetBackingStoreGtkX11(GtkWidget* widget, const IntSize& size) : WidgetBackingStore(size) { GdkVisual* visual = gtk_widget_get_visual(widget); GdkScreen* screen = gdk_visual_get_screen(visual); m_display = GDK_SCREEN_XDISPLAY(screen); m_pixmap = XCreatePixmap(m_display, GDK_WINDOW_XID(gdk_screen_get_root_window(screen)), size.width(), size.height(), gdk_visual_get_depth(visual)); m_gc = XCreateGC(m_display, m_pixmap, 0, 0); m_surface = adoptRef(cairo_xlib_surface_create(m_display, m_pixmap, GDK_VISUAL_XVISUAL(visual), size.width(), size.height())); }
static void gdk_x11_drawable_update_picture_clip (GdkDrawable *drawable, GdkGC *gc) { GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable); Display *xdisplay = GDK_SCREEN_XDISPLAY (impl->screen); Picture picture = gdk_x11_drawable_get_picture (drawable); GdkRegion *clip_region = gc ? _gdk_gc_get_clip_region (gc) : NULL; if (clip_region) { GdkRegionBox *boxes = clip_region->rects; gint n_boxes = clip_region->numRects; XRectangle *rects = g_new (XRectangle, n_boxes); int i; for (i=0; i < n_boxes; i++) { rects[i].x = CLAMP (boxes[i].x1 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT); rects[i].y = CLAMP (boxes[i].y1 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT); rects[i].width = CLAMP (boxes[i].x2 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT) - rects[i].x; rects[i].height = CLAMP (boxes[i].y2 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT) - rects[i].y; } XRenderSetPictureClipRectangles (xdisplay, picture, 0, 0, rects, n_boxes); g_free (rects); } else { XRenderPictureAttributes pa; GdkBitmap *mask; gulong pa_mask; pa_mask = CPClipMask; if (gc && (mask = _gdk_gc_get_clip_mask (gc))) { pa.clip_mask = GDK_PIXMAP_XID (mask); pa.clip_x_origin = gc->clip_x_origin; pa.clip_y_origin = gc->clip_y_origin; pa_mask |= CPClipXOrigin | CPClipYOrigin; } else pa.clip_mask = None; XRenderChangePicture (xdisplay, picture, pa_mask, &pa); } }
static void gdk_x11_draw_text_wc (GdkDrawable *drawable, GdkFont *font, GdkGC *gc, gint x, gint y, const GdkWChar *text, gint text_length) { GdkDrawableImplX11 *impl; Display *xdisplay; impl = GDK_DRAWABLE_IMPL_X11 (drawable); xdisplay = GDK_SCREEN_XDISPLAY (impl->screen); if (font->type == GDK_FONT_FONT) { XFontStruct *xfont = (XFontStruct *) GDK_FONT_XFONT (font); gchar *text_8bit; gint i; XSetFont(xdisplay, GDK_GC_GET_XGC (gc), xfont->fid); text_8bit = g_new (gchar, text_length); for (i=0; i<text_length; i++) text_8bit[i] = text[i]; XDrawString (xdisplay, impl->xid, GDK_GC_GET_XGC (gc), x, y, text_8bit, text_length); g_free (text_8bit); } else if (font->type == GDK_FONT_FONTSET) { if (sizeof(GdkWChar) == sizeof(wchar_t)) { XwcDrawString (xdisplay, impl->xid, (XFontSet) GDK_FONT_XFONT (font), GDK_GC_GET_XGC (gc), x, y, (wchar_t *)text, text_length); } else { wchar_t *text_wchar; gint i; text_wchar = g_new (wchar_t, text_length); for (i=0; i<text_length; i++) text_wchar[i] = text[i]; XwcDrawString (xdisplay, impl->xid, (XFontSet) GDK_FONT_XFONT (font), GDK_GC_GET_XGC (gc), x, y, text_wchar, text_length); g_free (text_wchar); } } else
static gboolean init_xfree_xinerama (GdkScreen *screen) { #ifdef HAVE_XFREE_XINERAMA Display *dpy = GDK_SCREEN_XDISPLAY (screen); GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); XineramaScreenInfo *monitors; int i, n_monitors; if (!XineramaIsActive (dpy)) return FALSE; monitors = XineramaQueryScreens (dpy, &n_monitors); if (n_monitors <= 0 || monitors == NULL) { /* If Xinerama doesn't think we have any monitors, try acting as * though we had no Xinerama. If the "no monitors" condition * is because XRandR 1.2 is currently switching between CRTCs, * we'll be notified again when we have our monitor back, * and can go back into Xinerama-ish mode at that point. */ if (monitors) XFree (monitors); return FALSE; } x11_screen->n_monitors = n_monitors; x11_screen->monitors = g_new0 (GdkX11Monitor, n_monitors); for (i = 0; i < n_monitors; ++i) { init_monitor_geometry (&x11_screen->monitors[i], monitors[i].x_org, monitors[i].y_org, monitors[i].width, monitors[i].height); } XFree (monitors); x11_screen->primary_monitor = 0; return TRUE; #endif /* HAVE_XFREE_XINERAMA */ return FALSE; }
/** * _gdk_x11_drawable_finish: * @drawable: a #GdkDrawableImplX11. * * Performs necessary cleanup prior to freeing a pixmap or * destroying a window. **/ void _gdk_x11_drawable_finish (GdkDrawable *drawable) { GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable); if (impl->picture) { XRenderFreePicture (GDK_SCREEN_XDISPLAY (impl->screen), impl->picture); impl->picture = None; } if (impl->cairo_surface) { cairo_surface_finish (impl->cairo_surface); cairo_surface_set_user_data (impl->cairo_surface, &gdk_x11_cairo_key, NULL, NULL); } }
static gboolean init_solaris_xinerama (GdkScreen *screen) { #ifdef HAVE_SOLARIS_XINERAMA Display *dpy = GDK_SCREEN_XDISPLAY (screen); int screen_no = gdk_screen_get_number (screen); GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); XRectangle monitors[MAXFRAMEBUFFERS]; unsigned char hints[16]; gint result; int n_monitors; int i; if (!XineramaGetState (dpy, screen_no)) return FALSE; result = XineramaGetInfo (dpy, screen_no, monitors, hints, &n_monitors); /* Yes I know it should be Success but the current implementation * returns the num of monitor */ if (result == 0) { return FALSE; } x11_screen->monitors = g_new0 (GdkX11Monitor, n_monitors); x11_screen->n_monitors = n_monitors; for (i = 0; i < n_monitors; i++) { init_monitor_geometry (&x11_screen->monitors[i], monitors[i].x, monitors[i].y, monitors[i].width, monitors[i].height); } x11_screen->primary_monitor = 0; return TRUE; #endif /* HAVE_SOLARIS_XINERAMA */ return FALSE; }
static void init_multihead (GdkScreen *screen) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); int opcode, firstevent, firsterror; /* There are four different implementations of multihead support: * * 1. Fake Xinerama for debugging purposes * 2. RandR 1.2 * 3. Solaris Xinerama * 4. XFree86/Xorg Xinerama * * We use them in that order. */ if (init_fake_xinerama (screen)) return; if (init_randr13 (screen)) return; if (XQueryExtension (GDK_SCREEN_XDISPLAY (screen), "XINERAMA", &opcode, &firstevent, &firsterror)) { if (init_solaris_xinerama (screen)) return; if (init_xfree_xinerama (screen)) return; } /* No multihead support of any kind for this screen */ x11_screen->n_monitors = 1; x11_screen->monitors = g_new0 (GdkX11Monitor, 1); x11_screen->primary_monitor = 0; init_monitor_geometry (x11_screen->monitors, 0, 0, WidthOfScreen (x11_screen->xscreen), HeightOfScreen (x11_screen->xscreen)); }
static GdkRegion * window_get_shape (GdkScreen *screen, GdkNativeWindow window) { GdkRegion *shape = NULL; #if defined(GDK_WINDOWING_X11) && defined(HAVE_X11_EXTENSIONS_SHAPE_H) XRectangle *rects; gint rect_count; gint rect_order; rects = XShapeGetRectangles (GDK_SCREEN_XDISPLAY (screen), window, ShapeBounding, &rect_count, &rect_order); if (rects) { if (rect_count > 1) { gint i; shape = gdk_region_new (); for (i = 0; i < rect_count; i++) { GdkRectangle rect = { rects[i].x, rects[i].y, rects[i].width, rects[i].height }; gdk_region_union_with_rect (shape, &rect); } } XFree (rects); } #endif return shape; }
/* gdk_x11_draw_text * * Modified by Li-Da Lho to draw 16 bits and Multibyte strings * * Interface changed: add "GdkFont *font" to specify font or fontset explicitely */ static void gdk_x11_draw_text (GdkDrawable *drawable, GdkFont *font, GdkGC *gc, gint x, gint y, const gchar *text, gint text_length) { GdkDrawableImplX11 *impl; Display *xdisplay; impl = GDK_DRAWABLE_IMPL_X11 (drawable); xdisplay = GDK_SCREEN_XDISPLAY (impl->screen); if (font->type == GDK_FONT_FONT) { XFontStruct *xfont = (XFontStruct *) GDK_FONT_XFONT (font); XSetFont(xdisplay, GDK_GC_GET_XGC (gc), xfont->fid); if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0)) { XDrawString (xdisplay, impl->xid, GDK_GC_GET_XGC (gc), x, y, text, text_length); } else { XDrawString16 (xdisplay, impl->xid, GDK_GC_GET_XGC (gc), x, y, (XChar2b *) text, text_length / 2); } } else if (font->type == GDK_FONT_FONTSET) { XFontSet fontset = (XFontSet) GDK_FONT_XFONT (font); XmbDrawString (xdisplay, impl->xid, fontset, GDK_GC_GET_XGC (gc), x, y, text, text_length); } else g_error("undefined font type\n"); }
GtkWidget * na_tray_child_new (GdkScreen *screen, Window icon_window) { XWindowAttributes window_attributes; Display *xdisplay; NaTrayChild *child; GdkVisual *visual; gboolean visual_has_alpha; GdkColormap *colormap; gboolean new_colormap; int result; g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); g_return_val_if_fail (icon_window != None, NULL); xdisplay = GDK_SCREEN_XDISPLAY (screen); /* We need to determine the visual of the window we are embedding and create * the socket in the same visual. */ gdk_error_trap_push (); result = XGetWindowAttributes (xdisplay, icon_window, &window_attributes); gdk_error_trap_pop (); if (!result) /* Window already gone */ return NULL; visual = gdk_x11_screen_lookup_visual (screen, window_attributes.visual->visualid); if (!visual) /* Icon window is on another screen? */ return NULL; new_colormap = FALSE; if (visual == gdk_screen_get_rgb_visual (screen)) colormap = gdk_screen_get_rgb_colormap (screen); else if (visual == gdk_screen_get_rgba_visual (screen)) colormap = gdk_screen_get_rgba_colormap (screen); else if (visual == gdk_screen_get_system_visual (screen)) colormap = gdk_screen_get_system_colormap (screen); else { colormap = gdk_colormap_new (visual, FALSE); new_colormap = TRUE; } child = g_object_new (NA_TYPE_TRAY_CHILD, NULL); child->icon_window = icon_window; gtk_widget_set_colormap (GTK_WIDGET (child), colormap); /* We have alpha if the visual has something other than red, green, * and blue */ visual_has_alpha = visual->red_prec + visual->blue_prec + visual->green_prec < visual->depth; child->has_alpha = (visual_has_alpha && gdk_display_supports_composite (gdk_screen_get_display (screen))); child->composited = child->has_alpha; if (new_colormap) g_object_unref (colormap); return GTK_WIDGET (child); }
static GdkNativeWindow select_window_x11 (GdkScreen *screen) { Display *x_dpy = GDK_SCREEN_XDISPLAY (screen); gint x_scr = GDK_SCREEN_XNUMBER (screen); Window x_root = RootWindow (x_dpy, x_scr); Window x_win = None; GC x_gc = None; Cursor x_cursor = XCreateFontCursor (x_dpy, GDK_CROSSHAIR); GdkKeymapKey *keys = NULL; gint status; gint i, num_keys; gint buttons = 0; gint mask = ButtonPressMask | ButtonReleaseMask; gboolean cancel = FALSE; if (shootvals.shoot_type == SHOOT_REGION) mask |= PointerMotionMask; status = XGrabPointer (x_dpy, x_root, False, mask, GrabModeSync, GrabModeAsync, x_root, x_cursor, CurrentTime); if (status != GrabSuccess) { gint x, y; guint xmask; /* if we can't grab the pointer, return the window under the pointer */ XQueryPointer (x_dpy, x_root, &x_root, &x_win, &x, &y, &x, &y, &xmask); if (x_win == None || x_win == x_root) g_message (_("Error selecting the window")); } if (shootvals.shoot_type == SHOOT_REGION) { XGCValues gc_values; gc_values.function = GXxor; gc_values.plane_mask = AllPlanes; gc_values.foreground = WhitePixel (x_dpy, x_scr); gc_values.background = BlackPixel (x_dpy, x_scr); gc_values.line_width = 0; gc_values.line_style = LineSolid; gc_values.fill_style = FillSolid; gc_values.cap_style = CapButt; gc_values.join_style = JoinMiter; gc_values.graphics_exposures = FALSE; gc_values.clip_x_origin = 0; gc_values.clip_y_origin = 0; gc_values.clip_mask = None; gc_values.subwindow_mode = IncludeInferiors; x_gc = XCreateGC (x_dpy, x_root, GCFunction | GCPlaneMask | GCForeground | GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle | GCGraphicsExposures | GCBackground | GCFillStyle | GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode, &gc_values); } if (gdk_keymap_get_entries_for_keyval (NULL, GDK_Escape, &keys, &num_keys)) { gdk_error_trap_push (); #define X_GRAB_KEY(index, modifiers) \ XGrabKey (x_dpy, keys[index].keycode, modifiers, x_root, False, \ GrabModeAsync, GrabModeAsync) for (i = 0; i < num_keys; i++) { X_GRAB_KEY (i, 0); X_GRAB_KEY (i, LockMask); /* CapsLock */ X_GRAB_KEY (i, Mod2Mask); /* NumLock */ X_GRAB_KEY (i, Mod5Mask); /* ScrollLock */ X_GRAB_KEY (i, LockMask | Mod2Mask); /* CapsLock + NumLock */ X_GRAB_KEY (i, LockMask | Mod5Mask); /* CapsLock + ScrollLock */ X_GRAB_KEY (i, Mod2Mask | Mod5Mask); /* NumLock + ScrollLock */ X_GRAB_KEY (i, LockMask | Mod2Mask | Mod5Mask); /* all */ } #undef X_GRAB_KEY gdk_flush (); gdk_error_trap_pop (); } while (! cancel && ((x_win == None) || (buttons != 0))) { XEvent x_event; gint x, y, w, h; XAllowEvents (x_dpy, SyncPointer, CurrentTime); XWindowEvent (x_dpy, x_root, mask | KeyPressMask, &x_event); switch (x_event.type) { case ButtonPress: if (x_win == None) { x_win = x_event.xbutton.subwindow; if (x_win == None) x_win = x_root; #ifdef HAVE_X11_XMU_WINUTIL_H else if (! shootvals.decorate) x_win = XmuClientWindow (x_dpy, x_win); #endif shootvals.x2 = shootvals.x1 = x_event.xbutton.x_root; shootvals.y2 = shootvals.y1 = x_event.xbutton.y_root; } buttons++; break; case ButtonRelease: if (buttons > 0) buttons--; if (! buttons && shootvals.shoot_type == SHOOT_REGION) { x = MIN (shootvals.x1, shootvals.x2); y = MIN (shootvals.y1, shootvals.y2); w = ABS (shootvals.x2 - shootvals.x1); h = ABS (shootvals.y2 - shootvals.y1); if (w > 0 && h > 0) XDrawRectangle (x_dpy, x_root, x_gc, x, y, w, h); shootvals.x2 = x_event.xbutton.x_root; shootvals.y2 = x_event.xbutton.y_root; } break; case MotionNotify: if (buttons > 0) { x = MIN (shootvals.x1, shootvals.x2); y = MIN (shootvals.y1, shootvals.y2); w = ABS (shootvals.x2 - shootvals.x1); h = ABS (shootvals.y2 - shootvals.y1); if (w > 0 && h > 0) XDrawRectangle (x_dpy, x_root, x_gc, x, y, w, h); shootvals.x2 = x_event.xmotion.x_root; shootvals.y2 = x_event.xmotion.y_root; x = MIN (shootvals.x1, shootvals.x2); y = MIN (shootvals.y1, shootvals.y2); w = ABS (shootvals.x2 - shootvals.x1); h = ABS (shootvals.y2 - shootvals.y1); if (w > 0 && h > 0) XDrawRectangle (x_dpy, x_root, x_gc, x, y, w, h); } break; case KeyPress: { guint *keyvals; gint n; if (gdk_keymap_get_entries_for_keycode (NULL, x_event.xkey.keycode, NULL, &keyvals, &n)) { gint i; for (i = 0; i < n && ! cancel; i++) if (keyvals[i] == GDK_Escape) cancel = TRUE; g_free (keyvals); } } break; default: break; } } if (keys) { #define X_UNGRAB_KEY(index, modifiers) \ XUngrabKey (x_dpy, keys[index].keycode, modifiers, x_root) for (i = 0; i < num_keys; i++) { X_UNGRAB_KEY (i, 0); X_UNGRAB_KEY (i, LockMask); /* CapsLock */ X_UNGRAB_KEY (i, Mod2Mask); /* NumLock */ X_UNGRAB_KEY (i, Mod5Mask); /* ScrollLock */ X_UNGRAB_KEY (i, LockMask | Mod2Mask); /* CapsLock + NumLock */ X_UNGRAB_KEY (i, LockMask | Mod5Mask); /* CapsLock + ScrollLock */ X_UNGRAB_KEY (i, Mod2Mask | Mod5Mask); /* NumLock + ScrollLock */ X_UNGRAB_KEY (i, LockMask | Mod2Mask | Mod5Mask); /* all */ } #undef X_UNGRAB_KEY g_free (keys); } if (status == GrabSuccess) XUngrabPointer (x_dpy, CurrentTime); XFreeCursor (x_dpy, x_cursor); if (x_gc != None) XFreeGC (x_dpy, x_gc); return x_win; }
void gdk_x11_screen_get_work_area (GdkX11Screen *x11_screen, GdkRectangle *area) { Atom workarea; Atom type; Window win; int format; gulong num; gulong leftovers; gulong max_len = 4 * 32; guchar *ret_workarea = NULL; long *workareas; int result; int desktop; Display *display; display = GDK_SCREEN_XDISPLAY (x11_screen); workarea = XInternAtom (display, "_NET_WORKAREA", True); /* Defaults in case of error */ area->x = 0; area->y = 0; area->width = WidthOfScreen (x11_screen->xscreen); area->height = HeightOfScreen (x11_screen->xscreen); if (!gdk_x11_screen_supports_net_wm_hint (x11_screen, g_intern_static_string ("_NET_WORKAREA"))) return; if (workarea == None) return; win = XRootWindow (display, gdk_x11_screen_get_screen_number (x11_screen)); result = XGetWindowProperty (display, win, workarea, 0, max_len, False, AnyPropertyType, &type, &format, &num, &leftovers, &ret_workarea); if (result != Success || type == None || format == 0 || leftovers || num % 4 != 0) goto out; desktop = get_current_desktop (x11_screen); if (desktop + 1 > num / 4) /* fvwm gets this wrong */ goto out; workareas = (long *) ret_workarea; area->x = workareas[desktop * 4]; area->y = workareas[desktop * 4 + 1]; area->width = workareas[desktop * 4 + 2]; area->height = workareas[desktop * 4 + 3]; area->x /= x11_screen->surface_scale; area->y /= x11_screen->surface_scale; area->width /= x11_screen->surface_scale; area->height /= x11_screen->surface_scale; out: if (ret_workarea) XFree (ret_workarea); }
static void instance_init( GbdX11emitter* self ) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE( self,GBD_TYPE_X11EMITTER,GbdX11emitterPrivate ); g_datalist_init( &self->priv->mapcache ); self->priv->dpy = GDK_SCREEN_XDISPLAY( gdk_screen_get_default( ) ); }
gboolean vfs_exec_on_screen( GdkScreen* screen, const char* work_dir, char** argv, char** envp, const char* disp_name, GSpawnFlags flags, GError **err ) { #ifdef HAVE_SN SnLauncherContext * ctx = NULL; SnDisplay* display; #endif gboolean ret; GSpawnChildSetupFunc setup_func = NULL; extern char **environ; char** new_env = envp; int i, n_env = 0; char* display_name; int display_index = -1, startup_id_index = -1; if ( ! envp ) envp = environ; n_env = g_strv_length(envp); new_env = g_new0( char*, n_env + 4 ); for ( i = 0; i < n_env; ++i ) { /* g_debug( "old envp[%d] = \"%s\"" , i, envp[i]); */ if ( 0 == strncmp( envp[ i ], "DISPLAY=", 8 ) ) display_index = i; else { if ( 0 == strncmp( envp[ i ], "DESKTOP_STARTUP_ID=", 19 ) ) startup_id_index = i; new_env[i] = g_strdup( envp[ i ] ); } } #ifdef HAVE_SN display = sn_display_new ( GDK_SCREEN_XDISPLAY ( screen ), ( SnDisplayErrorTrapPush ) gdk_error_trap_push, ( SnDisplayErrorTrapPush ) gdk_error_trap_pop ); if ( G_LIKELY ( display ) ) { if ( !disp_name ) disp_name = argv[ 0 ]; ctx = sn_launcher_context_new( display, gdk_screen_get_number( screen ) ); sn_launcher_context_set_description( ctx, disp_name ); sn_launcher_context_set_name( ctx, g_get_prgname() ); sn_launcher_context_set_binary_name( ctx, argv[ 0 ] ); sn_launcher_context_set_workspace ( ctx, tvsn_get_active_workspace_number( screen ) ); /* FIXME: I don't think this is correct, other people seem to use CurrentTime here. However, using CurrentTime causes problems, so I so it like this. Maybe this is incorrect, but it works, so, who cares? */ /* time( &cur_time ); */ sn_launcher_context_initiate( ctx, g_get_prgname(), argv[ 0 ], gtk_get_current_event_time() /*cur_time*/ ); setup_func = (GSpawnChildSetupFunc) sn_launcher_context_setup_child_process; if( startup_id_index >= 0 ) g_free( new_env[i] ); else startup_id_index = i++; new_env[ startup_id_index ] = g_strconcat( "DESKTOP_STARTUP_ID=", sn_launcher_context_get_startup_id ( ctx ), NULL ); } #endif /* This is taken from gdk_spawn_on_screen */ display_name = gdk_screen_make_display_name ( screen ); if ( display_index >= 0 ) new_env[ display_index ] = g_strconcat( "DISPLAY=", display_name, NULL ); else new_env[ i++ ] = g_strconcat( "DISPLAY=", display_name, NULL ); g_free( display_name ); new_env[ i ] = NULL; ret = g_spawn_async( work_dir, argv, new_env, flags, NULL, NULL, NULL, err ); /* for debugging */ #if 0 g_debug( "debug vfs_execute_on_screen(): flags: %d, display_index=%d", flags, display_index ); for( i = 0; argv[i]; ++i ) { g_debug( "argv[%d] = \"%s\"" , i, argv[i] ); } for( i = 0; i < n_env /*new_env[i]*/; ++i ) { g_debug( "new_env[%d] = \"%s\"" , i, new_env[i] ); } if( ret ) g_debug( "the program was executed without error" ); else g_debug( "launch failed: %s", (*err)->message ); #endif g_strfreev( new_env ); #ifdef HAVE_SN if ( G_LIKELY ( ctx ) ) { if ( G_LIKELY ( ret ) ) g_timeout_add ( 20 * 1000, sn_timeout, ctx ); else { sn_launcher_context_complete ( ctx ); sn_launcher_context_unref ( ctx ); } } if ( G_LIKELY ( display ) ) sn_display_unref ( display ); #endif return ret; }
static void init_xft_settings (GdkScreen *screen) { GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen); Display *xdisplay = GDK_SCREEN_XDISPLAY (screen); int xscreen = GDK_SCREEN_XNUMBER (screen); double dpi_double; if (screen_x11->xft_init) return; screen_x11->xft_init = TRUE; if (!get_boolean_default (xdisplay, "antialias", &screen_x11->xft_antialias)) screen_x11->xft_antialias = TRUE; if (!get_boolean_default (xdisplay, "hinting", &screen_x11->xft_hinting)) screen_x11->xft_hinting = TRUE; if (!get_integer_default (xdisplay, "hintstyle", &screen_x11->xft_hintstyle)) screen_x11->xft_hintstyle = FC_HINT_FULL; if (!get_integer_default (xdisplay, "rgba", &screen_x11->xft_rgba)) { int subpixel = FC_RGBA_UNKNOWN; #if RENDER_MAJOR > 0 || RENDER_MINOR >= 6 if (_gdk_x11_have_render (screen_x11->display)) { int render_order = XRenderQuerySubpixelOrder (xdisplay, xscreen); switch (render_order) { default: case SubPixelUnknown: subpixel = FC_RGBA_UNKNOWN; break; case SubPixelHorizontalRGB: subpixel = FC_RGBA_RGB; break; case SubPixelHorizontalBGR: subpixel = FC_RGBA_BGR; break; case SubPixelVerticalRGB: subpixel = FC_RGBA_VRGB; break; case SubPixelVerticalBGR: subpixel = FC_RGBA_VBGR; break; case SubPixelNone: subpixel = FC_RGBA_NONE; break; } } #endif screen_x11->xft_rgba = subpixel; } if (!get_double_default (xdisplay, "dpi", &dpi_double)) dpi_double = (((double) DisplayHeight (xdisplay, xscreen) * 25.4) / (double) DisplayHeightMM (xdisplay, xscreen)); screen_x11->xft_dpi = (int)(0.5 + PANGO_SCALE * dpi_double); }
/* * draw_border_shape * Returns: void * Description: Draws a slight border around the decoration */ static void draw_border_shape (Display *xdisplay, Pixmap pixmap, Picture picture, int width, int height, decor_context_t *c, void *closure) { static XRenderColor white = { 0xffff, 0xffff, 0xffff, 0xffff }; decor_t d; decor_shadow_info_t *info = (decor_shadow_info_t *) closure; double save_decoration_alpha; GdkScreen *screen; memset (&d, 0, sizeof (d)); if (info) { gwd_decor_frame_ref (info->frame); d.frame = info->frame; d.state = info->state; d.actions = info->active; } else { d.frame = gwd_get_decor_frame ("normal"); d.state = 0; d.active = TRUE; } screen = gdk_screen_get_default (); d.surface = cairo_xlib_surface_create (GDK_SCREEN_XDISPLAY (screen), pixmap, GDK_VISUAL_XVISUAL (gdk_screen_get_rgba_visual (screen)), width, height); d.width = width; d.height = height; d.active = TRUE; d.draw = theme_draw_window_decoration; d.picture = picture; d.context = c; /* we use closure argument if maximized */ if (info) d.state = info->state; else d.state = 0; decor_get_default_layout (c, 1, 1, &d.border_layout); /* create shadow from opaque decoration * FIXME: Should not modify settings value * like this */ save_decoration_alpha = decoration_alpha; decoration_alpha = 1.0; (*d.draw) (&d); decoration_alpha = save_decoration_alpha; XRenderFillRectangle (xdisplay, PictOpSrc, picture, &white, c->left_space, c->top_space, width - c->left_space - c->right_space, height - c->top_space - c->bottom_space); if (!info) gwd_decor_frame_unref (d.frame); cairo_surface_destroy (d.surface); }
/* Returns NULL if screen could not be created. For instance, if * the driver does not support Xrandr 1.2. */ MateRRScreen * mate_rr_screen_new (GdkScreen *gdk_screen, MateRRScreenChanged callback, gpointer data, GError **error) { #ifdef HAVE_RANDR Display *dpy = GDK_SCREEN_XDISPLAY (gdk_screen); int event_base; int ignore; #endif g_return_val_if_fail (error == NULL || *error == NULL, NULL); _mate_desktop_init_i18n (); #ifdef HAVE_RANDR if (XRRQueryExtension (dpy, &event_base, &ignore)) { MateRRScreen *screen = g_new0 (MateRRScreen, 1); screen->gdk_screen = gdk_screen; screen->gdk_root = gdk_screen_get_root_window (gdk_screen); screen->xroot = gdk_x11_drawable_get_xid (screen->gdk_root); screen->xdisplay = dpy; screen->xscreen = gdk_x11_screen_get_xscreen (screen->gdk_screen); screen->connector_type_atom = XInternAtom (dpy, "ConnectorType", FALSE); screen->callback = callback; screen->data = data; screen->randr_event_base = event_base; XRRQueryVersion (dpy, &screen->rr_major_version, &screen->rr_minor_version); if (screen->rr_major_version > 1 || (screen->rr_major_version == 1 && screen->rr_minor_version < 2)) { g_set_error (error, MATE_RR_ERROR, MATE_RR_ERROR_NO_RANDR_EXTENSION, "RANDR extension is too old (must be at least 1.2)"); g_free (screen); return NULL; } screen->info = screen_info_new (screen, TRUE, error); if (!screen->info) { g_free (screen); return NULL; } if (screen->callback) { XRRSelectInput (screen->xdisplay, screen->xroot, RRScreenChangeNotifyMask); gdk_x11_register_standard_event_type (gdk_screen_get_display (gdk_screen), event_base, RRNotify + 1); gdk_window_add_filter (screen->gdk_root, screen_on_event, screen); } return screen; } else { #endif /* HAVE_RANDR */ g_set_error (error, MATE_RR_ERROR, MATE_RR_ERROR_NO_RANDR_EXTENSION, _("RANDR extension is not present")); return NULL; #ifdef HAVE_RANDR } #endif }
static void widget_realized (void) { GdkWindow * window = gtk_widget_get_window (s_widget); #ifdef GDK_WINDOWING_X11 GdkScreen * screen = gdk_window_get_screen (window); int nscreen = GDK_SCREEN_XNUMBER (screen); s_display = GDK_SCREEN_XDISPLAY (screen); s_xwindow = GDK_WINDOW_XID (window); /* Create s_context */ int attribs[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_ALPHA_SIZE, 1, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 1, None }; XVisualInfo * xvinfo = glXChooseVisual (s_display, nscreen, attribs); g_return_if_fail (xvinfo); /* Fix up visual/colormap */ GdkVisual * visual = gdk_x11_screen_lookup_visual (screen, xvinfo->visualid); g_return_if_fail (visual); gtk_widget_set_visual (s_widget, visual); s_context = glXCreateContext (s_display, xvinfo, 0, True); g_return_if_fail (s_context); XFree (xvinfo); glXMakeCurrent (s_display, s_xwindow, s_context); #endif #ifdef GDK_WINDOWING_WIN32 s_hwnd = GDK_WINDOW_HWND (window); s_hdc = GetDC (s_hwnd); PIXELFORMATDESCRIPTOR desc = { sizeof (PIXELFORMATDESCRIPTOR), 1, // version number (?) PFD_DRAW_TO_WINDOW | // format must support window PFD_SUPPORT_OPENGL | // format must support OpenGL PFD_DOUBLEBUFFER, // must support double buffering PFD_TYPE_RGBA, // request an RGBA format 24, // select a 8:8:8 bit color depth 0, 0, 0, 0, 0, 0, // color bits ignored (?) 0, // no alpha buffer 0, // shift bit ignored (?) 0, // no accumulation buffer 0, 0, 0, 0, // accumulation bits ignored (?) 16, // 16-bit z-buffer (depth buffer) 0, // no stencil buffer 0, // no auxiliary buffer (?) PFD_MAIN_PLANE, // main drawing layer 0, // reserved (?) 0, 0, 0 // layer masks ignored (?) }; int format = ChoosePixelFormat (s_hdc, & desc); g_return_if_fail (format != 0); SetPixelFormat (s_hdc, format, & desc); s_glrc = wglCreateContext (s_hdc); g_return_if_fail (s_glrc); wglMakeCurrent (s_hdc, s_glrc); #endif }
static gboolean panel_multiscreen_get_randr_monitors_for_screen (GdkScreen *screen, int *monitors_ret, GdkRectangle **geometries_ret) { #ifdef HAVE_RANDR Display *xdisplay; Window xroot; XRRScreenResources *resources; RROutput primary; GArray *geometries; int i; gboolean driver_is_pre_randr_1_2; if (!have_randr) return FALSE; /* GTK+ 2.14.x uses the Xinerama API, instead of RANDR, to get the * monitor geometries. It does this to avoid calling * XRRGetScreenResources(), which is slow as it re-detects all the * monitors --- note that XRRGetScreenResourcesCurrent() had not been * introduced yet. Using Xinerama in GTK+ has the bad side effect that * gdk_screen_get_monitor_plug_name() will return NULL, as Xinerama * does not provide that information, unlike RANDR. * * Here we need to identify the output names, so that we can put the * built-in LCD in a laptop *before* all other outputs. This is so * that mate-panel will normally prefer to appear on the "native" * display rather than on an external monitor. * * To get the output names and geometries, we will not use * gdk_screen_get_n_monitors() and friends, but rather we will call * XRR*() directly. * * See https://bugzilla.novell.com/show_bug.cgi?id=479684 for this * particular bug, and and * http://bugzilla.gnome.org/show_bug.cgi?id=562944 for a more * long-term solution. */ xdisplay = GDK_SCREEN_XDISPLAY (screen); #if GTK_CHECK_VERSION (3, 0, 0) xroot = GDK_WINDOW_XID (gdk_screen_get_root_window (screen)); #else xroot = GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (screen)); #endif #if (RANDR_MAJOR > 1 || (RANDR_MAJOR == 1 && RANDR_MINOR >= 3)) if (have_randr_1_3) { resources = XRRGetScreenResourcesCurrent (xdisplay, xroot); if (resources->noutput == 0) { /* This might happen if nothing tried to get randr * resources from the server before, so we need an * active probe. See comment #27 in * https://bugzilla.gnome.org/show_bug.cgi?id=597101 */ XRRFreeScreenResources (resources); resources = XRRGetScreenResources (xdisplay, xroot); } } else resources = XRRGetScreenResources (xdisplay, xroot); #else resources = XRRGetScreenResources (xdisplay, xroot); #endif if (!resources) return FALSE; primary = None; #if (RANDR_MAJOR > 1 || (RANDR_MAJOR == 1 && RANDR_MINOR >= 3)) if (have_randr_1_3) primary = XRRGetOutputPrimary (xdisplay, xroot); #endif geometries = g_array_sized_new (FALSE, FALSE, sizeof (GdkRectangle), resources->noutput); driver_is_pre_randr_1_2 = FALSE; for (i = 0; i < resources->noutput; i++) { XRROutputInfo *output; output = XRRGetOutputInfo (xdisplay, resources, resources->outputs[i]); /* Drivers before RANDR 1.2 return "default" for the output * name */ if (g_strcmp0 (output->name, "default") == 0) driver_is_pre_randr_1_2 = TRUE; if (output->connection != RR_Disconnected && output->crtc != 0) { XRRCrtcInfo *crtc; GdkRectangle rect; crtc = XRRGetCrtcInfo (xdisplay, resources, output->crtc); rect.x = crtc->x; rect.y = crtc->y; rect.width = crtc->width; rect.height = crtc->height; XRRFreeCrtcInfo (crtc); if (_panel_multiscreen_output_should_be_first (xdisplay, resources->outputs[i], output, primary)) g_array_prepend_vals (geometries, &rect, 1); else g_array_append_vals (geometries, &rect, 1); } XRRFreeOutputInfo (output); } XRRFreeScreenResources (resources); if (driver_is_pre_randr_1_2) { /* Drivers before RANDR 1.2 don't provide useful info about * outputs */ g_array_free (geometries, TRUE); return FALSE; } if (geometries->len == 0) { /* This can happen in at least one case: * https://bugzilla.novell.com/show_bug.cgi?id=543876 where all * monitors appear disconnected (possibly because the screen * is behing a KVM switch) -- see comment #8. * There might be other cases too, so we stay on the safe side. */ g_array_free (geometries, TRUE); return FALSE; } *monitors_ret = geometries->len; *geometries_ret = (GdkRectangle *) g_array_free (geometries, FALSE); return TRUE; #else return FALSE; #endif }
static GdkNativeWindow select_window (GdkScreen *screen) { #define MASK (ButtonPressMask | ButtonReleaseMask) Display *x_dpy; Cursor x_cursor; XEvent x_event; Window x_win; Window x_root; gint x_scr; gint status; gint buttons; x_dpy = GDK_SCREEN_XDISPLAY (screen); x_scr = GDK_SCREEN_XNUMBER (screen); x_win = None; x_root = RootWindow (x_dpy, x_scr); x_cursor = XCreateFontCursor (x_dpy, GDK_CROSSHAIR); buttons = 0; status = XGrabPointer (x_dpy, x_root, False, MASK, GrabModeSync, GrabModeAsync, x_root, x_cursor, CurrentTime); if (status != GrabSuccess) { g_message (_("Error grabbing the pointer %d"), status); return 0; } while ((x_win == None) || (buttons != 0)) { XAllowEvents (x_dpy, SyncPointer, CurrentTime); XWindowEvent (x_dpy, x_root, MASK, &x_event); switch (x_event.type) { case ButtonPress: if (x_win == None) { x_win = x_event.xbutton.subwindow; if (x_win == None) x_win = x_root; } buttons++; break; case ButtonRelease: if (buttons > 0) buttons--; break; default: g_assert_not_reached (); } } XUngrabPointer (x_dpy, CurrentTime); XFreeCursor (x_dpy, x_cursor); return x_win; }
static gboolean init_randr13 (GdkScreen *screen) { #ifdef HAVE_RANDR GdkDisplay *display = gdk_screen_get_display (screen); GdkX11Display *display_x11 = GDK_X11_DISPLAY (display); GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); Display *dpy = GDK_SCREEN_XDISPLAY (screen); XRRScreenResources *resources; RROutput primary_output; RROutput first_output = None; int i; GArray *monitors; gboolean randr12_compat = FALSE; if (!display_x11->have_randr13) return FALSE; resources = XRRGetScreenResourcesCurrent (x11_screen->xdisplay, x11_screen->xroot_window); if (!resources) return FALSE; monitors = g_array_sized_new (FALSE, TRUE, sizeof (GdkX11Monitor), resources->noutput); for (i = 0; i < resources->noutput; ++i) { XRROutputInfo *output = XRRGetOutputInfo (dpy, resources, resources->outputs[i]); /* Non RandR1.2 X driver have output name "default" */ randr12_compat |= !g_strcmp0 (output->name, "default"); if (output->connection == RR_Disconnected) { XRRFreeOutputInfo (output); continue; } if (output->crtc) { GdkX11Monitor monitor; XRRCrtcInfo *crtc = XRRGetCrtcInfo (dpy, resources, output->crtc); monitor.geometry.x = crtc->x; monitor.geometry.y = crtc->y; monitor.geometry.width = crtc->width; monitor.geometry.height = crtc->height; monitor.output = resources->outputs[i]; monitor.width_mm = output->mm_width; monitor.height_mm = output->mm_height; monitor.output_name = g_strdup (output->name); /* FIXME: need EDID parser */ monitor.manufacturer = NULL; g_array_append_val (monitors, monitor); XRRFreeCrtcInfo (crtc); } XRRFreeOutputInfo (output); } if (resources->noutput > 0) first_output = resources->outputs[0]; XRRFreeScreenResources (resources); /* non RandR 1.2 X driver doesn't return any usable multihead data */ if (randr12_compat) { guint n_monitors = monitors->len; free_monitors ((GdkX11Monitor *)g_array_free (monitors, FALSE), n_monitors); return FALSE; } g_array_sort (monitors, (GCompareFunc) monitor_compare_function); x11_screen->n_monitors = monitors->len; x11_screen->monitors = (GdkX11Monitor *)g_array_free (monitors, FALSE); x11_screen->primary_monitor = 0; primary_output = XRRGetOutputPrimary (x11_screen->xdisplay, x11_screen->xroot_window); for (i = 0; i < x11_screen->n_monitors; ++i) { if (x11_screen->monitors[i].output == primary_output) { x11_screen->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 (x11_screen->monitors[i].output_name, "LVDS", 4) == 0) { x11_screen->primary_monitor = i; break; } /* No primary specified and no LVDS found */ if (x11_screen->monitors[i].output == first_output) x11_screen->primary_monitor = i; } return x11_screen->n_monitors > 0; #endif return FALSE; }