2019-03-18 05:52:32 +00:00
|
|
|
// Copyright 2018-2019, Collabora, Ltd.
|
|
|
|
// SPDX-License-Identifier: BSL-1.0
|
|
|
|
/*!
|
|
|
|
* @file
|
|
|
|
* @brief Holds event related functions.
|
|
|
|
* @author Jakob Bornecrantz <jakob@collabora.com>
|
|
|
|
* @ingroup oxr_main
|
|
|
|
*/
|
|
|
|
|
2019-10-08 14:28:15 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
2019-03-18 05:52:32 +00:00
|
|
|
|
2019-06-18 19:13:35 +00:00
|
|
|
#include "util/u_misc.h"
|
|
|
|
|
2019-03-18 05:52:32 +00:00
|
|
|
#include "oxr_objects.h"
|
|
|
|
#include "oxr_logger.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct oxr_event
|
|
|
|
{
|
|
|
|
struct oxr_event *next;
|
|
|
|
size_t length;
|
2019-09-26 20:25:05 +00:00
|
|
|
XrResult result;
|
2019-03-18 05:52:32 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
lock(struct oxr_instance *inst)
|
|
|
|
{}
|
|
|
|
|
|
|
|
void
|
|
|
|
unlock(struct oxr_instance *inst)
|
|
|
|
{}
|
|
|
|
|
2019-10-08 14:28:15 +00:00
|
|
|
void *
|
|
|
|
oxr_event_extra(struct oxr_event *event)
|
|
|
|
{
|
|
|
|
return &event[1];
|
|
|
|
}
|
|
|
|
|
2019-03-18 05:52:32 +00:00
|
|
|
struct oxr_event *
|
|
|
|
pop(struct oxr_instance *inst)
|
|
|
|
{
|
2019-10-08 14:28:15 +00:00
|
|
|
struct oxr_event *ret = inst->next_event;
|
2019-03-18 05:52:32 +00:00
|
|
|
if (ret == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
inst->next_event = ret->next;
|
|
|
|
ret->next = NULL;
|
|
|
|
|
|
|
|
if (ret == inst->last_event) {
|
|
|
|
inst->last_event = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
push(struct oxr_instance *inst, struct oxr_event *event)
|
|
|
|
{
|
2019-10-08 14:28:15 +00:00
|
|
|
struct oxr_event *last = inst->last_event;
|
2019-03-18 05:52:32 +00:00
|
|
|
if (last != NULL) {
|
|
|
|
last->next = event;
|
|
|
|
}
|
|
|
|
inst->last_event = event;
|
|
|
|
|
|
|
|
if (inst->next_event == NULL) {
|
|
|
|
inst->next_event = event;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#define ALLOC(log, inst, event, extra) \
|
|
|
|
do { \
|
|
|
|
XrResult ret = \
|
|
|
|
oxr_event_alloc(log, inst, sizeof(**extra), event); \
|
|
|
|
if (ret != XR_SUCCESS) { \
|
|
|
|
return ret; \
|
|
|
|
} \
|
2019-10-08 14:28:15 +00:00
|
|
|
*((void **)extra) = oxr_event_extra(*event); \
|
2019-03-18 05:52:32 +00:00
|
|
|
} while (false)
|
|
|
|
|
|
|
|
static XrResult
|
|
|
|
oxr_event_alloc(struct oxr_logger *log,
|
|
|
|
struct oxr_instance *inst,
|
|
|
|
size_t size,
|
|
|
|
struct oxr_event **out_event)
|
|
|
|
{
|
2019-06-18 19:13:35 +00:00
|
|
|
struct oxr_event *event = U_CALLOC_WITH_CAST(
|
|
|
|
struct oxr_event, sizeof(struct oxr_event) + size);
|
2019-03-18 05:52:32 +00:00
|
|
|
|
|
|
|
if (event == NULL) {
|
|
|
|
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE,
|
|
|
|
" out of memory");
|
|
|
|
}
|
|
|
|
|
|
|
|
event->next = NULL;
|
|
|
|
event->length = size;
|
2019-09-26 20:25:05 +00:00
|
|
|
event->result = XR_SUCCESS;
|
2019-03-18 05:52:32 +00:00
|
|
|
|
|
|
|
*out_event = event;
|
|
|
|
|
|
|
|
return XR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
XrResult
|
|
|
|
oxr_event_push_XrEventDataSessionStateChanged(struct oxr_logger *log,
|
|
|
|
struct oxr_session *sess,
|
|
|
|
XrSessionState state,
|
|
|
|
XrTime time)
|
|
|
|
{
|
|
|
|
struct oxr_instance *inst = sess->sys->inst;
|
|
|
|
XrEventDataSessionStateChanged *changed;
|
2019-07-24 23:52:07 +00:00
|
|
|
struct oxr_event *event = NULL;
|
2019-03-18 05:52:32 +00:00
|
|
|
|
|
|
|
ALLOC(log, inst, &event, &changed);
|
|
|
|
|
|
|
|
changed->type = XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED;
|
|
|
|
changed->session = oxr_session_to_openxr(sess);
|
|
|
|
changed->state = state;
|
|
|
|
changed->time = time;
|
|
|
|
|
2019-09-26 20:25:05 +00:00
|
|
|
event->result = state == XR_SESSION_STATE_LOSS_PENDING
|
|
|
|
? XR_SESSION_LOSS_PENDING
|
|
|
|
: XR_SUCCESS;
|
|
|
|
|
2019-03-18 05:52:32 +00:00
|
|
|
lock(inst);
|
|
|
|
push(inst, event);
|
|
|
|
unlock(inst);
|
|
|
|
|
|
|
|
return XR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2020-05-30 12:26:46 +00:00
|
|
|
XrResult
|
|
|
|
oxr_event_remove_session_events(struct oxr_logger *log,
|
|
|
|
struct oxr_session *sess)
|
|
|
|
{
|
|
|
|
struct oxr_instance *inst = sess->sys->inst;
|
|
|
|
XrSession session = oxr_session_to_openxr(sess);
|
|
|
|
|
|
|
|
lock(inst);
|
|
|
|
|
|
|
|
struct oxr_event *e = inst->next_event;
|
|
|
|
while (e != NULL) {
|
|
|
|
struct oxr_event *cur = e;
|
|
|
|
e = e->next;
|
|
|
|
|
|
|
|
XrEventDataSessionStateChanged *changed = oxr_event_extra(cur);
|
|
|
|
if (changed->type != XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (changed->session != session) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cur == inst->next_event) {
|
|
|
|
inst->next_event = cur->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cur == inst->last_event) {
|
|
|
|
inst->last_event = NULL;
|
|
|
|
}
|
|
|
|
free(cur);
|
|
|
|
}
|
|
|
|
|
|
|
|
unlock(inst);
|
|
|
|
|
|
|
|
return XR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2019-03-18 05:52:32 +00:00
|
|
|
XrResult
|
|
|
|
oxr_poll_event(struct oxr_logger *log,
|
|
|
|
struct oxr_instance *inst,
|
|
|
|
XrEventDataBuffer *eventData)
|
|
|
|
{
|
2019-10-08 15:24:16 +00:00
|
|
|
struct oxr_session *sess = inst->sessions;
|
|
|
|
while (sess) {
|
|
|
|
oxr_session_poll(sess);
|
|
|
|
sess = sess->next;
|
|
|
|
}
|
|
|
|
|
2019-03-18 05:52:32 +00:00
|
|
|
lock(inst);
|
2019-10-08 14:28:15 +00:00
|
|
|
struct oxr_event *event = pop(inst);
|
2019-03-18 05:52:32 +00:00
|
|
|
unlock(inst);
|
|
|
|
|
|
|
|
if (event == NULL) {
|
|
|
|
return XR_EVENT_UNAVAILABLE;
|
|
|
|
}
|
|
|
|
|
2019-11-13 20:53:16 +00:00
|
|
|
XrResult ret = event->result;
|
2019-10-08 14:28:15 +00:00
|
|
|
memcpy(eventData, oxr_event_extra(event), event->length);
|
2019-03-18 05:52:32 +00:00
|
|
|
free(event);
|
|
|
|
|
2019-11-13 20:53:16 +00:00
|
|
|
return ret;
|
2019-03-18 05:52:32 +00:00
|
|
|
}
|