Home | History | Annotate | Download | only in drm
      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 #define LIBVA_MAJOR_VERSION 1
     32 
     33 typedef struct drm_auth_x11             DRMAuthX11;
     34 typedef struct drm_auth_x11_vtable      DRMAuthX11VTable;
     35 
     36 typedef void (*VAGenericFunc)(void);
     37 typedef Display *(*X11OpenDisplayFunc)(const char *display_name);
     38 typedef int (*X11CloseDisplayFunc)(Display *display);
     39 typedef Bool (*VADRI2QueryExtensionFunc)(
     40     Display *display, int *event_base, int *error_base);
     41 typedef Bool (*VADRI2QueryVersionFunc)(
     42     Display *display, int *major, int *minor);
     43 typedef Bool (*VADRI2AuthenticateFunc)(
     44     Display *display, XID window, uint32_t magic);
     45 
     46 struct drm_auth_x11_vtable {
     47     X11OpenDisplayFunc          x11_open_display;
     48     X11CloseDisplayFunc         x11_close_display;
     49     VADRI2QueryExtensionFunc    va_dri2_query_extension;
     50     VADRI2QueryVersionFunc      va_dri2_query_version;
     51     VADRI2AuthenticateFunc      va_dri2_authenticate;
     52 };
     53 
     54 struct drm_auth_x11 {
     55     void                       *handle; /* libva-x11.so.1 */
     56     DRMAuthX11VTable            vtable;
     57     Display                    *display;
     58     Window                      window;
     59 };
     60 
     61 static bool
     62 get_symbol(void *handle, void *func_vptr, const char *name)
     63 {
     64     VAGenericFunc func, *func_ptr = func_vptr;
     65     const char *error;
     66 
     67     dlerror();
     68     func = (VAGenericFunc)dlsym(handle, name);
     69     error = dlerror();
     70 
     71     if (error) {
     72         fprintf(stderr, "error: failed to resolve %s() function: %s\n",
     73                 name, error);
     74         return false;
     75     }
     76 
     77     *func_ptr = func;
     78     return true;
     79 }
     80 
     81 static bool
     82 drm_auth_x11_init(DRMAuthX11 *auth)
     83 {
     84     struct drm_auth_x11_vtable *vtable;
     85     char libva_x11_name[16];
     86     int ret;
     87 
     88     ret = snprintf(
     89         libva_x11_name, sizeof(libva_x11_name),
     90         "libva-x11.so.%d", LIBVA_MAJOR_VERSION
     91     );
     92     if (ret < 0 || ret >= sizeof(libva_x11_name))
     93         return false;
     94 
     95     auth->handle = dlopen(libva_x11_name, RTLD_LAZY | RTLD_GLOBAL);
     96     if (!auth->handle) {
     97         perror("open lib");
     98         return false;
     99     }
    100 
    101     vtable = &auth->vtable;
    102     if (!get_symbol(RTLD_DEFAULT, &vtable->x11_open_display, "XOpenDisplay"))
    103         return false;
    104     if (!get_symbol(RTLD_DEFAULT, &vtable->x11_close_display, "XCloseDisplay"))
    105         return false;
    106     if (!get_symbol(auth->handle, &vtable->va_dri2_query_extension,
    107                     "VA_DRI2QueryExtension"))
    108         return false;
    109     if (!get_symbol(auth->handle, &vtable->va_dri2_query_version,
    110                     "VA_DRI2QueryVersion"))
    111         return false;
    112     if (!get_symbol(auth->handle, &vtable->va_dri2_authenticate,
    113                     "VA_DRI2Authenticate"))
    114         return false;
    115 
    116     auth->display = vtable->x11_open_display(NULL);
    117     if (!auth->display)
    118         return false;
    119 
    120     auth->window = DefaultRootWindow(auth->display);
    121     return true;
    122 }
    123 
    124 static void
    125 drm_auth_x11_terminate(DRMAuthX11 *auth)
    126 {
    127     if (!auth)
    128         return;
    129 
    130     if (auth->display) {
    131         auth->vtable.x11_close_display(auth->display);
    132         auth->display = NULL;
    133         auth->window  = None;
    134     }
    135 
    136     if (auth->handle) {
    137         dlclose(auth->handle);
    138         auth->handle = NULL;
    139     }
    140 }
    141 
    142 static bool
    143 drm_auth_x11_authenticate(DRMAuthX11 *auth, int fd, uint32_t magic)
    144 {
    145     DRMAuthX11VTable * const vtable = &auth->vtable;
    146     int evt_base, err_base, v_major, v_minor;
    147 
    148     if (!vtable->va_dri2_query_extension(auth->display, &evt_base, &err_base))
    149         return false;
    150     if (!vtable->va_dri2_query_version(auth->display, &v_major, &v_minor))
    151         return false;
    152     if (!vtable->va_dri2_authenticate(auth->display, auth->window, magic))
    153         return false;
    154     return true;
    155 }
    156 
    157 /* Try to authenticate the DRM connection with the supplied magic through X11 */
    158 bool
    159 va_drm_authenticate_x11(int fd, uint32_t magic)
    160 {
    161     DRMAuthX11 auth;
    162     bool success = false;
    163 
    164     memset(&auth, 0, sizeof(auth));
    165     if (!drm_auth_x11_init(&auth))
    166         goto end;
    167     success = drm_auth_x11_authenticate(&auth, fd, magic);
    168 
    169 end:
    170     drm_auth_x11_terminate(&auth);
    171     return success;
    172 }
    173