xref: /aosp_15_r20/external/libva/va/drm/va_drm_auth_x11.c (revision 54e60f844a168e9a219354de272cd517ee8cd4b7)
1 /*
2  * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sub license, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 #define _GNU_SOURCE 1
26 #include "sysdeps.h"
27 #include <dlfcn.h>
28 #include <X11/Xlib.h>
29 #include "va_drm_auth_x11.h"
30 
31 typedef struct drm_auth_x11             DRMAuthX11;
32 typedef struct drm_auth_x11_vtable      DRMAuthX11VTable;
33 
34 typedef void (*VAGenericFunc)(void);
35 typedef Display *(*X11OpenDisplayFunc)(const char *display_name);
36 typedef int (*X11CloseDisplayFunc)(Display *display);
37 typedef Bool(*VADRI2AuthenticateFunc)(
38     Display *display, XID window, uint32_t magic);
39 
40 struct drm_auth_x11_vtable {
41     X11OpenDisplayFunc          x11_open_display;
42     X11CloseDisplayFunc         x11_close_display;
43     VADRI2AuthenticateFunc      va_dri2_authenticate;
44 };
45 
46 struct drm_auth_x11 {
47     void                       *handle; /* libva-x11.so.1 */
48     DRMAuthX11VTable            vtable;
49     Display                    *display;
50     Window                      window;
51 };
52 
53 static bool
get_symbol(void * handle,void * func_vptr,const char * name)54 get_symbol(void *handle, void *func_vptr, const char *name)
55 {
56     VAGenericFunc func, *func_ptr = func_vptr;
57     const char *error;
58 
59     dlerror();
60     func = (VAGenericFunc)dlsym(handle, name);
61     error = dlerror();
62 
63     if (error) {
64         fprintf(stderr, "error: failed to resolve %s() function: %s\n",
65                 name, error);
66         return false;
67     }
68 
69     *func_ptr = func;
70     return true;
71 }
72 
73 static bool
drm_auth_x11_init(DRMAuthX11 * auth)74 drm_auth_x11_init(DRMAuthX11 *auth)
75 {
76     struct drm_auth_x11_vtable *vtable;
77     char libva_x11_name[16];
78     int ret;
79 
80     ret = snprintf(
81               libva_x11_name, sizeof(libva_x11_name),
82               "libva-x11.so.%d", LIBVA_MAJOR_VERSION
83           );
84     if (ret < 0 || ret >= sizeof(libva_x11_name))
85         return false;
86 
87     auth->handle = dlopen(libva_x11_name, RTLD_LAZY | RTLD_GLOBAL);
88     if (!auth->handle) {
89         perror("open lib");
90         return false;
91     }
92 
93     vtable = &auth->vtable;
94     if (!get_symbol(RTLD_DEFAULT, &vtable->x11_open_display, "XOpenDisplay"))
95         return false;
96     if (!get_symbol(RTLD_DEFAULT, &vtable->x11_close_display, "XCloseDisplay"))
97         return false;
98     if (!get_symbol(auth->handle, &vtable->va_dri2_authenticate,
99                     "VA_DRI2Authenticate"))
100         return false;
101 
102     auth->display = vtable->x11_open_display(NULL);
103     if (!auth->display)
104         return false;
105 
106     auth->window = DefaultRootWindow(auth->display);
107     return true;
108 }
109 
110 static void
drm_auth_x11_terminate(DRMAuthX11 * auth)111 drm_auth_x11_terminate(DRMAuthX11 *auth)
112 {
113     if (!auth)
114         return;
115 
116     if (auth->display) {
117         auth->vtable.x11_close_display(auth->display);
118         auth->display = NULL;
119         auth->window  = None;
120     }
121 
122     if (auth->handle) {
123         dlclose(auth->handle);
124         auth->handle = NULL;
125     }
126 }
127 
128 /* Try to authenticate the DRM connection with the supplied magic through X11 */
129 bool
va_drm_authenticate_x11(int fd,uint32_t magic)130 va_drm_authenticate_x11(int fd, uint32_t magic)
131 {
132     DRMAuthX11VTable * vtable;
133     DRMAuthX11 auth;
134     bool success = false;
135 
136     memset(&auth, 0, sizeof(auth));
137     if (!drm_auth_x11_init(&auth))
138         goto end;
139     vtable = &auth.vtable;
140     success = vtable->va_dri2_authenticate(auth.display, auth.window, magic);
141 
142 end:
143     drm_auth_x11_terminate(&auth);
144     return success;
145 }
146