Edit

IABSD.fr/xenocara/lib/mesa/src/x11/loader_x11.c

Branch :

  • Show log

    Commit

  • Author : jsg
    Date : 2025-06-05 11:23:11
    Hash : 67d6f117
    Message : Import Mesa 25.0.7

  • lib/mesa/src/x11/loader_x11.c
  • /*
     * Copyright © 2013 Keith Packard
     * Copyright © 2015 Boyan Ding
     *
     * Permission to use, copy, modify, distribute, and sell this software and its
     * documentation for any purpose is hereby granted without fee, provided that
     * the above copyright notice appear in all copies and that both that copyright
     * notice and this permission notice appear in supporting documentation, and
     * that the name of the copyright holders not be used in advertising or
     * publicity pertaining to distribution of the software without specific,
     * written prior permission.  The copyright holders make no representations
     * about the suitability of this software for any purpose.  It is provided "as
     * is" without express or implied warranty.
     *
     * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
     * OF THIS SOFTWARE.
     */
    
    #include <stdbool.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <xcb/xcb.h>
    #include <xcb/dri3.h>
    #include <xcb/present.h>
    #include <xcb/xfixes.h>
    #include "loader_x11.h"
    /** x11_dri3_open
     *
     * Wrapper around xcb_dri3_open
     */
    int
    x11_dri3_open(xcb_connection_t *conn,
                     xcb_window_t root,
                     uint32_t provider)
    {
       xcb_dri3_open_cookie_t       cookie;
       xcb_dri3_open_reply_t        *reply;
       xcb_xfixes_query_version_cookie_t fixes_cookie;
       xcb_xfixes_query_version_reply_t *fixes_reply;
       int                          fd;
       const xcb_query_extension_reply_t *extension;
    
       xcb_prefetch_extension_data(conn, &xcb_dri3_id);
       extension = xcb_get_extension_data(conn, &xcb_dri3_id);
       if (!(extension && extension->present))
          return -1;
    
       cookie = xcb_dri3_open(conn,
                              root,
                              provider);
    
       reply = xcb_dri3_open_reply(conn, cookie, NULL);
    
       if (!reply || reply->nfd != 1) {
          free(reply);
          return -1;
       }
    
       fd = xcb_dri3_open_reply_fds(conn, reply)[0];
       free(reply);
       fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
    
       /* let the server know our xfixes level */
       fixes_cookie = xcb_xfixes_query_version(conn,
                                               XCB_XFIXES_MAJOR_VERSION,
                                               XCB_XFIXES_MINOR_VERSION);
       fixes_reply = xcb_xfixes_query_version_reply(conn, fixes_cookie, NULL);
       if (fixes_reply->major_version < 2) {
          close(fd);
          fd = -1;
       }
       free(fixes_reply);
    
       return fd;
    }
    
    /* Only request versions of these protocols which we actually support. */
    #define DRI3_SUPPORTED_MAJOR 1
    #define PRESENT_SUPPORTED_MAJOR 1
    
    #ifdef HAVE_X11_DRM
    #define DRI3_SUPPORTED_MINOR 2
    #define PRESENT_SUPPORTED_MINOR 2
    #else
    #define PRESENT_SUPPORTED_MINOR 0
    #define DRI3_SUPPORTED_MINOR 0
    #endif
    
    bool
    x11_dri3_check_multibuffer(xcb_connection_t *c, bool *err, bool *explicit_modifiers)
    {
       xcb_dri3_query_version_cookie_t      dri3_cookie;
       xcb_dri3_query_version_reply_t       *dri3_reply;
       xcb_present_query_version_cookie_t   present_cookie;
       xcb_present_query_version_reply_t    *present_reply;
       xcb_generic_error_t                  *error;
       const xcb_query_extension_reply_t    *extension;
    
       xcb_prefetch_extension_data(c, &xcb_dri3_id);
       xcb_prefetch_extension_data(c, &xcb_present_id);
    
       extension = xcb_get_extension_data(c, &xcb_dri3_id);
       if (!(extension && extension->present))
          goto error;
    
       extension = xcb_get_extension_data(c, &xcb_present_id);
       if (!(extension && extension->present))
          goto error;
    
       dri3_cookie = xcb_dri3_query_version(c,
                                            DRI3_SUPPORTED_MAJOR,
                                            DRI3_SUPPORTED_MINOR);
       present_cookie = xcb_present_query_version(c,
                                                  PRESENT_SUPPORTED_MAJOR,
                                                  PRESENT_SUPPORTED_MINOR);
    
       dri3_reply = xcb_dri3_query_version_reply(c, dri3_cookie, &error);
       if (!dri3_reply) {
          free(error);
          goto error;
       }
    
       int dri3Major = dri3_reply->major_version;
       int dri3Minor = dri3_reply->minor_version;
       free(dri3_reply);
    
       present_reply = xcb_present_query_version_reply(c, present_cookie, &error);
       if (!present_reply) {
          free(error);
          goto error;
       }
       int presentMajor = present_reply->major_version;
       int presentMinor = present_reply->minor_version;
       free(present_reply);
    
    #ifdef HAVE_X11_DRM
       if (presentMajor > 1 || (presentMajor == 1 && presentMinor >= 2)) {
          *explicit_modifiers = dri3Major > 1 || (dri3Major == 1 && dri3Minor >= 2);
          if (dri3Major >= 1)
             return true;
       }
    #endif
       return false;
    error:
       *err = true;
       return false;
    }