// Copyright 2022 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef libWaylandClient_hpp
#define libWaylandClient_hpp

#include <wayland-client.h>

// The Wayland protocol functions used by the WSI (wl_display_get_registry,
// wl_registry_bind, wl_surface_attach, wl_shm_create_pool, ...) are NOT real
// symbols exported by libwayland-client.so; they are `static inline` wrappers
// generated into <wayland-client-protocol.h> that marshal requests through the
// low-level wl_proxy_* primitives. SwiftShader loads libwayland-client.so
// dynamically (so it remains a self-contained ICD that also works where Wayland
// is absent), therefore it can only dlsym the real exported primitives and must
// re-implement those inline wrappers on top of them. dlsym'ing the wrapper names
// directly just returns nullptr, which would crash on first use.
struct LibWaylandClientExports
{
	LibWaylandClientExports() {}
	LibWaylandClientExports(void *libwl);

	// Real exported primitives: display and event-queue handling.
	int (*wl_display_dispatch_queue)(wl_display *display, wl_event_queue *queue) = nullptr;
	int (*wl_display_roundtrip_queue)(wl_display *display, wl_event_queue *queue) = nullptr;
	int (*wl_display_flush)(wl_display *display) = nullptr;
	wl_event_queue *(*wl_display_create_queue)(wl_display *display) = nullptr;
	void (*wl_event_queue_destroy)(wl_event_queue *queue) = nullptr;

	// Real exported primitives: proxy marshalling and lifetime.
	// Requests are marshalled with the wl_proxy_marshal[_constructor[_versioned]]
	// trio (available since libwayland 1.2) rather than the newer
	// wl_proxy_marshal_flags (1.20 / 1.19.91), so this builds and runs against
	// older libwayland too. These are exactly the primitives the generated
	// static-inline wrappers used prior to 1.20.
	void (*wl_proxy_marshal)(wl_proxy *proxy, uint32_t opcode, ...) = nullptr;
	wl_proxy *(*wl_proxy_marshal_constructor)(wl_proxy *proxy, uint32_t opcode, const wl_interface *interface, ...) = nullptr;
	wl_proxy *(*wl_proxy_marshal_constructor_versioned)(wl_proxy *proxy, uint32_t opcode, const wl_interface *interface, uint32_t version, ...) = nullptr;
	int (*wl_proxy_add_listener)(wl_proxy *proxy, void (**implementation)(void), void *data) = nullptr;
	void (*wl_proxy_destroy)(wl_proxy *proxy) = nullptr;
	void (*wl_proxy_set_queue)(wl_proxy *proxy, wl_event_queue *queue) = nullptr;
	void *(*wl_proxy_create_wrapper)(void *proxy) = nullptr;
	void (*wl_proxy_wrapper_destroy)(void *proxy_wrapper) = nullptr;

	// Real exported data symbols: protocol interface descriptions.
	const wl_interface *wl_registry_interface = nullptr;
	const wl_interface *wl_shm_interface = nullptr;
	const wl_interface *wl_shm_pool_interface = nullptr;
	const wl_interface *wl_surface_interface = nullptr;
	const wl_interface *wl_buffer_interface = nullptr;

	// Re-implementations of the generated static-inline protocol wrappers, built
	// on top of the loaded primitives above.
	wl_registry *display_get_registry(wl_display *display);
	int registry_add_listener(wl_registry *registry, const wl_registry_listener *listener, void *data);
	void *registry_bind(wl_registry *registry, uint32_t name, const wl_interface *interface, uint32_t version);
	wl_shm_pool *shm_create_pool(wl_shm *shm, int32_t fd, int32_t size);
	wl_buffer *shm_pool_create_buffer(wl_shm_pool *pool, int32_t offset, int32_t width, int32_t height, int32_t stride, uint32_t format);
	void shm_pool_destroy(wl_shm_pool *pool);
	int buffer_add_listener(wl_buffer *buffer, const wl_buffer_listener *listener, void *data);
	void buffer_destroy(wl_buffer *buffer);
	void surface_attach(wl_surface *surface, wl_buffer *buffer, int32_t x, int32_t y);
	void surface_damage(wl_surface *surface, int32_t x, int32_t y, int32_t width, int32_t height);
	void surface_commit(wl_surface *surface);

	// True when every primitive and interface required by the WSI resolved.
	bool loaded() const;
};

class LibWaylandClient
{
public:
	bool isPresent()
	{
		return loadExports() != nullptr;
	}

	LibWaylandClientExports *operator->();

private:
	LibWaylandClientExports *loadExports();
};

extern LibWaylandClient libWaylandClient;

#endif  // libWaylandClient_hpp
