Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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.