static void na_tray_manager_set_visual_property (NaTrayManager *manager) { #ifdef GDK_WINDOWING_X11 GdkWindow *window; GdkDisplay *display; Visual *xvisual; Atom visual_atom; gulong data[1]; if (!manager->invisible) return; window = gtk_widget_get_window (manager->invisible); if (!window) return; /* The visual property is a hint to the tray icons as to what visual they * should use for their windows. If the X server has RGBA colormaps, then * we tell the tray icons to use a RGBA colormap and we'll composite the * icon onto its parents with real transparency. Otherwise, we just tell * the icon to use our colormap, and we'll do some hacks with parent * relative backgrounds to simulate transparency. */ display = gtk_widget_get_display (manager->invisible); visual_atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_SYSTEM_TRAY_VISUAL"); if (gdk_screen_get_rgba_visual (manager->screen) != NULL && gdk_display_supports_composite (display)) { xvisual = GDK_VISUAL_XVISUAL (gdk_screen_get_rgba_visual (manager->screen)); } else { /* We actually want the visual of the tray where the icons will * be embedded. In almost all cases, this will be the same as the visual * of the screen. */ GdkColormap *colormap; colormap = gdk_screen_get_default_colormap (manager->screen); xvisual = GDK_VISUAL_XVISUAL (gdk_colormap_get_visual (colormap)); } data[0] = XVisualIDFromVisual (xvisual); XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XWINDOW (window), visual_atom, XA_VISUALID, 32, PropModeReplace, (guchar *) &data, 1); #endif }
// Look for an existing Colormap that known to be associated with visual. static Colormap LookupColormapForVisual(const Screen* screen, const Visual* visual) { // common case if (visual == DefaultVisualOfScreen(screen)) return DefaultColormapOfScreen(screen); #ifdef MOZ_WIDGET_GTK2 // I wish there were a gdk_x11_display_lookup_screen. Display* dpy = DisplayOfScreen(screen); GdkDisplay* gdkDpy = gdk_x11_lookup_xdisplay(dpy); if (gdkDpy) { gint screen_num = 0; for (int s = 0; s < ScreenCount(dpy); ++s) { if (ScreenOfDisplay(dpy, s) == screen) { screen_num = s; break; } } GdkScreen* gdkScreen = gdk_display_get_screen(gdkDpy, screen_num); GdkColormap* gdkColormap = NULL; if (visual == GDK_VISUAL_XVISUAL(gdk_screen_get_rgb_visual(gdkScreen))) { // widget/src/gtk2/mozcontainer.c uses gdk_rgb_get_colormap() // which is inherited by child widgets, so this is the visual // expected when drawing directly to widget surfaces or surfaces // created using cairo_surface_create_similar with // CAIRO_CONTENT_COLOR. // gdk_screen_get_rgb_colormap is the generalization of // gdk_rgb_get_colormap for any screen. gdkColormap = gdk_screen_get_rgb_colormap(gdkScreen); } else if (visual == GDK_VISUAL_XVISUAL(gdk_screen_get_rgba_visual(gdkScreen))) { // This is the visual expected on displays with the Composite // extension enabled when the surface has been created using // cairo_surface_create_similar with CAIRO_CONTENT_COLOR_ALPHA, // as happens with non-unit opacity. gdkColormap = gdk_screen_get_rgba_colormap(gdkScreen); } if (gdkColormap != NULL) return GDK_COLORMAP_XCOLORMAP(gdkColormap); } #endif return None; }
static cairo_t * gdk_cairo_create (GdkDrawable *drawable) { int width, height; cairo_t *cr = NULL; cairo_surface_t *surface = NULL; GdkVisual *visual = gdk_drawable_get_visual (drawable); gdk_drawable_get_size (drawable, &width, &height); if (visual) surface = cairo_xlib_surface_create (GDK_DRAWABLE_XDISPLAY (drawable), GDK_DRAWABLE_XID (drawable), GDK_VISUAL_XVISUAL (visual), width, height); else if (gdk_drawable_get_depth (drawable) == 1) surface = cairo_xlib_surface_create_for_bitmap (GDK_PIXMAP_XDISPLAY (drawable), GDK_PIXMAP_XID (drawable), GDK_SCREEN_XSCREEN (gdk_drawable_get_screen (drawable)), width, height); else { g_warning ("Using Cairo rendering requires the drawable argument to\n" "have a specified colormap. All windows have a colormap,\n" "however, pixmaps only have colormap by default if they\n" "were created with a non-NULL window argument. Otherwise\n" "a colormap must be set on them with " "gdk_drawable_set_colormap"); return NULL; } if (surface) { cr = cairo_create (surface); cairo_surface_destroy (surface); } return cr; }
static gboolean parent_set_hook(GSignalInvocationHint*, guint, const GValue* param_values, void* data) { wxGLCanvas* win = (wxGLCanvas*)data; if (g_value_peek_pointer(¶m_values[0]) == win->m_wxwindow) { const XVisualInfo* xvi = win->GetXVisualInfo(); GdkVisual* visual = gtk_widget_get_visual(win->m_wxwindow); if (GDK_VISUAL_XVISUAL(visual)->visualid != xvi->visualid) { GdkScreen* screen = gtk_widget_get_screen(win->m_wxwindow); visual = gdk_x11_screen_lookup_visual(screen, xvi->visualid); #ifdef __WXGTK3__ gtk_widget_set_visual(win->m_wxwindow, visual); #else GdkColormap* colormap = gdk_colormap_new(visual, false); gtk_widget_set_colormap(win->m_wxwindow, colormap); g_object_unref(colormap); #endif } // remove hook return false; } return true; }
void image_to_pixmap(image *img, GdkPixmap *pm, int w, int h) { int realw, realh; int need_free; imlib_context_set_image(img->image); realw = imlib_image_get_width(); realh = imlib_image_get_height(); if (w != realw || h != realh) { Imlib_Image newimg; newimg = imlib_create_cropped_scaled_image(0, 0, realw, realh, w, h); imlib_context_set_image(newimg); need_free = TRUE; } else need_free = FALSE; imlib_context_set_display(GDK_WINDOW_XDISPLAY(pm)); imlib_context_set_visual(GDK_VISUAL_XVISUAL(gdk_visual_get_system())); imlib_context_set_colormap (GDK_COLORMAP_XCOLORMAP(gdk_colormap_get_system())); imlib_context_set_drawable(GDK_WINDOW_XWINDOW(pm)); imlib_context_set_blend(1); imlib_render_image_on_drawable(0, 0); if (need_free) imlib_free_image(); }
static Picture gdk_x11_drawable_get_picture (GdkDrawable *drawable) { GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable); if (!impl->picture) { Display *xdisplay = GDK_SCREEN_XDISPLAY (impl->screen); XRenderPictFormat *format; GdkVisual *visual = gdk_drawable_get_visual (GDK_DRAWABLE_IMPL_X11 (drawable)->wrapper); if (!visual) return None; format = XRenderFindVisualFormat (xdisplay, GDK_VISUAL_XVISUAL (visual)); if (format) { XRenderPictureAttributes attributes; attributes.graphics_exposures = False; impl->picture = XRenderCreatePicture (xdisplay, impl->xid, format, CPGraphicsExposure, &attributes); } } return impl->picture; }
NetscapePluginX11::NetscapePluginX11(NetscapePlugin& plugin, Display* display, uint64_t windowID) : m_plugin(plugin) , m_pluginDisplay(display) , m_windowID(windowID) { // It seems flash needs the socket to be in the same process, // I guess it uses gdk_window_lookup(), so we create a new socket here // containing a plug with the UI process socket embedded. m_platformPluginWidget = gtk_plug_new(static_cast<Window>(windowID)); // Hide the GtkPlug on delete-event since we assume the widget is valid while the plugin is active. // platformDestroy() will be called anyway right after the delete-event. g_signal_connect(m_platformPluginWidget, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), nullptr); GtkWidget* socket = gtk_socket_new(); // Do not show the plug widget until the socket is connected. g_signal_connect_swapped(socket, "plug-added", G_CALLBACK(gtk_widget_show), m_platformPluginWidget); g_signal_connect(socket, "plug-removed", G_CALLBACK(socketPlugRemovedCallback), nullptr); gtk_container_add(GTK_CONTAINER(m_platformPluginWidget), socket); gtk_widget_show(socket); Display* hostDisplay = x11HostDisplay(); m_npWindowID = gtk_socket_get_id(GTK_SOCKET(socket)); GdkWindow* window = gtk_widget_get_window(socket); m_setWindowCallbackStruct.display = GDK_WINDOW_XDISPLAY(window); m_setWindowCallbackStruct.visual = GDK_VISUAL_XVISUAL(gdk_window_get_visual(window)); m_setWindowCallbackStruct.depth = gdk_visual_get_depth(gdk_window_get_visual(window)); m_setWindowCallbackStruct.colormap = XCreateColormap(hostDisplay, GDK_ROOT_WINDOW(), m_setWindowCallbackStruct.visual, AllocNone); XFlush(hostDisplay); }
static gboolean parent_set_hook(GSignalInvocationHint*, guint, const GValue* param_values, void* data) { wxGLCanvas* win = (wxGLCanvas*)data; if (g_value_peek_pointer(¶m_values[0]) == win->m_wxwindow) { const XVisualInfo* xvi = (XVisualInfo*)win->m_vi; GdkVisual* visual = gtk_widget_get_visual(win->m_wxwindow); if (GDK_VISUAL_XVISUAL(visual)->visualid != xvi->visualid) { #if GTK_CHECK_VERSION(2, 2, 0) if (gtk_check_version(2, 2, 0) == NULL) { GdkScreen* screen = gtk_widget_get_screen(win->m_wxwindow); visual = gdk_x11_screen_lookup_visual(screen, xvi->visualid); } else #endif { visual = gdkx_visual_get(xvi->visualid); } GdkColormap* colormap = gdk_colormap_new(visual, false); gtk_widget_set_colormap(win->m_wxwindow, colormap); g_object_unref(colormap); } // remove hook return false; } return true; }
std::unique_ptr<BackingStoreBackendCairo> BackingStore::createBackend() { #if PLATFORM(GTK) && PLATFORM(X11) const auto& sharedDisplay = PlatformDisplay::sharedDisplay(); if (is<PlatformDisplayX11>(sharedDisplay)) { GdkVisual* visual = gtk_widget_get_visual(m_webPageProxy.viewWidget()); GdkScreen* screen = gdk_visual_get_screen(visual); ASSERT(downcast<PlatformDisplayX11>(sharedDisplay).native() == GDK_SCREEN_XDISPLAY(screen)); return std::make_unique<BackingStoreBackendCairoX11>(downcast<PlatformDisplayX11>(sharedDisplay).native(), GDK_WINDOW_XID(gdk_screen_get_root_window(screen)), GDK_VISUAL_XVISUAL(visual), gdk_visual_get_depth(visual), m_size, m_deviceScaleFactor); } #endif IntSize scaledSize = m_size; scaledSize.scale(m_deviceScaleFactor); #if PLATFORM(GTK) RefPtr<cairo_surface_t> surface = adoptRef(gdk_window_create_similar_surface(gtk_widget_get_window(m_webPageProxy.viewWidget()), CAIRO_CONTENT_COLOR_ALPHA, scaledSize.width(), scaledSize.height())); #else RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, scaledSize.width(), scaledSize.height())); #endif cairoSurfaceSetDeviceScale(surface.get(), m_deviceScaleFactor, m_deviceScaleFactor); return std::make_unique<BackingStoreBackendCairoImpl>(surface.get(), m_size); }
nsresult nsPluginNativeWindowGtk2::CreateXEmbedWindow() { NS_ASSERTION(!mSocketWidget,"Already created a socket widget!"); GdkWindow *parent_win = gdk_window_lookup((XID)window); mSocketWidget = gtk_socket_new(); //attach the socket to the container widget gtk_widget_set_parent_window(mSocketWidget, parent_win); // Make sure to handle the plug_removed signal. If we don't the // socket will automatically be destroyed when the plug is // removed, which means we're destroying it more than once. // SYNTAX ERROR. g_signal_connect(mSocketWidget, "plug_removed", G_CALLBACK(plug_removed_cb), NULL); g_signal_connect(mSocketWidget, "unrealize", G_CALLBACK(socket_unrealize_cb), NULL); g_signal_connect(mSocketWidget, "destroy", G_CALLBACK(gtk_widget_destroyed), &mSocketWidget); gpointer user_data = NULL; gdk_window_get_user_data(parent_win, &user_data); GtkContainer *container = GTK_CONTAINER(user_data); gtk_container_add(container, mSocketWidget); gtk_widget_realize(mSocketWidget); // The GtkSocket has a visible window, but the plugin's XEmbed plug will // cover this window. Normally GtkSockets let the X server paint their // background and this would happen immediately (before the plug is // created). Setting the background to None prevents the server from // painting this window, avoiding flicker. gdk_window_set_back_pixmap(mSocketWidget->window, NULL, FALSE); // Resize before we show SetAllocation(); gtk_widget_show(mSocketWidget); gdk_flush(); window = (void*)gtk_socket_get_id(GTK_SOCKET(mSocketWidget)); // Fill out the ws_info structure. // (The windowless case is done in nsObjectFrame.cpp.) GdkWindow *gdkWindow = gdk_window_lookup((XID)window); if(!gdkWindow) return NS_ERROR_FAILURE; mWsInfo.display = GDK_WINDOW_XDISPLAY(gdkWindow); mWsInfo.colormap = GDK_COLORMAP_XCOLORMAP(gdk_drawable_get_colormap(gdkWindow)); GdkVisual* gdkVisual = gdk_drawable_get_visual(gdkWindow); mWsInfo.visual = GDK_VISUAL_XVISUAL(gdkVisual); mWsInfo.depth = gdkVisual->depth; return NS_OK; }
static gboolean gdk_gl_pixmap_impl_x11_make_context_current (GdkGLDrawable *draw, GdkGLDrawable *read, GdkGLContext *glcontext) { GdkGLConfig *glconfig; GLXPixmap glxpixmap; GLXContext glxcontext; g_return_val_if_fail (GDK_IS_GL_PIXMAP_IMPL_X11 (draw), FALSE); g_return_val_if_fail (GDK_IS_GL_CONTEXT_IMPL_X11 (glcontext), FALSE); glconfig = GDK_GL_PIXMAP_IMPL_X11 (draw)->glconfig; glxpixmap = GDK_GL_PIXMAP_IMPL_X11 (draw)->glxpixmap; glxcontext = GDK_GL_CONTEXT_GLXCONTEXT (glcontext); if (glxpixmap == None || glxcontext == NULL) return FALSE; #ifdef GDKGLEXT_MULTIHEAD_SUPPORT GDK_GL_NOTE (MISC, g_message (" -- Pixmap: screen number = %d", GDK_SCREEN_XNUMBER (gdk_drawable_get_screen (GDK_DRAWABLE (draw))))); #endif /* GDKGLEXT_MULTIHEAD_SUPPORT */ GDK_GL_NOTE (MISC, g_message (" -- Pixmap: visual id = 0x%lx", GDK_VISUAL_XVISUAL (gdk_drawable_get_visual (GDK_DRAWABLE (draw)))->visualid)); GDK_GL_NOTE_FUNC_IMPL ("glXMakeCurrent"); if (!glXMakeCurrent (GDK_GL_CONFIG_XDISPLAY (glconfig), glxpixmap, glxcontext)) { g_warning ("glXMakeCurrent() failed"); _gdk_gl_context_set_gl_drawable (glcontext, NULL); /* currently unused. */ /* _gdk_gl_context_set_gl_drawable_read (glcontext, NULL); */ return FALSE; } _gdk_gl_context_set_gl_drawable (glcontext, draw); /* currently unused. */ /* _gdk_gl_context_set_gl_drawable_read (glcontext, read); */ if (_GDK_GL_CONFIG_AS_SINGLE_MODE (glconfig)) { /* We do this because we are treating a double-buffered frame buffer as a single-buffered frame buffer because the system does not appear to export any suitable single-buffered visuals (in which the following are necessary). */ glDrawBuffer (GL_FRONT); glReadBuffer (GL_FRONT); } GDK_GL_NOTE (MISC, _gdk_gl_print_gl_info ()); return TRUE; }
/* private at present... */ gboolean _gdk_x11_gl_overlay_get_info (GdkVisual *visual, GdkGLOverlayInfo *overlay_info) { __SOVPropArray *sov_props; VisualID xvisualid; int i; GDK_GL_NOTE_FUNC_PRIVATE (); g_return_val_if_fail (GDK_IS_VISUAL (visual), FALSE); g_return_val_if_fail (overlay_info != NULL, FALSE); /* Get SOV properties. */ #ifdef GDKGLEXT_MULTIHEAD_SUPPORT sov_props = gdk_gl_overlay_get_sov_props (gdk_visual_get_screen (visual)); #else /* GDKGLEXT_MULTIHEAD_SUPPORT */ sov_props = gdk_gl_overlay_get_sov_props (NULL); #endif /* GDKGLEXT_MULTIHEAD_SUPPORT */ /* Look up SOV property for the visual. */ xvisualid = GDK_VISUAL_XVISUAL (visual)->visualid; for (i = 0; i < sov_props->num; i++) { if ((VisualID) (sov_props->prop[i].overlay_visual) == xvisualid) { overlay_info->visual = visual; overlay_info->transparent_type = sov_props->prop[i].transparent_type; overlay_info->value = sov_props->prop[i].value; overlay_info->layer = sov_props->prop[i].layer; GDK_GL_NOTE (MISC, g_message (" -- overlay visual")); GDK_GL_NOTE (MISC, g_print ("transparent_type = %d\n", overlay_info->transparent_type)); GDK_GL_NOTE (MISC, g_print ("value = %u\n", overlay_info->value)); GDK_GL_NOTE (MISC, g_print ("layer = %d\n", overlay_info->layer)); return TRUE; } } /* meaningless */ overlay_info->visual = visual; overlay_info->transparent_type = GDK_GL_OVERLAY_TRANSPARENT_NONE; overlay_info->value = 0; overlay_info->layer = 0; GDK_GL_NOTE (MISC, g_message (" -- not overlay visual")); return FALSE; }
GtkWidget* gtk_xtbin_new (GdkWindow *parent_window, String * f) { GtkXtBin *xtbin; gpointer user_data; assert(parent_window != NULL); xtbin = g_object_new (GTK_TYPE_XTBIN, NULL); if (!xtbin) return (GtkWidget*)NULL; if (f) fallback = f; /* Initialize the Xt toolkit */ xtbin->parent_window = parent_window; xt_client_init(&(xtbin->xtclient), GDK_VISUAL_XVISUAL(gdk_rgb_get_visual()), GDK_COLORMAP_XCOLORMAP(gdk_rgb_get_colormap()), gdk_rgb_get_visual()->depth); if (!xtbin->xtclient.xtdisplay) { /* If XtOpenDisplay failed, we can't go any further. * Bail out. */ #ifdef DEBUG_XTBIN printf("gtk_xtbin_init: XtOpenDisplay() returned NULL.\n"); #endif g_free (xtbin); return (GtkWidget *)NULL; } /* Launch X event loop */ xt_client_xloop_create(); /* Build the hierachy */ xtbin->xtdisplay = xtbin->xtclient.xtdisplay; gtk_widget_set_parent_window(GTK_WIDGET(xtbin), parent_window); gdk_window_get_user_data(xtbin->parent_window, &user_data); if (user_data) gtk_container_add(GTK_CONTAINER(user_data), GTK_WIDGET(xtbin)); /* This GtkSocket has a visible window, but the Xt plug will cover this * window. Normally GtkSockets let the X server paint their background and * this would happen immediately (before the plug is mapped). Setting the * background to None prevents the server from painting this window, * avoiding flicker. */ gtk_widget_realize(GTK_WIDGET(xtbin)); gdk_window_set_back_pixmap(GTK_WIDGET(xtbin)->window, NULL, FALSE); return GTK_WIDGET (xtbin); }
/* 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; }
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 cairo_surface_t * create_root_surface (GdkScreen *screen) { Atom prop_root, prop_esetroot; gint number, width, height; Display *display; Pixmap pixmap; cairo_surface_t *surface; number = gdk_screen_get_number (screen); width = gdk_screen_get_width (screen); height = gdk_screen_get_height (screen); /* Open a new connection so with Retain Permanent so the pixmap remains when the greeter quits */ gdk_flush (); display = XOpenDisplay (gdk_display_get_name (gdk_screen_get_display (screen))); if (!display) { g_warning ("Failed to create root pixmap"); return NULL; } XSetCloseDownMode (display, RetainPermanent); pixmap = XCreatePixmap (display, RootWindow (display, number), width, height, DefaultDepth (display, number)); XCloseDisplay (display); /* Convert into a Cairo surface */ surface = cairo_xlib_surface_create (GDK_SCREEN_XDISPLAY (screen), pixmap, GDK_VISUAL_XVISUAL (gdk_screen_get_system_visual (screen)), width, height); /* Use this pixmap for the background */ XSetWindowBackgroundPixmap (GDK_SCREEN_XDISPLAY (screen), RootWindow (GDK_SCREEN_XDISPLAY (screen), number), cairo_xlib_surface_get_drawable (surface)); /* Fix to make the code work when a compositor is running */ Pixmap xpm = cairo_xlib_surface_get_drawable (surface); prop_root = XInternAtom(GDK_SCREEN_XDISPLAY (screen), "_XROOTPMAP_ID", False); prop_esetroot = XInternAtom(GDK_SCREEN_XDISPLAY (screen), "ESETROOT_PMAP_ID", False); XChangeProperty(GDK_SCREEN_XDISPLAY (screen), RootWindow (GDK_SCREEN_XDISPLAY (screen), number), prop_root, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &xpm, 1); XChangeProperty(GDK_SCREEN_XDISPLAY (screen), RootWindow (GDK_SCREEN_XDISPLAY (screen), number), prop_esetroot, XA_PIXMAP, 32, PropModeReplace, (unsigned char *) &xpm, 1); return surface; }
void set_desktop_background(GdkWindow *window) { Pixmap xpm = get_pixmap_prop(GDK_WINDOW_XWINDOW(window), "_XROOTPMAP_ID"); #ifdef HAVE_GTK3 if (xpm != None) { GdkScreen *screen = gdk_window_get_screen(window); Window root_return; int x, y; unsigned int width, height, bw, depth_ret; cairo_surface_t *surface = NULL; gdk_error_trap_push(); if (XGetGeometry(GDK_SCREEN_XDISPLAY(screen), xpm, &root_return, &x, &y, &width, &height, &bw, &depth_ret)) { surface = cairo_xlib_surface_create(GDK_SCREEN_XDISPLAY (screen), xpm, GDK_VISUAL_XVISUAL(gdk_screen_get_system_visual(screen)), width, height); } gdk_error_trap_pop_ignored (); cairo_pattern_t *pattern = cairo_pattern_create_for_surface(surface); gdk_window_set_background_pattern(window, pattern); cairo_surface_destroy(surface); // cairo_pattern_destroy ??? } else { GdkRGBA black = { 0.0, 0.0, 0.0, 1.0 }; gdk_window_set_background_rgba(window, &black); } #else if (xpm != None) { GDKPIXMAP *gpm = gdk_pixmap_foreign_new(xpm); gdk_window_set_back_pixmap (window, gpm, FALSE); g_object_unref (gpm); } #endif }
gboolean gdk_gl_window_make_context_current (GdkGLDrawable *draw, GdkGLContext *glcontext) { GdkGLDrawable *read = draw; GdkGLConfig *glconfig; Window glxwindow; GLXContext glxcontext; g_return_val_if_fail (GDK_IS_GL_WINDOW (draw), FALSE); g_return_val_if_fail (GDK_IS_GL_CONTEXT_IMPL_X11 (glcontext), FALSE); glconfig = GDK_GL_WINDOW (draw)->glconfig; glxwindow = GDK_GL_WINDOW (draw)->glxwindow; glxcontext = GDK_GL_CONTEXT_GLXCONTEXT (glcontext); if (glxwindow == None || glxcontext == NULL) return FALSE; GDK_GL_NOTE (MISC, g_message (" -- Window: screen number = %d", GDK_SCREEN_XNUMBER (gdk_drawable_get_screen (GDK_DRAWABLE (draw))))); GDK_GL_NOTE (MISC, g_message (" -- Window: visual id = 0x%lx", GDK_VISUAL_XVISUAL (gdk_drawable_get_visual (GDK_DRAWABLE (draw)))->visualid)); GDK_GL_NOTE_FUNC_IMPL ("glXMakeCurrent"); if (!glXMakeCurrent (GDK_GL_CONFIG_XDISPLAY (glconfig), glxwindow, glxcontext)) { g_warning ("glXMakeCurrent() failed"); _gdk_gl_context_set_gl_drawable (glcontext, NULL); return FALSE; } _gdk_gl_context_set_gl_drawable (glcontext, draw); if (_GDK_GL_CONFIG_AS_SINGLE_MODE (glconfig)) { /* We do this because we are treating a double-buffered frame buffer as a single-buffered frame buffer because the system does not appear to export any suitable single-buffered visuals (in which the following are necessary). */ glDrawBuffer (GL_FRONT); glReadBuffer (GL_FRONT); } GDK_GL_NOTE (MISC, _gdk_gl_print_gl_info ()); return TRUE; }
static void gtku_gl_drawing_area_init (GtkuGLDrawingArea * self) { GtkuGLDrawingAreaPrivate * priv = GTKU_GL_DRAWING_AREA_GET_PRIVATE (self); gtk_widget_set_double_buffered (GTK_WIDGET (self), FALSE); priv->dpy = NULL; priv->visual = NULL; priv->context = NULL; #ifdef USE_VBLANK priv->vblank_watch = 0; priv->pipe[0] = -1; priv->thread = 0; priv->quit_thread = 0; priv->swap_requested = 0; #endif XVisualInfo * vinfo = glXChooseVisual (GDK_DISPLAY (), GDK_SCREEN_XNUMBER (gdk_screen_get_default ()), attr_list); if (!vinfo) { fprintf (stderr, "Preferred visual not found, using default...\n"); return; } VisualID desired_id = vinfo->visualid; XFree (vinfo); GList * visuals = gdk_list_visuals (); GList * vis; for (vis = visuals; vis; vis = vis->next) { Visual * xv = GDK_VISUAL_XVISUAL (vis->data); if (XVisualIDFromVisual (xv) == desired_id) { GdkColormap * colormap = gdk_colormap_new (vis->data, FALSE); gtk_widget_set_colormap (GTK_WIDGET (self), colormap); g_object_unref (G_OBJECT (colormap)); break; } } g_list_free (visuals); }
bool NetscapePlugin::platformPostInitializeWindowed(bool needsXEmbed, uint64_t windowID) { m_npWindow.type = NPWindowTypeWindow; if (!needsXEmbed) { notImplemented(); return false; } Display* display = x11HostDisplay(); #if PLATFORM(GTK) // It seems flash needs the socket to be in the same process, // I guess it uses gdk_window_lookup(), so we create a new socket here // containing a plug with the UI process socket embedded. m_platformPluginWidget = gtk_plug_new(static_cast<Window>(windowID)); GtkWidget* socket = gtk_socket_new(); // Do not show the plug widget until the socket is connected. g_signal_connect_swapped(socket, "plug-added", G_CALLBACK(gtk_widget_show), m_platformPluginWidget); g_signal_connect(socket, "plug-removed", G_CALLBACK(socketPlugRemovedCallback), nullptr); gtk_container_add(GTK_CONTAINER(m_platformPluginWidget), socket); gtk_widget_show(socket); m_npWindow.window = GINT_TO_POINTER(gtk_socket_get_id(GTK_SOCKET(socket))); GdkWindow* window = gtk_widget_get_window(socket); NPSetWindowCallbackStruct* callbackStruct = static_cast<NPSetWindowCallbackStruct*>(m_npWindow.ws_info); callbackStruct->display = GDK_WINDOW_XDISPLAY(window); callbackStruct->visual = GDK_VISUAL_XVISUAL(gdk_window_get_visual(window)); callbackStruct->depth = gdk_visual_get_depth(gdk_window_get_visual(window)); callbackStruct->colormap = XCreateColormap(display, GDK_ROOT_WINDOW(), callbackStruct->visual, AllocNone); #else UNUSED_PARAM(windowID); #endif XFlush(display); callSetWindow(); return true; }
cairo_surface_t * create_native_surface_and_wrap (int w, int h, GtkWidget *parent_style_window) { GdkWindow *window; GdkVisual *visual; cairo_surface_t *surface; Display *display; Pixmap pixmap; if (w <= 0 || h <= 0) abort (); display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); window = gtk_widget_get_window (parent_style_window); visual = gdk_window_get_visual (window); pixmap = XCreatePixmap (display, GDK_WINDOW_XID (window), w, h, gdk_visual_get_depth (visual)); surface = cairo_xlib_surface_create (display, pixmap, GDK_VISUAL_XVISUAL (visual), w, h); return surface; }
static cairo_t * get_cairo_context (gamine_t *cb) { Display *dpy; Drawable xid; Visual *visual; GdkDrawable *drawable; gint x_offset, y_offset; gint width, height; cairo_surface_t *surface; cairo_t *context; if (cb->is_cairo) return cb->cr; //if (GDK_IS_WINDOW (window)) { gdk_window_get_internal_paint_info ((cb->da)->window, &drawable,&x_offset, &y_offset); //} else { // drawable = window; //}; dpy = gdk_x11_drawable_get_xdisplay (drawable); xid = gdk_x11_drawable_get_xid (drawable); gdk_drawable_get_size (drawable, &width, &height); visual = GDK_VISUAL_XVISUAL(gdk_drawable_get_visual (drawable)); //create an xlib surface surface = cairo_xlib_surface_create (dpy, xid, visual, width, height); //create context context = cairo_create (surface); //cairo_surface_destroy (surface); //if (GDK_IS_WINDOW (window)) cairo_translate (context, -x_offset, -y_offset); cb->is_cairo = TRUE; cb->cr = context; cb->surface = surface; return context; }
Pixmap ShadowHelper::createPixmap( const Cairo::Surface& surface, int opacity ) const { assert( surface.isValid() ); int width(0); int height(0); cairo_surface_get_size( surface, width, height ); GdkScreen* screen = gdk_screen_get_default(); Display* display( GDK_DISPLAY_XDISPLAY( gdk_screen_get_display( screen ) ) ); Window root( GDK_WINDOW_XID( gdk_screen_get_root_window( screen ) ) ); Pixmap pixmap = XCreatePixmap( display, root, width, height, 32 ); // create surface for pixmap { Cairo::Surface dest( cairo_xlib_surface_create( display, pixmap, GDK_VISUAL_XVISUAL( gdk_screen_get_rgba_visual( screen ) ), width, height ) ); Cairo::Context context( dest ); cairo_set_operator( context, CAIRO_OPERATOR_SOURCE ); cairo_rectangle( context, 0, 0, width, height ); cairo_set_source_surface( context, surface, 0, 0 ); cairo_fill( context ); if( opacity < 255 ) { cairo_set_operator( context, CAIRO_OPERATOR_DEST_IN ); cairo_set_source( context, ColorUtils::Rgba( 0, 0, 0, double(opacity)/255 ) ); cairo_rectangle( context, 0, 0, width, height ); cairo_fill( context ); } } return pixmap; }
nsresult nsPluginNativeWindowGtk::CreateXEmbedWindow(bool aEnableXtFocus) { NS_ASSERTION(!mSocketWidget,"Already created a socket widget!"); GdkDisplay *display = gdk_display_get_default(); GdkWindow *parent_win = gdk_x11_window_lookup_for_display(display, GetWindow()); mSocketWidget = gtk_socket_new(); //attach the socket to the container widget gtk_widget_set_parent_window(mSocketWidget, parent_win); // enable/disable focus event handlers, // see plugin_window_filter_func() for details g_object_set_data(G_OBJECT(mSocketWidget), "enable-xt-focus", (void *)aEnableXtFocus); // Make sure to handle the plug_removed signal. If we don't the // socket will automatically be destroyed when the plug is // removed, which means we're destroying it more than once. // SYNTAX ERROR. g_signal_connect(mSocketWidget, "plug_removed", G_CALLBACK(plug_removed_cb), nullptr); g_signal_connect(mSocketWidget, "unrealize", G_CALLBACK(socket_unrealize_cb), nullptr); g_signal_connect(mSocketWidget, "destroy", G_CALLBACK(gtk_widget_destroyed), &mSocketWidget); gpointer user_data = nullptr; gdk_window_get_user_data(parent_win, &user_data); GtkContainer *container = GTK_CONTAINER(user_data); gtk_container_add(container, mSocketWidget); gtk_widget_realize(mSocketWidget); // The GtkSocket has a visible window, but the plugin's XEmbed plug will // cover this window. Normally GtkSockets let the X server paint their // background and this would happen immediately (before the plug is // created). Setting the background to None prevents the server from // painting this window, avoiding flicker. // TODO GTK3 #if (MOZ_WIDGET_GTK == 2) gdk_window_set_back_pixmap(gtk_widget_get_window(mSocketWidget), nullptr, FALSE); #endif // Resize before we show SetAllocation(); gtk_widget_show(mSocketWidget); gdk_flush(); SetWindow(gtk_socket_get_id(GTK_SOCKET(mSocketWidget))); // Fill out the ws_info structure. // (The windowless case is done in nsPluginFrame.cpp.) GdkWindow *gdkWindow = gdk_x11_window_lookup_for_display(display, GetWindow()); if(!gdkWindow) return NS_ERROR_FAILURE; mWsInfo.display = GDK_WINDOW_XDISPLAY(gdkWindow); #if (MOZ_WIDGET_GTK == 2) mWsInfo.colormap = GDK_COLORMAP_XCOLORMAP(gdk_drawable_get_colormap(gdkWindow)); GdkVisual* gdkVisual = gdk_drawable_get_visual(gdkWindow); mWsInfo.depth = gdkVisual->depth; #else mWsInfo.colormap = None; GdkVisual* gdkVisual = gdk_window_get_visual(gdkWindow); mWsInfo.depth = gdk_visual_get_depth(gdkVisual); #endif mWsInfo.visual = GDK_VISUAL_XVISUAL(gdkVisual); return NS_OK; }
RedirectedXCompositeWindow::RedirectedXCompositeWindow(GdkWindow* parentWindow, std::function<void()> damageNotify) : m_display(GDK_DISPLAY_XDISPLAY(gdk_window_get_display(parentWindow))) , m_window(0) , m_parentWindow(0) , m_pixmap(0) , m_damage(0) , m_needsNewPixmapAfterResize(false) { Screen* screen = DefaultScreenOfDisplay(m_display); GdkVisual* visual = gdk_window_get_visual(parentWindow); Colormap colormap = XCreateColormap(m_display, RootWindowOfScreen(screen), GDK_VISUAL_XVISUAL(visual), AllocNone); // This is based on code from Chromium: src/content/common/gpu/image_transport_surface_linux.cc XSetWindowAttributes windowAttributes; windowAttributes.override_redirect = True; windowAttributes.colormap = colormap; // CWBorderPixel must be present when the depth doesn't match the parent's one. // See http://cgit.freedesktop.org/xorg/xserver/tree/dix/window.c?id=xorg-server-1.16.0#n703. windowAttributes.border_pixel = 0; m_parentWindow = XCreateWindow(m_display, RootWindowOfScreen(screen), WidthOfScreen(screen) + 1, 0, 1, 1, 0, gdk_visual_get_depth(visual), InputOutput, GDK_VISUAL_XVISUAL(visual), CWOverrideRedirect | CWColormap | CWBorderPixel, &windowAttributes); XMapWindow(m_display, m_parentWindow); windowAttributes.event_mask = StructureNotifyMask; windowAttributes.override_redirect = False; // Create the window of at last 1x1 since X doesn't allow to create empty windows. m_window = XCreateWindow(m_display, m_parentWindow, 0, 0, std::max(1, m_size.width()), std::max(1, m_size.height()), 0, CopyFromParent, InputOutput, CopyFromParent, CWEventMask, &windowAttributes); XMapWindow(m_display, m_window); XFreeColormap(m_display, colormap); xDamageNotifier().add(m_window, WTF::move(damageNotify)); while (1) { XEvent event; XWindowEvent(m_display, m_window, StructureNotifyMask, &event); if (event.type == MapNotify && event.xmap.window == m_window) break; } XSelectInput(m_display, m_window, NoEventMask); XCompositeRedirectWindow(m_display, m_window, CompositeRedirectManual); m_damage = XDamageCreate(m_display, m_window, XDamageReportNonEmpty); }
nsresult nsPluginNativeWindowGtk2::CreateXCompositedWindow() { NS_ASSERTION(!mSocketWidget,"Already created a socket widget!"); mParentWindow = gtk_window_new(GTK_WINDOW_POPUP); mSocketWidget = gtk_socket_new(); GdkWindow *parent_win = mParentWindow->window; //attach the socket to the container widget gtk_widget_set_parent_window(mSocketWidget, parent_win); // Make sure to handle the plug_removed signal. If we don't the // socket will automatically be destroyed when the plug is // removed, which means we're destroying it more than once. // SYNTAX ERROR. g_signal_connect(mSocketWidget, "plug_removed", G_CALLBACK(plug_removed_cb), NULL); g_signal_connect(mSocketWidget, "destroy", G_CALLBACK(gtk_widget_destroyed), &mSocketWidget); /*gpointer user_data = NULL; gdk_window_get_user_data(parent_win, &user_data); */ GtkContainer *container = GTK_CONTAINER(mParentWindow); gtk_container_add(container, mSocketWidget); gtk_widget_realize(mSocketWidget); // Resize before we show SetAllocation(); gtk_widget_set_size_request (mSocketWidget, width, height); /* move offscreen */ gtk_window_move (GTK_WINDOW(mParentWindow), width+1000, height+1000); gtk_widget_show(mSocketWidget); gtk_widget_show_all(mParentWindow); /* store away a reference to the socketwidget */ mPlugWindow = (mSocketWidget); gdk_flush(); window = (nsPluginPort *)gtk_socket_get_id(GTK_SOCKET(mSocketWidget)); /* This is useful if we still have the plugin window inline * i.e. firefox vs. fennec */ // gdk_window_set_composited(mSocketWidget->window, TRUE); if (!mDamage) { /* we install a general handler instead of one specific to a particular window * because we don't have a GdkWindow for the plugin window */ gdk_window_add_filter (parent_win, plugin_composite_filter_func, this); int junk; if (!XDamageQueryExtension (GDK_DISPLAY (), &xdamage_event_base, &junk)) printf ("This requires the XDamage extension"); mDamage = XDamageCreate(GDK_DISPLAY(), (Drawable)window, XDamageReportNonEmpty); XCompositeRedirectWindow (GDK_DISPLAY(), (Drawable)window, CompositeRedirectManual); /* this is a hack to avoid having flash causing a crash when it is unloaded. * libplayback sets up dbus_connection_filters. When flash is unloaded it takes * libplayback with it, however the connection filters are not removed * which causes a crash when dbus tries to execute them. dlopening libplayback * ensures that those functions stay around even after flash is gone. */ static void *libplayback_handle; if (!libplayback_handle) { libplayback_handle = dlopen("libplayback-1.so.0", RTLD_NOW); } } // Fill out the ws_info structure. // (The windowless case is done in nsObjectFrame.cpp.) GdkWindow *gdkWindow = gdk_window_lookup((XID)window); mWsInfo.display = GDK_WINDOW_XDISPLAY(gdkWindow); mWsInfo.colormap = GDK_COLORMAP_XCOLORMAP(gdk_drawable_get_colormap(gdkWindow)); GdkVisual* gdkVisual = gdk_drawable_get_visual(gdkWindow); mWsInfo.visual = GDK_VISUAL_XVISUAL(gdkVisual); mWsInfo.depth = gdkVisual->depth; return NS_OK; }
static void setup_font_sample(GtkWidget* darea, Antialiasing antialiasing, Hinting hinting) { const char* string1 = "abcfgop AO "; const char* string2 = "abcfgop"; XftColor black, white; XRenderColor rendcolor; Display* xdisplay = gdk_x11_get_default_xdisplay(); #if GTK_CHECK_VERSION (3, 0, 0) Colormap xcolormap = DefaultColormap(xdisplay, 0); #else GdkColormap* colormap = gdk_rgb_get_colormap(); Colormap xcolormap = GDK_COLORMAP_XCOLORMAP(colormap); #endif #if GTK_CHECK_VERSION (3, 0, 0) GdkVisual* visual = gdk_visual_get_system (); #else GdkVisual* visual = gdk_colormap_get_visual(colormap); #endif Visual* xvisual = GDK_VISUAL_XVISUAL(visual); FcPattern* pattern; XftFont* font1; XftFont* font2; XGlyphInfo extents1 = { 0 }; XGlyphInfo extents2 = { 0 }; #if !GTK_CHECK_VERSION (3, 0, 0) GdkPixmap* pixmap; #endif XftDraw* draw; GdkPixbuf* tmp_pixbuf; GdkPixbuf* pixbuf; int width, height; int ascent, descent; pattern = FcPatternBuild (NULL, FC_FAMILY, FcTypeString, "Serif", FC_SLANT, FcTypeInteger, FC_SLANT_ROMAN, FC_SIZE, FcTypeDouble, 18., NULL); font1 = open_pattern (pattern, antialiasing, hinting); FcPatternDestroy (pattern); pattern = FcPatternBuild (NULL, FC_FAMILY, FcTypeString, "Serif", FC_SLANT, FcTypeInteger, FC_SLANT_ITALIC, FC_SIZE, FcTypeDouble, 20., NULL); font2 = open_pattern (pattern, antialiasing, hinting); FcPatternDestroy (pattern); ascent = 0; descent = 0; if (font1) { XftTextExtentsUtf8 (xdisplay, font1, (unsigned char*) string1, strlen (string1), &extents1); ascent = MAX (ascent, font1->ascent); descent = MAX (descent, font1->descent); } if (font2) { XftTextExtentsUtf8 (xdisplay, font2, (unsigned char*) string2, strlen (string2), &extents2); ascent = MAX (ascent, font2->ascent); descent = MAX (descent, font2->descent); } width = extents1.xOff + extents2.xOff + 4; height = ascent + descent + 2; #if !GTK_CHECK_VERSION (3, 0, 0) pixmap = gdk_pixmap_new (NULL, width, height, visual->depth); #endif #if GTK_CHECK_VERSION (3, 0, 0) draw = XftDrawCreate (xdisplay, GDK_WINDOW_XID (gdk_screen_get_root_window (gdk_screen_get_default ())), xvisual, xcolormap); #else draw = XftDrawCreate (xdisplay, GDK_DRAWABLE_XID (pixmap), xvisual, xcolormap); #endif rendcolor.red = 0; rendcolor.green = 0; rendcolor.blue = 0; rendcolor.alpha = 0xffff; XftColorAllocValue(xdisplay, xvisual, xcolormap, &rendcolor, &black); rendcolor.red = 0xffff; rendcolor.green = 0xffff; rendcolor.blue = 0xffff; rendcolor.alpha = 0xffff; XftColorAllocValue(xdisplay, xvisual, xcolormap, &rendcolor, &white); XftDrawRect(draw, &white, 0, 0, width, height); if (font1) { XftDrawStringUtf8(draw, &black, font1, 2, 2 + ascent, (unsigned char*) string1, strlen(string1)); } if (font2) { XftDrawStringUtf8(draw, &black, font2, 2 + extents1.xOff, 2 + ascent, (unsigned char*) string2, strlen(string2)); } XftDrawDestroy(draw); if (font1) { XftFontClose(xdisplay, font1); } if (font2) { XftFontClose(xdisplay, font2); } #if GTK_CHECK_VERSION (3, 0, 0) tmp_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE,8, width, height); #else tmp_pixbuf = gdk_pixbuf_get_from_drawable(NULL, pixmap, colormap, 0, 0, 0, 0, width, height); #endif pixbuf = gdk_pixbuf_scale_simple(tmp_pixbuf, 1 * width, 1 * height, GDK_INTERP_TILES); #if !GTK_CHECK_VERSION (3, 0, 0) g_object_unref(pixmap); #endif g_object_unref(tmp_pixbuf); g_object_set_data_full(G_OBJECT(darea), "sample-pixbuf", pixbuf, (GDestroyNotify) g_object_unref); #if GTK_CHECK_VERSION (3, 0, 0) gtk_widget_set_size_request (GTK_WIDGET(darea), width + 2, height + 2); g_signal_connect(darea, "draw", G_CALLBACK(sample_draw), NULL); #else g_signal_connect(darea, "size_request", G_CALLBACK(sample_size_request), NULL); g_signal_connect(darea, "expose_event", G_CALLBACK(sample_expose), NULL); #endif }
/* * 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); }
GtkWidget* gtk_xtbin_new (GdkWindow *parent_window, String * f) { GtkXtBin *xtbin; gpointer user_data; assert(parent_window != NULL); xtbin = gtk_type_new (GTK_TYPE_XTBIN); if (!xtbin) return (GtkWidget*)NULL; if (f) fallback = f; /* Initialize the Xt toolkit */ xtbin->parent_window = parent_window; xt_client_init(&(xtbin->xtclient), GDK_VISUAL_XVISUAL(gdk_window_get_visual(parent_window )), GDK_COLORMAP_XCOLORMAP(gdk_window_get_colormap(parent_window)), gdk_window_get_visual(parent_window )->depth); if (!xtbin->xtclient.xtdisplay) { /* If XtOpenDisplay failed, we can't go any further. * Bail out. */ #ifdef DEBUG_XTBIN printf("gtk_xtbin_init: XtOpenDisplay() returned NULL.\n"); #endif g_free (xtbin); return (GtkWidget *)NULL; } /* If this is the first running widget, hook this display into the mainloop */ if (0 == num_widgets) { int cnumber; /* * hook Xt event loop into the glib event loop. */ /* the assumption is that gtk_init has already been called */ GSource* gs = g_source_new(&xt_event_funcs, sizeof(GSource)); if (!gs) { return NULL; } g_source_set_priority(gs, GDK_PRIORITY_EVENTS); g_source_set_can_recurse(gs, TRUE); tag = g_source_attach(gs, (GMainContext*)NULL); #ifdef VMS cnumber = XConnectionNumber(xtdisplay); #else cnumber = ConnectionNumber(xtdisplay); #endif xt_event_poll_fd.fd = cnumber; xt_event_poll_fd.events = G_IO_IN; xt_event_poll_fd.revents = 0; /* hmm... is this correct? */ g_main_context_add_poll ((GMainContext*)NULL, &xt_event_poll_fd, G_PRIORITY_LOW); /* add a timer so that we can poll and process Xt timers */ xt_polling_timer_id = gtk_timeout_add(25, (GtkFunction)xt_event_polling_timer_callback, xtdisplay); } /* Bump up our usage count */ num_widgets++; /* Build the hierachy */ xtbin->xtdisplay = xtbin->xtclient.xtdisplay; gtk_widget_set_parent_window(GTK_WIDGET(xtbin), parent_window); gdk_window_get_user_data(xtbin->parent_window, &user_data); if (user_data) gtk_container_add(GTK_CONTAINER(user_data), GTK_WIDGET(xtbin)); return GTK_WIDGET (xtbin); }
static GdkPixmap * create_text_pixmap(GtkWidget *drawing_area, FT_Face face) { gint i, pixmap_width, pixmap_height, pos_y, textlen; GdkPixmap *pixmap = NULL; const gchar *text; Display *xdisplay; Drawable xdrawable; Visual *xvisual; Colormap xcolormap; XftDraw *draw; XftColor colour; XGlyphInfo extents; XftFont *font; gint *sizes = NULL, n_sizes, alpha_size; FcCharSet *charset = NULL; cairo_t *cr; GdkWindow *window = gtk_widget_get_window (drawing_area); text = pango_language_get_sample_string(NULL); if (! check_font_contain_text (face, text)) { pango_language_get_sample_string (pango_language_from_string ("en_US")); } textlen = strlen(text); /* create the XftDraw */ xdisplay = GDK_PIXMAP_XDISPLAY(window); #if GTK_CHECK_VERSION(3, 0, 0) xvisual = GDK_VISUAL_XVISUAL(gdk_window_get_visual(window)); #else xvisual = GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(window)); #endif xcolormap = GDK_COLORMAP_XCOLORMAP(gdk_drawable_get_colormap(window)); XftColorAllocName(xdisplay, xvisual, xcolormap, "black", &colour); /* work out what sizes to render */ if (FT_IS_SCALABLE(face)) { n_sizes = 8; sizes = g_new(gint, n_sizes); sizes[0] = 8; sizes[1] = 10; sizes[2] = 12; sizes[3] = 18; sizes[4] = 24; sizes[5] = 36; sizes[6] = 48; sizes[7] = 72; alpha_size = 24; } else { /* use fixed sizes */ n_sizes = face->num_fixed_sizes; sizes = g_new(gint, n_sizes); alpha_size = 0; for (i = 0; i < face->num_fixed_sizes; i++) { sizes[i] = face->available_sizes[i].height; /* work out which font size to render */ if (face->available_sizes[i].height <= 24) alpha_size = face->available_sizes[i].height; } } /* calculate size of pixmap to use (with 4 pixels padding) ... */ pixmap_width = 8; pixmap_height = 8; font = get_font(xdisplay, face, alpha_size, charset); charset = FcCharSetCopy (font->charset); XftTextExtentsUtf8(xdisplay, font, (guchar *)lowercase_text, strlen(lowercase_text), &extents); pixmap_height += extents.height + 4; pixmap_width = MAX(pixmap_width, 8 + extents.width); XftTextExtentsUtf8(xdisplay, font, (guchar *)uppercase_text, strlen(uppercase_text), &extents); pixmap_height += extents.height + 4; pixmap_width = MAX(pixmap_width, 8 + extents.width); XftTextExtentsUtf8(xdisplay, font, (guchar *)punctuation_text, strlen(punctuation_text), &extents); pixmap_height += extents.height + 4; pixmap_width = MAX(pixmap_width, 8 + extents.width); XftFontClose(xdisplay, font); pixmap_height += 8; for (i = 0; i < n_sizes; i++) { font = get_font(xdisplay, face, sizes[i], charset); if (!font) continue; XftTextExtentsUtf8(xdisplay, font, (guchar *)text, textlen, &extents); pixmap_height += extents.height + 4; pixmap_width = MAX(pixmap_width, 8 + extents.width); XftFontClose(xdisplay, font); } /* create pixmap */ gtk_widget_set_size_request(drawing_area, pixmap_width, pixmap_height); pixmap = gdk_pixmap_new(window, pixmap_width, pixmap_height, -1); if (!pixmap) goto end; cr = gdk_cairo_create (pixmap); cairo_set_source_rgb (cr, 1, 1, 1); cairo_paint (cr); cairo_destroy (cr); xdrawable = GDK_DRAWABLE_XID(pixmap); draw = XftDrawCreate(xdisplay, xdrawable, xvisual, xcolormap); /* draw text */ pos_y = 4; font = get_font(xdisplay, face, alpha_size, charset); draw_string(xdisplay, draw, font, &colour, lowercase_text, &pos_y); draw_string(xdisplay, draw, font, &colour, uppercase_text, &pos_y); draw_string(xdisplay, draw, font, &colour, punctuation_text, &pos_y); XftFontClose(xdisplay, font); pos_y += 8; for (i = 0; i < n_sizes; i++) { font = get_font(xdisplay, face, sizes[i], charset); if (!font) continue; draw_string(xdisplay, draw, font, &colour, text, &pos_y); XftFontClose(xdisplay, font); } g_signal_connect(drawing_area, "expose-event", G_CALLBACK(expose_event), pixmap); end: g_free(sizes); FcCharSetDestroy (charset); return pixmap; }