|
Packit Service |
f6fdc3 |
/*
|
|
Packit Service |
f6fdc3 |
* Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved.
|
|
Packit Service |
f6fdc3 |
*
|
|
Packit Service |
f6fdc3 |
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
Packit Service |
f6fdc3 |
* copy of this software and associated documentation files (the "Software"),
|
|
Packit Service |
f6fdc3 |
* to deal in the Software without restriction, including without limitation
|
|
Packit Service |
f6fdc3 |
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
Packit Service |
f6fdc3 |
* and/or sell copies of the Software, and to permit persons to whom the
|
|
Packit Service |
f6fdc3 |
* Software is furnished to do so, subject to the following conditions:
|
|
Packit Service |
f6fdc3 |
*
|
|
Packit Service |
f6fdc3 |
* The above copyright notice and this permission notice shall be included in
|
|
Packit Service |
f6fdc3 |
* all copies or substantial portions of the Software.
|
|
Packit Service |
f6fdc3 |
*
|
|
Packit Service |
f6fdc3 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
Packit Service |
f6fdc3 |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
Packit Service |
f6fdc3 |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
Packit Service |
f6fdc3 |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
Packit Service |
f6fdc3 |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
Packit Service |
f6fdc3 |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
Packit Service |
f6fdc3 |
* DEALINGS IN THE SOFTWARE.
|
|
Packit Service |
f6fdc3 |
*/
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
#include <stdio.h>
|
|
Packit Service |
f6fdc3 |
#include <stdlib.h>
|
|
Packit Service |
f6fdc3 |
#include <string.h>
|
|
Packit Service |
f6fdc3 |
#include <stddef.h>
|
|
Packit Service |
f6fdc3 |
#include <unistd.h>
|
|
Packit Service |
f6fdc3 |
#include <assert.h>
|
|
Packit Service |
f6fdc3 |
#include <sys/socket.h>
|
|
Packit Service |
f6fdc3 |
#include <sys/types.h>
|
|
Packit Service |
f6fdc3 |
#include <netinet/in.h>
|
|
Packit Service |
f6fdc3 |
#include <netdb.h>
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
#include <wayland-server.h>
|
|
Packit Service |
f6fdc3 |
#include <EGL/egl.h>
|
|
Packit Service |
f6fdc3 |
#include <EGL/eglext.h>
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
#include "wayland-eglstream-server.h"
|
|
Packit Service |
f6fdc3 |
#include "wayland-eglstream-server-protocol.h"
|
|
Packit Service |
f6fdc3 |
#include "wayland-eglstream.h"
|
|
Packit Service |
f6fdc3 |
#include "wayland-eglswap.h"
|
|
Packit Service |
f6fdc3 |
#include "wayland-eglutils.h"
|
|
Packit Service |
68ab9c |
#include "wayland-thread.h"
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
#define MASK(_VAL_) (1 << (_VAL_))
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
static struct wl_list wlStreamDpyList = WL_LIST_INIT(&wlStreamDpyList);
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
static void
|
|
Packit Service |
f6fdc3 |
destroy_wl_eglstream_resource(struct wl_resource *resource)
|
|
Packit Service |
f6fdc3 |
{
|
|
Packit Service |
f6fdc3 |
struct wl_eglstream *wlStream = wl_resource_get_user_data(resource);
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
if (wlStream->handle >= 0) {
|
|
Packit Service |
f6fdc3 |
close(wlStream->handle);
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
free(wlStream);
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
static void
|
|
Packit Service |
f6fdc3 |
destroy_wl_eglstream(struct wl_client *client, struct wl_resource *resource)
|
|
Packit Service |
f6fdc3 |
{
|
|
Packit Service |
f6fdc3 |
(void) client;
|
|
Packit Service |
f6fdc3 |
wl_resource_destroy(resource);
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
static void
|
|
Packit Service |
f6fdc3 |
handle_create_stream(struct wl_client *client,
|
|
Packit Service |
f6fdc3 |
struct wl_resource *resource, uint32_t id,
|
|
Packit Service |
f6fdc3 |
int32_t width, int32_t height,
|
|
Packit Service |
f6fdc3 |
int handle, int handle_type,
|
|
Packit Service |
f6fdc3 |
struct wl_array *attribs)
|
|
Packit Service |
f6fdc3 |
{
|
|
Packit Service |
f6fdc3 |
struct wl_eglstream_display *wlStreamDpy =
|
|
Packit Service |
f6fdc3 |
wl_resource_get_user_data(resource);
|
|
Packit Service |
f6fdc3 |
struct wl_eglstream *wlStream;
|
|
Packit Service |
f6fdc3 |
struct sockaddr_in sockAddr;
|
|
Packit Service |
f6fdc3 |
char sockAddrStr[NI_MAXHOST];
|
|
Packit Service |
f6fdc3 |
intptr_t *attr;
|
|
Packit Service |
f6fdc3 |
int mask = 0;
|
|
Packit Service |
f6fdc3 |
enum wl_eglstream_error err;
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
wlStream = calloc(1, sizeof *wlStream);
|
|
Packit Service |
f6fdc3 |
if (wlStream == NULL) {
|
|
Packit Service |
f6fdc3 |
err = WL_EGLSTREAM_ERROR_BAD_ALLOC;
|
|
Packit Service |
f6fdc3 |
goto error_create_stream;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
wlStream->wlStreamDpy = wlStreamDpy;
|
|
Packit Service |
f6fdc3 |
wlStream->eglStream = EGL_NO_STREAM_KHR;
|
|
Packit Service |
f6fdc3 |
wlStream->width = width;
|
|
Packit Service |
f6fdc3 |
wlStream->height = height;
|
|
Packit Service |
f6fdc3 |
wlStream->handle = -1;
|
|
Packit Service |
f6fdc3 |
wlStream->yInverted = EGL_FALSE;
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
memset(&sockAddr, 0, sizeof(sockAddr));
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
switch (handle_type) {
|
|
Packit Service |
f6fdc3 |
case WL_EGLSTREAM_HANDLE_TYPE_FD:
|
|
Packit Service |
f6fdc3 |
wlStream->handle = handle;
|
|
Packit Service |
f6fdc3 |
wlStream->fromFd = EGL_TRUE;
|
|
Packit Service |
f6fdc3 |
break;
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
case WL_EGLSTREAM_HANDLE_TYPE_INET:
|
|
Packit Service |
f6fdc3 |
sockAddr.sin_family = AF_INET;
|
|
Packit Service |
f6fdc3 |
wlStream->isInet = EGL_TRUE;
|
|
Packit Service |
f6fdc3 |
/* Close the given dummy fd */
|
|
Packit Service |
f6fdc3 |
close(handle);
|
|
Packit Service |
f6fdc3 |
break;
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
case WL_EGLSTREAM_HANDLE_TYPE_SOCKET:
|
|
Packit Service |
f6fdc3 |
wlStream->handle = handle;
|
|
Packit Service |
f6fdc3 |
break;
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
default:
|
|
Packit Service |
f6fdc3 |
err = WL_EGLSTREAM_ERROR_BAD_HANDLE;
|
|
Packit Service |
f6fdc3 |
goto error_create_stream;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
wl_array_for_each(attr, attribs) {
|
|
Packit Service |
f6fdc3 |
switch (attr[0]) {
|
|
Packit Service |
f6fdc3 |
case WL_EGLSTREAM_ATTRIB_INET_ADDR:
|
|
Packit Service |
f6fdc3 |
/* INET_ADDR should only be set once */
|
|
Packit Service |
f6fdc3 |
if (mask & MASK(WL_EGLSTREAM_ATTRIB_INET_ADDR)) {
|
|
Packit Service |
f6fdc3 |
err = WL_EGLSTREAM_ERROR_BAD_ATTRIBS;
|
|
Packit Service |
f6fdc3 |
goto error_create_stream;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
sockAddr.sin_addr.s_addr = htonl((int)attr[1]);
|
|
Packit Service |
f6fdc3 |
mask |= MASK(WL_EGLSTREAM_ATTRIB_INET_ADDR);
|
|
Packit Service |
f6fdc3 |
break;
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
case WL_EGLSTREAM_ATTRIB_INET_PORT:
|
|
Packit Service |
f6fdc3 |
/* INET_PORT should only be set once */
|
|
Packit Service |
f6fdc3 |
if (mask & MASK(WL_EGLSTREAM_ATTRIB_INET_PORT)) {
|
|
Packit Service |
f6fdc3 |
err = WL_EGLSTREAM_ERROR_BAD_ATTRIBS;
|
|
Packit Service |
f6fdc3 |
goto error_create_stream;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
sockAddr.sin_port = htons((int)attr[1]);
|
|
Packit Service |
f6fdc3 |
mask |= MASK(WL_EGLSTREAM_ATTRIB_INET_PORT);
|
|
Packit Service |
f6fdc3 |
break;
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
case WL_EGLSTREAM_ATTRIB_Y_INVERTED:
|
|
Packit Service |
f6fdc3 |
/* Y_INVERTED should only be set once */
|
|
Packit Service |
f6fdc3 |
if (mask & MASK(WL_EGLSTREAM_ATTRIB_Y_INVERTED)) {
|
|
Packit Service |
f6fdc3 |
err = WL_EGLSTREAM_ERROR_BAD_ATTRIBS;
|
|
Packit Service |
f6fdc3 |
goto error_create_stream;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
wlStream->yInverted = (EGLBoolean)attr[1];
|
|
Packit Service |
f6fdc3 |
mask |= MASK(WL_EGLSTREAM_ATTRIB_Y_INVERTED);
|
|
Packit Service |
f6fdc3 |
break;
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
default:
|
|
Packit Service |
f6fdc3 |
assert(!"Unknown attribute");
|
|
Packit Service |
f6fdc3 |
break;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
/* Attribs processed in pairs */
|
|
Packit Service |
f6fdc3 |
attr++;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
if (wlStream->isInet) {
|
|
Packit Service |
f6fdc3 |
/* Both address and port should have been set */
|
|
Packit Service |
f6fdc3 |
if (mask != (MASK(WL_EGLSTREAM_ATTRIB_INET_ADDR) |
|
|
Packit Service |
f6fdc3 |
MASK(WL_EGLSTREAM_ATTRIB_INET_PORT))) {
|
|
Packit Service |
f6fdc3 |
err = WL_EGLSTREAM_ERROR_BAD_ATTRIBS;
|
|
Packit Service |
f6fdc3 |
goto error_create_stream;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
wlStream->handle = socket(AF_INET, SOCK_STREAM, 0);
|
|
Packit Service |
f6fdc3 |
if (wlStream->handle == -1) {
|
|
Packit Service |
f6fdc3 |
err = WL_EGLSTREAM_ERROR_BAD_ALLOC;
|
|
Packit Service |
f6fdc3 |
goto error_create_stream;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
if (connect(wlStream->handle,
|
|
Packit Service |
f6fdc3 |
(struct sockaddr *)&sockAddr,
|
|
Packit Service |
f6fdc3 |
sizeof(sockAddr)) < 0) {
|
|
Packit Service |
f6fdc3 |
err = WL_EGLSTREAM_ERROR_BAD_ADDRESS;
|
|
Packit Service |
f6fdc3 |
goto error_create_stream;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
wlStream->resource =
|
|
Packit Service |
f6fdc3 |
wl_resource_create(client, &wl_buffer_interface, 1, id);
|
|
Packit Service |
f6fdc3 |
if (!wlStream->resource) {
|
|
Packit Service |
f6fdc3 |
err = WL_EGLSTREAM_ERROR_BAD_ALLOC;
|
|
Packit Service |
f6fdc3 |
goto error_create_stream;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
wl_resource_set_implementation(
|
|
Packit Service |
f6fdc3 |
wlStream->resource,
|
|
Packit Service |
f6fdc3 |
(void (**)(void))&wlStreamDpy->wl_eglstream_interface,
|
|
Packit Service |
f6fdc3 |
wlStream,
|
|
Packit Service |
f6fdc3 |
destroy_wl_eglstream_resource);
|
|
Packit Service |
f6fdc3 |
return;
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
error_create_stream:
|
|
Packit Service |
f6fdc3 |
switch (err) {
|
|
Packit Service |
f6fdc3 |
case WL_EGLSTREAM_ERROR_BAD_ALLOC:
|
|
Packit Service |
f6fdc3 |
wl_resource_post_no_memory(resource);
|
|
Packit Service |
f6fdc3 |
break;
|
|
Packit Service |
f6fdc3 |
case WL_EGLSTREAM_ERROR_BAD_HANDLE:
|
|
Packit Service |
f6fdc3 |
wl_resource_post_error(resource, err, "Invalid or unknown handle");
|
|
Packit Service |
f6fdc3 |
break;
|
|
Packit Service |
f6fdc3 |
case WL_EGLSTREAM_ERROR_BAD_ATTRIBS:
|
|
Packit Service |
f6fdc3 |
wl_resource_post_error(resource, err, "Malformed attributes list");
|
|
Packit Service |
f6fdc3 |
break;
|
|
Packit Service |
f6fdc3 |
case WL_EGLSTREAM_ERROR_BAD_ADDRESS:
|
|
Packit Service |
f6fdc3 |
wl_resource_post_error(resource, err, "Unable to connect to %s:%d.",
|
|
Packit Service |
f6fdc3 |
(getnameinfo((struct sockaddr *)&sockAddr,
|
|
Packit Service |
f6fdc3 |
sizeof(sockAddr),
|
|
Packit Service |
f6fdc3 |
sockAddrStr, NI_MAXHOST,
|
|
Packit Service |
f6fdc3 |
NULL, 0,
|
|
Packit Service |
f6fdc3 |
NI_NUMERICHOST) ?
|
|
Packit Service |
f6fdc3 |
"<invalid IP>" : sockAddrStr),
|
|
Packit Service |
f6fdc3 |
ntohs(sockAddr.sin_port));
|
|
Packit Service |
f6fdc3 |
break;
|
|
Packit Service |
f6fdc3 |
default:
|
|
Packit Service |
f6fdc3 |
assert(!"Unknown error code");
|
|
Packit Service |
f6fdc3 |
break;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
if (wlStream) {
|
|
Packit Service |
f6fdc3 |
if (wlStream->isInet && wlStream->handle >= 0) {
|
|
Packit Service |
f6fdc3 |
close(wlStream->handle);
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
free(wlStream);
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
static void
|
|
Packit Service |
f6fdc3 |
handle_swap_interval(struct wl_client *client,
|
|
Packit Service |
f6fdc3 |
struct wl_resource *displayResource,
|
|
Packit Service |
f6fdc3 |
struct wl_resource *streamResource,
|
|
Packit Service |
f6fdc3 |
int interval)
|
|
Packit Service |
f6fdc3 |
{
|
|
Packit Service |
f6fdc3 |
struct wl_eglstream_display *wlStreamDpy =
|
|
Packit Service |
f6fdc3 |
wl_resource_get_user_data(displayResource);
|
|
Packit Service |
f6fdc3 |
struct wl_eglstream *wlStream =
|
|
Packit Service |
f6fdc3 |
wl_eglstream_display_get_stream(wlStreamDpy, streamResource);
|
|
Packit Service |
f6fdc3 |
(void) client;
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
if (wlEglStreamSwapIntervalCallback(wlStreamDpy->data,
|
|
Packit Service |
f6fdc3 |
wlStream->eglStream,
|
|
Packit Service |
f6fdc3 |
&interval) == EGL_BAD_MATCH) {
|
|
Packit Service |
f6fdc3 |
wl_eglstream_display_send_swapinterval_override(displayResource,
|
|
Packit Service |
f6fdc3 |
interval,
|
|
Packit Service |
f6fdc3 |
streamResource);
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
static const struct wl_eglstream_display_interface
|
|
Packit Service |
f6fdc3 |
wl_eglstream_display_interface_impl = {
|
|
Packit Service |
f6fdc3 |
handle_create_stream,
|
|
Packit Service |
f6fdc3 |
handle_swap_interval,
|
|
Packit Service |
f6fdc3 |
};
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
static void
|
|
Packit Service |
f6fdc3 |
wl_eglstream_display_global_bind(struct wl_client *client,
|
|
Packit Service |
f6fdc3 |
void *data,
|
|
Packit Service |
f6fdc3 |
uint32_t version,
|
|
Packit Service |
f6fdc3 |
uint32_t id)
|
|
Packit Service |
f6fdc3 |
{
|
|
Packit Service |
f6fdc3 |
struct wl_eglstream_display *wlStreamDpy = NULL;
|
|
Packit Service |
f6fdc3 |
struct wl_resource *resource = NULL;
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
wlStreamDpy = (struct wl_eglstream_display *)data;
|
|
Packit Service |
f6fdc3 |
resource = wl_resource_create(client,
|
|
Packit Service |
f6fdc3 |
&wl_eglstream_display_interface,
|
|
Packit Service |
f6fdc3 |
version,
|
|
Packit Service |
f6fdc3 |
id);
|
|
Packit Service |
f6fdc3 |
if (!resource) {
|
|
Packit Service |
f6fdc3 |
wl_client_post_no_memory(client);
|
|
Packit Service |
f6fdc3 |
return;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
wl_resource_set_implementation(resource,
|
|
Packit Service |
f6fdc3 |
&wl_eglstream_display_interface_impl,
|
|
Packit Service |
f6fdc3 |
data,
|
|
Packit Service |
f6fdc3 |
NULL);
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
wl_eglstream_display_send_caps(resource, wlStreamDpy->supported_caps);
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
EGLBoolean
|
|
Packit Service |
f6fdc3 |
wl_eglstream_display_bind(WlEglPlatformData *data,
|
|
Packit Service |
f6fdc3 |
struct wl_display *wlDisplay,
|
|
Packit Service |
f6fdc3 |
EGLDisplay eglDisplay)
|
|
Packit Service |
f6fdc3 |
{
|
|
Packit Service |
f6fdc3 |
struct wl_eglstream_display *wlStreamDpy = NULL;
|
|
Packit Service |
f6fdc3 |
const char *exts = NULL;
|
|
Packit Service |
f6fdc3 |
char *env = NULL;
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
/* Check whether there's an EGLDisplay already bound to the given
|
|
Packit Service |
f6fdc3 |
* wl_display */
|
|
Packit Service |
f6fdc3 |
if (wl_eglstream_display_get(eglDisplay) != NULL) {
|
|
Packit Service |
f6fdc3 |
return EGL_FALSE;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
wlStreamDpy = calloc(1, sizeof(*wlStreamDpy));
|
|
Packit Service |
f6fdc3 |
if (!wlStreamDpy) {
|
|
Packit Service |
f6fdc3 |
return EGL_FALSE;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
wlStreamDpy->data = data;
|
|
Packit Service |
f6fdc3 |
wlStreamDpy->wlDisplay = wlDisplay;
|
|
Packit Service |
f6fdc3 |
wlStreamDpy->eglDisplay = eglDisplay;
|
|
Packit Service |
f6fdc3 |
wlStreamDpy->caps_override = 0;
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
4e1167 |
wlExternalApiUnlock();
|
|
Packit Service |
f6fdc3 |
exts = data->egl.queryString(eglDisplay, EGL_EXTENSIONS);
|
|
Packit Service |
4e1167 |
wlExternalApiLock();
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
#define CACHE_EXT(_PREFIX_, _NAME_) \
|
|
Packit Service |
f6fdc3 |
wlStreamDpy->exts._NAME_ = \
|
|
Packit Service |
f6fdc3 |
!!wlEglFindExtension("EGL_" #_PREFIX_ "_" #_NAME_, exts)
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
CACHE_EXT(NV, stream_attrib);
|
|
Packit Service |
f6fdc3 |
CACHE_EXT(KHR, stream_cross_process_fd);
|
|
Packit Service |
f6fdc3 |
CACHE_EXT(NV, stream_remote);
|
|
Packit Service |
f6fdc3 |
CACHE_EXT(NV, stream_socket);
|
|
Packit Service |
f6fdc3 |
CACHE_EXT(NV, stream_socket_inet);
|
|
Packit Service |
f6fdc3 |
CACHE_EXT(NV, stream_socket_unix);
|
|
Packit Service |
f6fdc3 |
CACHE_EXT(NV, stream_origin);
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
#undef CACHE_EXT
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
/* Advertise server capabilities */
|
|
Packit Service |
f6fdc3 |
if (wlStreamDpy->exts.stream_cross_process_fd) {
|
|
Packit Service |
f6fdc3 |
wlStreamDpy->supported_caps |= WL_EGLSTREAM_DISPLAY_CAP_STREAM_FD;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
if (wlStreamDpy->exts.stream_attrib &&
|
|
Packit Service |
f6fdc3 |
wlStreamDpy->exts.stream_remote &&
|
|
Packit Service |
f6fdc3 |
wlStreamDpy->exts.stream_socket) {
|
|
Packit Service |
f6fdc3 |
if (wlStreamDpy->exts.stream_socket_inet) {
|
|
Packit Service |
f6fdc3 |
wlStreamDpy->supported_caps |= WL_EGLSTREAM_DISPLAY_CAP_STREAM_INET;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
if (wlStreamDpy->exts.stream_socket_unix) {
|
|
Packit Service |
f6fdc3 |
wlStreamDpy->supported_caps |= WL_EGLSTREAM_DISPLAY_CAP_STREAM_SOCKET;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
env = getenv("WL_EGLSTREAM_CAP_OVERRIDE");
|
|
Packit Service |
f6fdc3 |
if (env) {
|
|
Packit Service |
f6fdc3 |
int serverCapOverride = atoi(env);
|
|
Packit Service |
f6fdc3 |
wlStreamDpy->caps_override = (wlStreamDpy->supported_caps
|
|
Packit Service |
f6fdc3 |
& serverCapOverride) !=
|
|
Packit Service |
f6fdc3 |
wlStreamDpy->supported_caps;
|
|
Packit Service |
f6fdc3 |
wlStreamDpy->supported_caps &= serverCapOverride;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
wlStreamDpy->wl_eglstream_interface.destroy = destroy_wl_eglstream;
|
|
Packit Service |
f6fdc3 |
wlStreamDpy->global = wl_global_create(wlDisplay,
|
|
Packit Service |
f6fdc3 |
&wl_eglstream_display_interface, 1,
|
|
Packit Service |
f6fdc3 |
wlStreamDpy,
|
|
Packit Service |
f6fdc3 |
wl_eglstream_display_global_bind);
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
wl_list_insert(&wlStreamDpyList, &wlStreamDpy->link);
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
return EGL_TRUE;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
void
|
|
Packit Service |
f6fdc3 |
wl_eglstream_display_unbind(struct wl_eglstream_display *wlStreamDpy)
|
|
Packit Service |
f6fdc3 |
{
|
|
Packit Service |
f6fdc3 |
wl_global_destroy(wlStreamDpy->global);
|
|
Packit Service |
f6fdc3 |
wl_list_remove(&wlStreamDpy->link);
|
|
Packit Service |
f6fdc3 |
free(wlStreamDpy);
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
struct wl_eglstream_display* wl_eglstream_display_get(EGLDisplay eglDisplay)
|
|
Packit Service |
f6fdc3 |
{
|
|
Packit Service |
f6fdc3 |
struct wl_eglstream_display *wlDisplay;
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
wl_list_for_each(wlDisplay, &wlStreamDpyList, link) {
|
|
Packit Service |
f6fdc3 |
if (wlDisplay->eglDisplay == eglDisplay) {
|
|
Packit Service |
f6fdc3 |
return wlDisplay;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
return NULL;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
struct wl_eglstream*
|
|
Packit Service |
f6fdc3 |
wl_eglstream_display_get_stream(struct wl_eglstream_display *wlStreamDpy,
|
|
Packit Service |
f6fdc3 |
struct wl_resource *resource)
|
|
Packit Service |
f6fdc3 |
{
|
|
Packit Service |
f6fdc3 |
if (resource == NULL) {
|
|
Packit Service |
f6fdc3 |
return NULL;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|
|
Packit Service |
f6fdc3 |
if (wl_resource_instance_of(resource, &wl_buffer_interface,
|
|
Packit Service |
f6fdc3 |
&wlStreamDpy->wl_eglstream_interface)) {
|
|
Packit Service |
f6fdc3 |
return wl_resource_get_user_data(resource);
|
|
Packit Service |
f6fdc3 |
} else {
|
|
Packit Service |
f6fdc3 |
return NULL;
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
}
|
|
Packit Service |
f6fdc3 |
|