You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现从Visual*到GdkVisual*的转换?已掌握反向转换API

Converting X11 Visual* to GdkVisual*

确实,GTK+ doesn't offer a direct reverse API for gdk_x11_visual_get_xvisual(), but there are a couple of reliable workarounds to get this done:

Method 1: Iterate through all available GdkVisuals and match the X11 Visual*

This is the most straightforward approach—enumerate all GdkVisual instances for your display/screen, extract their corresponding X11 Visual* using gdk_x11_visual_get_xvisual(), and compare to find a match with your target Visual*.

Example code:

GdkVisual* x11_visual_to_gdk_visual(Visual* x11_visual) {
    if (!x11_visual) return NULL;

    GdkDisplay* display = gdk_display_get_default();
    GdkScreen* screen = gdk_display_get_default_screen(display);
    GList* visuals = gdk_screen_list_visuals(screen);
    GdkVisual* matched_visual = NULL;

    for (GList* l = visuals; l != NULL; l = l->next) {
        GdkVisual* current = GDK_VISUAL(l->data);
        Visual* current_x11_visual = gdk_x11_visual_get_xvisual(current);

        if (current_x11_visual == x11_visual) {
            matched_visual = current;
            g_object_ref(matched_visual); // Add reference to avoid accidental destruction later
            break;
        }
    }

    g_list_free(visuals);
    return matched_visual;
}

Key Notes:

  • Always call g_object_ref() on the matched GdkVisual—the list returned by gdk_screen_list_visuals() doesn't add extra references, so you need to hold your own if you plan to keep the object long-term.
  • If no match is found, it means the X11 Visual* isn't supported by the current GDK screen. Make sure to handle the NULL return case in your code.

Method 2: Narrow down candidates using visual properties first

If you know the depth or visual class (like TrueColor, PseudoColor) of your target Visual*, you can filter candidates before comparing pointers to speed things up:

GdkVisual* x11_visual_to_gdk_visual_by_properties(Visual* x11_visual) {
    if (!x11_visual) return NULL;

    GdkDisplay* display = gdk_display_get_default();
    GdkScreen* screen = gdk_display_get_default_screen(display);
    int depth = x11_visual->depth;
    GdkVisualType visual_type = GDK_VISUAL_INVALID;

    // Map X11 visual class to GdkVisualType
    switch (x11_visual->class) {
        case StaticGray:
            visual_type = GDK_STATIC_GRAY;
            break;
        case GrayScale:
            visual_type = GDK_GRAYSCALE;
            break;
        case StaticColor:
            visual_type = GDK_STATIC_COLOR;
            break;
        case PseudoColor:
            visual_type = GDK_PSEUDO_COLOR;
            break;
        case TrueColor:
            visual_type = GDK_TRUE_COLOR;
            break;
        case DirectColor:
            visual_type = GDK_DIRECT_COLOR;
            break;
        default:
            visual_type = GDK_VISUAL_INVALID;
            break;
    }

    // Check if a matching type exists first
    GdkVisual* candidate = gdk_screen_get_visual_by_type(screen, visual_type);
    if (candidate) {
        Visual* candidate_x11 = gdk_x11_visual_get_xvisual(candidate);
        if (candidate_x11 == x11_visual) {
            g_object_ref(candidate);
            return candidate;
        }
    }

    // Fall back to full iteration if type-based lookup fails
    return x11_visual_to_gdk_visual(x11_visual);
}

This reduces the number of comparisons needed in most cases, but you still need to verify the pointer match—multiple visuals can share the same type and depth.

Extra Tips

  • For multi-screen setups, don't rely solely on the default screen. Use XVisualIDFromVisual() to get the visual ID, then match it against the X screen ID from gdk_x11_screen_get_xscreen() to find the correct GdkScreen.
  • Remember to call g_object_unref() on the GdkVisual* when you're done with it to avoid memory leaks.

内容的提问来源于stack exchange,提问作者Naseeb Panghal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:00:06