146 lines
4.2 KiB
C
146 lines
4.2 KiB
C
|
/*
|
||
|
* Copyright (c) 2012 Intel Corporation. All Rights Reserved.
|
||
|
*
|
||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||
|
* copy of this software and associated documentation files (the
|
||
|
* "Software"), to deal in the Software without restriction, including
|
||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||
|
* the following conditions:
|
||
|
*
|
||
|
* The above copyright notice and this permission notice (including the
|
||
|
* next paragraph) shall be included in all copies or substantial portions
|
||
|
* of the Software.
|
||
|
*
|
||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||
|
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
*/
|
||
|
|
||
|
#define _GNU_SOURCE 1
|
||
|
#include "sysdeps.h"
|
||
|
#include <dlfcn.h>
|
||
|
#include <X11/Xlib.h>
|
||
|
#include "va_drm_auth_x11.h"
|
||
|
|
||
|
typedef struct drm_auth_x11 DRMAuthX11;
|
||
|
typedef struct drm_auth_x11_vtable DRMAuthX11VTable;
|
||
|
|
||
|
typedef void (*VAGenericFunc)(void);
|
||
|
typedef Display *(*X11OpenDisplayFunc)(const char *display_name);
|
||
|
typedef int (*X11CloseDisplayFunc)(Display *display);
|
||
|
typedef Bool(*VADRI2AuthenticateFunc)(
|
||
|
Display *display, XID window, uint32_t magic);
|
||
|
|
||
|
struct drm_auth_x11_vtable {
|
||
|
X11OpenDisplayFunc x11_open_display;
|
||
|
X11CloseDisplayFunc x11_close_display;
|
||
|
VADRI2AuthenticateFunc va_dri2_authenticate;
|
||
|
};
|
||
|
|
||
|
struct drm_auth_x11 {
|
||
|
void *handle; /* libva-x11.so.1 */
|
||
|
DRMAuthX11VTable vtable;
|
||
|
Display *display;
|
||
|
Window window;
|
||
|
};
|
||
|
|
||
|
static bool
|
||
|
get_symbol(void *handle, void *func_vptr, const char *name)
|
||
|
{
|
||
|
VAGenericFunc func, *func_ptr = func_vptr;
|
||
|
const char *error;
|
||
|
|
||
|
dlerror();
|
||
|
func = (VAGenericFunc)dlsym(handle, name);
|
||
|
error = dlerror();
|
||
|
|
||
|
if (error) {
|
||
|
fprintf(stderr, "error: failed to resolve %s() function: %s\n",
|
||
|
name, error);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
*func_ptr = func;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
static bool
|
||
|
drm_auth_x11_init(DRMAuthX11 *auth)
|
||
|
{
|
||
|
struct drm_auth_x11_vtable *vtable;
|
||
|
char libva_x11_name[16];
|
||
|
int ret;
|
||
|
|
||
|
ret = snprintf(
|
||
|
libva_x11_name, sizeof(libva_x11_name),
|
||
|
"libva-x11.so.%d", LIBVA_MAJOR_VERSION
|
||
|
);
|
||
|
if (ret < 0 || ret >= sizeof(libva_x11_name))
|
||
|
return false;
|
||
|
|
||
|
auth->handle = dlopen(libva_x11_name, RTLD_LAZY | RTLD_GLOBAL);
|
||
|
if (!auth->handle) {
|
||
|
perror("open lib");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
vtable = &auth->vtable;
|
||
|
if (!get_symbol(RTLD_DEFAULT, &vtable->x11_open_display, "XOpenDisplay"))
|
||
|
return false;
|
||
|
if (!get_symbol(RTLD_DEFAULT, &vtable->x11_close_display, "XCloseDisplay"))
|
||
|
return false;
|
||
|
if (!get_symbol(auth->handle, &vtable->va_dri2_authenticate,
|
||
|
"VA_DRI2Authenticate"))
|
||
|
return false;
|
||
|
|
||
|
auth->display = vtable->x11_open_display(NULL);
|
||
|
if (!auth->display)
|
||
|
return false;
|
||
|
|
||
|
auth->window = DefaultRootWindow(auth->display);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
drm_auth_x11_terminate(DRMAuthX11 *auth)
|
||
|
{
|
||
|
if (!auth)
|
||
|
return;
|
||
|
|
||
|
if (auth->display) {
|
||
|
auth->vtable.x11_close_display(auth->display);
|
||
|
auth->display = NULL;
|
||
|
auth->window = None;
|
||
|
}
|
||
|
|
||
|
if (auth->handle) {
|
||
|
dlclose(auth->handle);
|
||
|
auth->handle = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Try to authenticate the DRM connection with the supplied magic through X11 */
|
||
|
bool
|
||
|
va_drm_authenticate_x11(int fd, uint32_t magic)
|
||
|
{
|
||
|
DRMAuthX11VTable * vtable;
|
||
|
DRMAuthX11 auth;
|
||
|
bool success = false;
|
||
|
|
||
|
memset(&auth, 0, sizeof(auth));
|
||
|
if (!drm_auth_x11_init(&auth))
|
||
|
goto end;
|
||
|
vtable = &auth.vtable;
|
||
|
success = vtable->va_dri2_authenticate(auth.display, auth.window, magic);
|
||
|
|
||
|
end:
|
||
|
drm_auth_x11_terminate(&auth);
|
||
|
return success;
|
||
|
}
|