Exemple #1
0
/*****************************************************************************
 * IDirectDrawClipper::GetClipList
 *
 * Retrieve a copy of the clip list
 *
 * Arguments:
 *  rect: Rectangle to be used to clip the clip list or NULL for the
 *      entire clip list.
 *  clip_list: structure for the resulting copy of the clip list.
 *      If NULL, fills Size up to the number of bytes necessary to hold
 *      the entire clip.
 *  clip_list_size: Size of resulting clip list; size of the buffer at clip_list
 *      or, if clip_list is NULL, receives the required size of the buffer
 *      in bytes.
 *
 * RETURNS
 *  Either DD_OK or DDERR_*
 ************************************************************************/
static HRESULT WINAPI ddraw_clipper_GetClipList(IDirectDrawClipper *iface, RECT *rect,
        RGNDATA *clip_list, DWORD *clip_list_size)
{
    struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
    HRGN region;

    TRACE("iface %p, rect %s, clip_list %p, clip_list_size %p.\n",
            iface, wine_dbgstr_rect(rect), clip_list, clip_list_size);

    wined3d_mutex_lock();

    if (clipper->window)
    {
        if (!(region = get_window_region(clipper->window)))
        {
            wined3d_mutex_unlock();
            WARN("Failed to get window region.\n");
            return E_FAIL;
        }
    }
    else
    {
        if (!(region = clipper->region))
        {
            wined3d_mutex_unlock();
            WARN("No clip list set.\n");
            return DDERR_NOCLIPLIST;
        }
    }

    if (rect)
    {
        HRGN clip_region;

        if (!(clip_region = CreateRectRgnIndirect(rect)))
        {
            wined3d_mutex_unlock();
            ERR("Failed to create region.\n");
            if (clipper->window)
                DeleteObject(region);
            return E_FAIL;
        }

        if (CombineRgn(clip_region, region, clip_region, RGN_AND) == ERROR)
        {
            wined3d_mutex_unlock();
            ERR("Failed to combine regions.\n");
            DeleteObject(clip_region);
            if (clipper->window)
                DeleteObject(region);
            return E_FAIL;
        }

        if (clipper->window)
            DeleteObject(region);
        region = clip_region;
    }

    *clip_list_size = GetRegionData(region, *clip_list_size, clip_list);
    if (rect || clipper->window)
        DeleteObject(region);

    wined3d_mutex_unlock();
    return DD_OK;
}
CoglOnscreen* ImGui_ImplGtk3Cogl_Init(GtkWidget* widget,
                                      void (*callback)(CoglOnscreen *onscreen, void *data),
                                      void *data)
{
    g_clear_pointer(&g_GtkWidget, g_object_unref);
    g_clear_pointer(&g_GdkWindow, g_object_unref);
    g_clear_pointer(&g_Framebuffer, cogl_object_unref);
    g_clear_pointer(&g_Context, cogl_object_unref);

    g_GtkWidget = GTK_WIDGET(g_object_ref(widget));
    gtk_widget_realize(widget);
    GdkWindow *parent_window = gtk_widget_get_window(widget);

    GtkAllocation allocation;
    gtk_widget_get_allocation(widget, &allocation);

    g_Callbacks = get_backend_callbacks(parent_window);

    GdkWindowAttr attributes;
    memset(&attributes, 0, sizeof(attributes));
    attributes.x = 0;
    attributes.y = 0;
    attributes.width = allocation.width;
    attributes.height = allocation.height;
    attributes.wclass = GDK_INPUT_OUTPUT;
    attributes.window_type = g_Callbacks->winsys == COGL_WINSYS_ID_EGL_WAYLAND ?
        GDK_WINDOW_SUBSURFACE : GDK_WINDOW_CHILD;

    GdkDisplay *display = gdk_window_get_display(parent_window);
    attributes.visual = gtk_widget_get_visual(widget);

    g_GdkWindow = gdk_window_new(parent_window, &attributes,
                                 GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL);
    gdk_window_set_transient_for(g_GdkWindow, parent_window);
    gdk_window_set_pass_through(g_GdkWindow, TRUE);

    cairo_rectangle_int_t empty_rect;
    memset(&empty_rect, 0, sizeof(empty_rect));
    cairo_region_t *input_region = cairo_region_create_rectangle(&empty_rect);
    gdk_window_input_shape_combine_region(g_GdkWindow, input_region, 0, 0);
    cairo_region_destroy(input_region);

    cairo_region_t *region = get_window_region(g_GdkWindow);
    gdk_window_set_opaque_region(g_GdkWindow, region);
    cairo_region_destroy(region);

    CoglRenderer *renderer = cogl_renderer_new();
    cogl_renderer_set_winsys_id(renderer, g_Callbacks->winsys);
    g_Callbacks->init(renderer, display, g_GdkWindow);

    gdk_window_ensure_native(g_GdkWindow);

    g_Context = cogl_context_new(cogl_display_new(renderer, NULL), NULL);
    CoglOnscreen *onscreen = cogl_onscreen_new(g_Context, 1, 1);
    cogl_object_unref(renderer);

    g_Callbacks->resize(g_GdkWindow, onscreen,
                        allocation.width, allocation.height,
                        allocation.x, allocation.y);

    gtk_widget_add_events(widget, EVENT_MASK);
    g_signal_connect(widget, "event", G_CALLBACK(handle_gdk_event), NULL);
    g_signal_connect(widget, "size-allocate", G_CALLBACK(handle_allocate), NULL);

    g_Callbacks->set_window(onscreen, g_GdkWindow);

    if (!cogl_framebuffer_allocate(COGL_FRAMEBUFFER(onscreen), NULL))
        g_warning("Unable to allocate framebuffer");

    g_Framebuffer = COGL_FRAMEBUFFER(onscreen);

    ImGuiIO& io = ImGui::GetIO();
    for (int i = 0; i < ImGuiKey_COUNT; i++)
    {
        io.KeyMap[i] = i;
    }

    io.SetClipboardTextFn = ImGui_ImplGtk3Cogl_SetClipboardText;
    io.GetClipboardTextFn = ImGui_ImplGtk3Cogl_GetClipboardText;
    io.ClipboardUserData = gtk_widget_get_clipboard(g_GtkWidget,
                                                    GDK_SELECTION_CLIPBOARD);

    g_Callback = callback;
    g_CallbackData = data;
    GdkFrameClock *clock = gdk_window_get_frame_clock(g_GdkWindow);
    g_signal_connect(clock, "paint", G_CALLBACK(handle_repaint), NULL);

    gdk_frame_clock_request_phase(clock, GDK_FRAME_CLOCK_PHASE_PAINT);

    gdk_window_show(g_GdkWindow);

    return COGL_ONSCREEN(g_Framebuffer);
}