diff --git a/AGENTS.md b/AGENTS.md
deleted file mode 100644
index 9af3362..0000000
--- a/AGENTS.md
+++ /dev/null
@@ -1,3 +0,0 @@
-Coding conventions:
-- Use `clang-format` on all C and C++ sources before committing.
-- In `CMakeLists.txt`, indent with four spaces. Tabs may be used for C++ files as per .clang-format.
diff --git a/CMakeLists.txt b/CMakeLists.txt
deleted file mode 100644
index f8ffe0b..0000000
--- a/CMakeLists.txt
+++ /dev/null
@@ -1,79 +0,0 @@
-cmake_minimum_required(VERSION 3.12)
-
-project(lunarwm VERSION 0.0.1 LANGUAGES C CXX)
-
-execute_process(COMMAND pkg-config --variable=pkgdatadir wayland-protocols
- OUTPUT_VARIABLE WAYLAND_PROTOCOLS
- OUTPUT_STRIP_TRAILING_WHITESPACE)
-execute_process(COMMAND pkg-config --variable=wayland_scanner wayland-scanner
- OUTPUT_VARIABLE WAYLAND_SCANNER
- OUTPUT_STRIP_TRAILING_WHITESPACE)
-
-add_custom_command(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-protocol.h
- COMMAND ${WAYLAND_SCANNER} server-header
- ${WAYLAND_PROTOCOLS}/stable/xdg-shell/xdg-shell.xml
- ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-protocol.h
- MAIN_DEPENDENCY ${WAYLAND_PROTOCOLS}/stable/xdg-shell/xdg-shell.xml
- COMMENT "Generating xdg-shell-protocol.h"
-)
-
-add_custom_target(xdg_shell_proto
- DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-protocol.h
-)
-
-set(CMAKE_CXX_STANDARD 23)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-set(CMAKE_CXX_EXTENSIONS OFF)
-
-add_compile_options(-Wall -Wextra -Wno-missing-field-initializers)
-
-add_compile_definitions(
- XR_USE_PLATFORM_XLIB
- XR_USE_GRAPHICS_API_OPENGL
- WLR_USE_UNSTABLE
-)
-
-
-list(INSERT CMAKE_MODULE_PATH 0
- ${CMAKE_CURRENT_SOURCE_DIR}/cmake
-)
-
-find_package(OpenGL REQUIRED)
-find_package(OpenXR REQUIRED)
-find_package(glm REQUIRED)
-find_package(PkgConfig REQUIRED)
-pkg_check_modules(Wlroots REQUIRED wlroots-0.19)
-pkg_check_modules(X11 REQUIRED x11)
-pkg_check_modules(wayland REQUIRED wayland-server wayland-protocols)
-
-include_directories(
- ${wayland_INCLUDE_DIRS}
- ${X11_INCLUDE_DIRS}
- ${GLM_INCLUDE_DIRS}
- ${Wlroots_INCLUDE_DIRS}
- ${CMAKE_CURRENT_BINARY_DIR}
-)
-
-set(SOURCES
- src/wlr/backend.cpp
- src/wlr/output.cpp
- src/wlr/openxr_gl.cpp
-
- src/compositor.cpp
- src/main.cpp
-
- ${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-protocol.h
-)
-
-add_executable(${PROJECT_NAME} ${SOURCES})
-
-target_link_libraries(${PROJECT_NAME}
- OpenGL::GL
- openxr_loader
- ${wayland_LIBRARIES}
- ${X11_LIBRARIES}
- ${GLM_LIBRARIES}
- ${Wlroots_LIBRARIES}
-)
-
diff --git a/cmake/FindWlroots.cmake b/cmake/FindWlroots.cmake
deleted file mode 100644
index 07797b5..0000000
--- a/cmake/FindWlroots.cmake
+++ /dev/null
@@ -1,10 +0,0 @@
-find_package(PkgConfig)
-pkg_check_modules(PC_WLR QUIET wlroots)
-find_path(WLR_INCLUDE_DIRS NAMES wlr/config.h HINTS ${PC_WLR_INCLUDE_DIRS})
-find_library(WLR_LIBRARIES NAMES wlroots HINTS ${PC_WLR_LIBRARY_DIRS})
-
-set(WLR_DEFINITIONS ${PC_WLR_CFLAGS_OTHER})
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(wlr DEFAULT_MSG WLR_LIBRARIES WLR_INCLUDE_DIRS)
-mark_as_advanced(WLR_LIBRARIES WLR_INCLUDE_DIRS)
diff --git a/protocol/wlr-layer-shell-unstable-v1.xml b/protocol/wlr-layer-shell-unstable-v1.xml
deleted file mode 100644
index e9f27e4..0000000
--- a/protocol/wlr-layer-shell-unstable-v1.xml
+++ /dev/null
@@ -1,407 +0,0 @@
-
-
-
- Copyright © 2017 Drew DeVault
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that copyright notice and this permission
- notice appear in supporting documentation, and that the name of
- the copyright holders not be used in advertising or publicity
- pertaining to distribution of the software without specific,
- written prior permission. The copyright holders make no
- representations about the suitability of this software for any
- purpose. It is provided "as is" without express or implied
- warranty.
-
- THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
- THIS SOFTWARE.
-
-
-
-
- Clients can use this interface to assign the surface_layer role to
- wl_surfaces. Such surfaces are assigned to a "layer" of the output and
- rendered with a defined z-depth respective to each other. They may also be
- anchored to the edges and corners of a screen and specify input handling
- semantics. This interface should be suitable for the implementation of
- many desktop shell components, and a broad number of other applications
- that interact with the desktop.
-
-
-
-
- Create a layer surface for an existing surface. This assigns the role of
- layer_surface, or raises a protocol error if another role is already
- assigned.
-
- Creating a layer surface from a wl_surface which has a buffer attached
- or committed is a client error, and any attempts by a client to attach
- or manipulate a buffer prior to the first layer_surface.configure call
- must also be treated as errors.
-
- After creating a layer_surface object and setting it up, the client
- must perform an initial commit without any buffer attached.
- The compositor will reply with a layer_surface.configure event.
- The client must acknowledge it and is then allowed to attach a buffer
- to map the surface.
-
- You may pass NULL for output to allow the compositor to decide which
- output to use. Generally this will be the one that the user most
- recently interacted with.
-
- Clients can specify a namespace that defines the purpose of the layer
- surface.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- These values indicate which layers a surface can be rendered in. They
- are ordered by z depth, bottom-most first. Traditional shell surfaces
- will typically be rendered between the bottom and top layers.
- Fullscreen shell surfaces are typically rendered at the top layer.
- Multiple surfaces can share a single layer, and ordering within a
- single layer is undefined.
-
-
-
-
-
-
-
-
-
-
-
-
- This request indicates that the client will not use the layer_shell
- object any more. Objects that have been created through this instance
- are not affected.
-
-
-
-
-
-
- An interface that may be implemented by a wl_surface, for surfaces that
- are designed to be rendered as a layer of a stacked desktop-like
- environment.
-
- Layer surface state (layer, size, anchor, exclusive zone,
- margin, interactivity) is double-buffered, and will be applied at the
- time wl_surface.commit of the corresponding wl_surface is called.
-
- Attaching a null buffer to a layer surface unmaps it.
-
- Unmapping a layer_surface means that the surface cannot be shown by the
- compositor until it is explicitly mapped again. The layer_surface
- returns to the state it had right after layer_shell.get_layer_surface.
- The client can re-map the surface by performing a commit without any
- buffer attached, waiting for a configure event and handling it as usual.
-
-
-
-
- Sets the size of the surface in surface-local coordinates. The
- compositor will display the surface centered with respect to its
- anchors.
-
- If you pass 0 for either value, the compositor will assign it and
- inform you of the assignment in the configure event. You must set your
- anchor to opposite edges in the dimensions you omit; not doing so is a
- protocol error. Both values are 0 by default.
-
- Size is double-buffered, see wl_surface.commit.
-
-
-
-
-
-
-
- Requests that the compositor anchor the surface to the specified edges
- and corners. If two orthogonal edges are specified (e.g. 'top' and
- 'left'), then the anchor point will be the intersection of the edges
- (e.g. the top left corner of the output); otherwise the anchor point
- will be centered on that edge, or in the center if none is specified.
-
- Anchor is double-buffered, see wl_surface.commit.
-
-
-
-
-
-
- Requests that the compositor avoids occluding an area with other
- surfaces. The compositor's use of this information is
- implementation-dependent - do not assume that this region will not
- actually be occluded.
-
- A positive value is only meaningful if the surface is anchored to one
- edge or an edge and both perpendicular edges. If the surface is not
- anchored, anchored to only two perpendicular edges (a corner), anchored
- to only two parallel edges or anchored to all edges, a positive value
- will be treated the same as zero.
-
- A positive zone is the distance from the edge in surface-local
- coordinates to consider exclusive.
-
- Surfaces that do not wish to have an exclusive zone may instead specify
- how they should interact with surfaces that do. If set to zero, the
- surface indicates that it would like to be moved to avoid occluding
- surfaces with a positive exclusive zone. If set to -1, the surface
- indicates that it would not like to be moved to accommodate for other
- surfaces, and the compositor should extend it all the way to the edges
- it is anchored to.
-
- For example, a panel might set its exclusive zone to 10, so that
- maximized shell surfaces are not shown on top of it. A notification
- might set its exclusive zone to 0, so that it is moved to avoid
- occluding the panel, but shell surfaces are shown underneath it. A
- wallpaper or lock screen might set their exclusive zone to -1, so that
- they stretch below or over the panel.
-
- The default value is 0.
-
- Exclusive zone is double-buffered, see wl_surface.commit.
-
-
-
-
-
-
- Requests that the surface be placed some distance away from the anchor
- point on the output, in surface-local coordinates. Setting this value
- for edges you are not anchored to has no effect.
-
- The exclusive zone includes the margin.
-
- Margin is double-buffered, see wl_surface.commit.
-
-
-
-
-
-
-
-
-
- Types of keyboard interaction possible for layer shell surfaces. The
- rationale for this is twofold: (1) some applications are not interested
- in keyboard events and not allowing them to be focused can improve the
- desktop experience; (2) some applications will want to take exclusive
- keyboard focus.
-
-
-
-
- This value indicates that this surface is not interested in keyboard
- events and the compositor should never assign it the keyboard focus.
-
- This is the default value, set for newly created layer shell surfaces.
-
- This is useful for e.g. desktop widgets that display information or
- only have interaction with non-keyboard input devices.
-
-
-
-
- Request exclusive keyboard focus if this surface is above the shell surface layer.
-
- For the top and overlay layers, the seat will always give
- exclusive keyboard focus to the top-most layer which has keyboard
- interactivity set to exclusive. If this layer contains multiple
- surfaces with keyboard interactivity set to exclusive, the compositor
- determines the one receiving keyboard events in an implementation-
- defined manner. In this case, no guarantee is made when this surface
- will receive keyboard focus (if ever).
-
- For the bottom and background layers, the compositor is allowed to use
- normal focus semantics.
-
- This setting is mainly intended for applications that need to ensure
- they receive all keyboard events, such as a lock screen or a password
- prompt.
-
-
-
-
- This requests the compositor to allow this surface to be focused and
- unfocused by the user in an implementation-defined manner. The user
- should be able to unfocus this surface even regardless of the layer
- it is on.
-
- Typically, the compositor will want to use its normal mechanism to
- manage keyboard focus between layer shell surfaces with this setting
- and regular toplevels on the desktop layer (e.g. click to focus).
- Nevertheless, it is possible for a compositor to require a special
- interaction to focus or unfocus layer shell surfaces (e.g. requiring
- a click even if focus follows the mouse normally, or providing a
- keybinding to switch focus between layers).
-
- This setting is mainly intended for desktop shell components (e.g.
- panels) that allow keyboard interaction. Using this option can allow
- implementing a desktop shell that can be fully usable without the
- mouse.
-
-
-
-
-
-
- Set how keyboard events are delivered to this surface. By default,
- layer shell surfaces do not receive keyboard events; this request can
- be used to change this.
-
- This setting is inherited by child surfaces set by the get_popup
- request.
-
- Layer surfaces receive pointer, touch, and tablet events normally. If
- you do not want to receive them, set the input region on your surface
- to an empty region.
-
- Keyboard interactivity is double-buffered, see wl_surface.commit.
-
-
-
-
-
-
- This assigns an xdg_popup's parent to this layer_surface. This popup
- should have been created via xdg_surface::get_popup with the parent set
- to NULL, and this request must be invoked before committing the popup's
- initial state.
-
- See the documentation of xdg_popup for more details about what an
- xdg_popup is and how it is used.
-
-
-
-
-
-
- When a configure event is received, if a client commits the
- surface in response to the configure event, then the client
- must make an ack_configure request sometime before the commit
- request, passing along the serial of the configure event.
-
- If the client receives multiple configure events before it
- can respond to one, it only has to ack the last configure event.
-
- A client is not required to commit immediately after sending
- an ack_configure request - it may even ack_configure several times
- before its next surface commit.
-
- A client may send multiple ack_configure requests before committing, but
- only the last request sent before a commit indicates which configure
- event the client really is responding to.
-
-
-
-
-
-
- This request destroys the layer surface.
-
-
-
-
-
- The configure event asks the client to resize its surface.
-
- Clients should arrange their surface for the new states, and then send
- an ack_configure request with the serial sent in this configure event at
- some point before committing the new surface.
-
- The client is free to dismiss all but the last configure event it
- received.
-
- The width and height arguments specify the size of the window in
- surface-local coordinates.
-
- The size is a hint, in the sense that the client is free to ignore it if
- it doesn't resize, pick a smaller size (to satisfy aspect ratio or
- resize in steps of NxM pixels). If the client picks a smaller size and
- is anchored to two opposite anchors (e.g. 'top' and 'bottom'), the
- surface will be centered on this axis.
-
- If the width or height arguments are zero, it means the client should
- decide its own window dimension.
-
-
-
-
-
-
-
-
- The closed event is sent by the compositor when the surface will no
- longer be shown. The output may have been destroyed or the user may
- have asked for it to be removed. Further changes to the surface will be
- ignored. The client should destroy the resource after receiving this
- event, and create a new surface if they so choose.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Change the layer that the surface is rendered on.
-
- Layer is double-buffered, see wl_surface.commit.
-
-
-
-
-
-
-
-
- Requests an edge for the exclusive zone to apply. The exclusive
- edge will be automatically deduced from anchor points when possible,
- but when the surface is anchored to a corner, it will be necessary
- to set it explicitly to disambiguate, as it is not possible to deduce
- which one of the two corner edges should be used.
-
- The edge must be one the surface is anchored to, otherwise the
- invalid_exclusive_edge protocol error will be raised.
-
-
-
-
-
diff --git a/src/common.h b/src/common.h
deleted file mode 100644
index 45a8ac3..0000000
--- a/src/common.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include
-
-#define OPENXR_CHECK(fn_call, ...) \
- do { \
- XrResult result = fn_call(__VA_ARGS__); \
- if (result != XR_SUCCESS) { \
- std::array msg {}; \
- xrResultToString(nullptr, result, msg.data()); \
- throw std::runtime_error( \
- std::format("OpenXR call '{}' failed (code {}): {}", #fn_call, \
- static_cast(result), msg.data())); \
- } \
- } while (0)
diff --git a/src/compositor.cpp b/src/compositor.cpp
deleted file mode 100644
index 189f765..0000000
--- a/src/compositor.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-#include "compositor.h"
-
-#include
-extern "C" {
-#include
-#include
-#include
-
-wlr_scene* wlr_scene_create();
-}
-
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-void handle_new_output(struct wl_listener* l, void* d)
-{
- (void)l;
- (void)d;
-}
-
-void handle_new_input(struct wl_listener* l, void* d)
-{
- (void)l;
- (void)d;
-}
-
-void handle_xdg_toplevel(struct wl_listener* l, void* d)
-{
- (void)l;
- (void)d;
-}
-
-void handle_xdg_popup(struct wl_listener* l, void* d)
-{
- (void)l;
- (void)d;
-}
-
-Compositor::Compositor()
-{
- // init logging + display + event loop
- wlr_log_init(WLR_DEBUG, nullptr);
- m_display = wl_display_create();
- m_event_loop = wl_display_get_event_loop(m_display);
-
- // openxr backend
- m_backend = wlr_openxr_backend_create(m_display, m_event_loop);
- if (!m_backend)
- throw std::runtime_error("backend fail");
-
- // renderer + allocator
- m_renderer = wlr_renderer_autocreate(m_backend);
- if (!m_renderer)
- throw std::runtime_error("Failed to create wlr_renderer.");
- wlr_renderer_init_wl_display(m_renderer, m_display);
- m_allocator = wlr_allocator_autocreate(m_backend, m_renderer);
- if (!m_allocator)
- throw std::runtime_error("Failed to create wlr_allocator.");
-
- // compositor/subcompositor/data-device
- m_compositor = wlr_compositor_create(m_display, 4, m_renderer);
- if (!m_compositor)
- throw std::runtime_error("Failed to create wlr_compositor.");
- m_subcompositor = wlr_subcompositor_create(m_display);
- if (!m_subcompositor)
- throw std::runtime_error("Failed to create wlr_subcompositor.");
- m_data_device = wlr_data_device_manager_create(m_display);
- if (!m_data_device)
- throw std::runtime_error("Failed to create wlr_data_device_manager.");
-
- // scene + output layout
- m_scene = wlr_scene_create();
- if (!m_scene)
- throw std::runtime_error("Failed to create wlr_scene.");
- m_output_layout = wlr_output_layout_create(m_display);
- if (!m_output_layout)
- throw std::runtime_error("Failed to create wlr_output_layout.");
-
- // seat for input
- m_seat = wlr_seat_create(m_display, "seat0");
- if (!m_seat)
- throw std::runtime_error("Failed to create wlr_seat.");
-
- // xdg shell
- m_xdg_shell = wlr_xdg_shell_create(m_display, 3);
- if (!m_xdg_shell)
- throw std::runtime_error("Failed to create wlr_xdg_shell.");
- m_new_xdg_toplevel.notify = handle_xdg_toplevel;
- wl_signal_add(&m_xdg_shell->events.new_toplevel, &m_new_xdg_toplevel);
- m_new_xdg_popup.notify = handle_xdg_popup;
- wl_signal_add(&m_xdg_shell->events.new_popup, &m_new_xdg_popup);
-
- // hook up backend signals
- m_new_output.notify = handle_new_output;
- wl_signal_add(&m_backend->events.new_output, &m_new_output);
- m_new_input.notify = handle_new_input;
- wl_signal_add(&m_backend->events.new_input, &m_new_input);
-}
-
-Compositor::~Compositor()
-{
- if (m_backend) {
- wlr_backend_destroy(m_backend);
- m_backend = nullptr;
- }
- if (m_display) {
- wl_display_destroy(m_display);
- m_display = nullptr;
- }
-}
-
-void Compositor::run()
-{
- char const* socket = wl_display_add_socket_auto(m_display);
- if (!socket) {
- throw std::runtime_error("Failed to create socket");
- }
-
- if (!wlr_backend_start(m_backend)) {
- throw std::runtime_error("Failed to start wlroots backend");
- }
-
- setenv("WAYLAND_DISPLAY", socket, true);
-
- wlr_log(
- WLR_INFO, "Running Wayland compositor on WAYLAND_DISPLAY=%s", socket);
-
- wl_display_run(m_display);
-}
diff --git a/src/compositor.h b/src/compositor.h
deleted file mode 100644
index 2847749..0000000
--- a/src/compositor.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#pragma once
-
-#include
-extern "C" {
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-}
-#include "wlr/openxr_gl.h"
-
-struct wlr_scene;
-
-struct Compositor {
- Compositor();
- ~Compositor();
-
- void run();
- void stop() { wl_display_terminate(m_display); }
-
- wl_listener m_new_output;
-
-private:
- // wlroots integration
- wl_display* m_display = nullptr;
- wl_event_loop* m_event_loop = nullptr;
- wlr_backend* m_backend = nullptr;
-
- wlr_renderer* m_renderer = nullptr;
- wlr_allocator* m_allocator = nullptr;
- wlr_compositor* m_compositor = nullptr;
- wlr_subcompositor* m_subcompositor = nullptr;
- wlr_data_device_manager* m_data_device = nullptr;
- wlr_scene* m_scene = nullptr;
- wlr_output_layout* m_output_layout = nullptr;
- wlr_xdg_shell* m_xdg_shell = nullptr;
- wlr_seat* m_seat = nullptr;
-
- wl_listener m_new_input;
- wl_listener m_new_xdg_toplevel;
- wl_listener m_new_xdg_popup;
-};
diff --git a/src/main.cpp b/src/main.cpp
deleted file mode 100644
index 6175d44..0000000
--- a/src/main.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "compositor.h"
-
-#include
-#include
-#include
-
-std::unique_ptr g_c;
-
-int main(void)
-{
- g_c = std::make_unique();
- std::signal(SIGINT, [](int) { g_c->stop(); });
- g_c->run();
-
- std::println("bai bai~!");
-}
diff --git a/src/wlr/backend.cpp b/src/wlr/backend.cpp
deleted file mode 100644
index 3d2d486..0000000
--- a/src/wlr/backend.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include "openxr_gl.h"
-
-extern "C" {
-#include
-}
-
-extern "C" {
-
-struct wlr_backend* wlr_my_backend_create(
- struct wl_event_loop* loop, char const* name)
-{
- (void)name;
- return wlr_openxr_backend_create(nullptr, loop);
-}
-
-bool wlr_backend_is_mybackend(struct wlr_backend* backend)
-{
- return wlr_backend_is_openxr(backend);
-}
-}
diff --git a/src/wlr/openxr_gl.cpp b/src/wlr/openxr_gl.cpp
deleted file mode 100644
index 8af3070..0000000
--- a/src/wlr/openxr_gl.cpp
+++ /dev/null
@@ -1,359 +0,0 @@
-#include "openxr_gl.h"
-
-extern "C" {
-#include
-#include
-#include
-#include
-}
-
-#include
-#include
-
-#define GL_GLEXT_PROTOTYPES
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-// Internal backend definition
-struct openxr_backend {
- wlr_backend base;
- wl_display* display;
- wl_event_loop* event_loop;
- XrInstance instance {};
- XrSession session {};
- XrSpace app_space { XR_NULL_HANDLE };
- XrSwapchain swapchain { XR_NULL_HANDLE };
- int32_t width = 0, height = 0;
- std::vector swapchain_images;
- std::vector framebuffers;
- bool started = false;
- struct wlr_output* output = nullptr;
-};
-
-static void output_destroy(struct wlr_output* wlr_output) { (void)wlr_output; }
-
-static bool output_test(
- struct wlr_output* wlr_output, const struct wlr_output_state* state)
-{
- (void)wlr_output;
- (void)state;
- return true;
-}
-
-static bool output_commit(
- struct wlr_output* wlr_output, const struct wlr_output_state* state)
-{
- // Retrieve our backend
- auto* xr = reinterpret_cast(wlr_output->backend);
- (void)state;
- // Wait for frame
- XrFrameState frameState { XR_TYPE_FRAME_STATE };
- xrWaitFrame(xr->session, nullptr, &frameState);
- xrBeginFrame(xr->session, nullptr);
- // Locate views
- uint32_t viewCount = static_cast(xr->framebuffers.size());
- std::vector views(viewCount, { XR_TYPE_VIEW });
- XrViewLocateInfo viewLocInfo { XR_TYPE_VIEW_LOCATE_INFO };
- viewLocInfo.viewConfigurationType
- = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
- viewLocInfo.displayTime = frameState.predictedDisplayTime;
- viewLocInfo.space = xr->app_space;
- XrViewState viewState { XR_TYPE_VIEW_STATE };
- uint32_t viewCountOutput;
- xrLocateViews(xr->session, &viewLocInfo, &viewState, viewCount,
- &viewCountOutput, views.data());
- // Prepare projection views
- std::vector projViews(
- viewCountOutput, { XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW });
- for (uint32_t i = 0; i < viewCountOutput; ++i) {
- // Acquire swapchain image
- XrSwapchainImageAcquireInfo acqInfo {
- XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO
- };
- uint32_t imgIndex;
- xrAcquireSwapchainImage(xr->swapchain, &acqInfo, &imgIndex);
- XrSwapchainImageWaitInfo waitInfo { XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO };
- waitInfo.timeout = XR_INFINITE_DURATION;
- xrWaitSwapchainImage(xr->swapchain, &waitInfo);
- // Bind framebuffer and clear
- glBindFramebuffer(GL_FRAMEBUFFER, xr->framebuffers[imgIndex]);
- glViewport(0, 0, xr->width, xr->height);
- glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- // TODO: render scene (e.g., wlr_scene_render)
- // Release swapchain image
- {
- XrSwapchainImageReleaseInfo relInfo {
- XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO
- };
- xrReleaseSwapchainImage(xr->swapchain, &relInfo);
- }
- // Setup projection view
- projViews[i].pose = views[i].pose;
- projViews[i].fov = views[i].fov;
- projViews[i].subImage.swapchain = xr->swapchain;
- projViews[i].subImage.imageArrayIndex = imgIndex;
- // Set image rectangle offset and extent
- projViews[i].subImage.imageRect.offset.x = 0;
- projViews[i].subImage.imageRect.offset.y = 0;
- projViews[i].subImage.imageRect.extent.width = xr->width;
- projViews[i].subImage.imageRect.extent.height = xr->height;
- }
- // Unbind
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- // End frame
- XrCompositionLayerProjection layer { XR_TYPE_COMPOSITION_LAYER_PROJECTION };
- layer.space = xr->app_space;
- layer.viewCount = static_cast(projViews.size());
- layer.views = projViews.data();
- XrCompositionLayerBaseHeader const* layers[]
- = { reinterpret_cast(&layer) };
- XrFrameEndInfo frameEndInfo { XR_TYPE_FRAME_END_INFO };
- frameEndInfo.displayTime = frameState.predictedDisplayTime;
- frameEndInfo.environmentBlendMode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
- frameEndInfo.layerCount = 1;
- frameEndInfo.layers = layers;
- xrEndFrame(xr->session, &frameEndInfo);
- return true;
-}
-
-static const struct wlr_drm_format_set* output_get_primary_formats(
- struct wlr_output* wlr_output, uint32_t buffer_caps)
-{
- (void)wlr_output;
- (void)buffer_caps;
- return NULL;
-}
-
-static const struct wlr_output_impl output_impl = {
- .destroy = output_destroy,
- .test = output_test,
- .commit = output_commit,
- .get_primary_formats = output_get_primary_formats,
-};
-
-static bool backend_start(wlr_backend* backend)
-{
- auto* xr = reinterpret_cast(backend);
- if (xr->started)
- return true;
-
- XrApplicationInfo ai {};
- std::strncpy(
- ai.applicationName, "LunarWM", XR_MAX_APPLICATION_NAME_SIZE - 1);
- ai.applicationVersion = 1;
- std::strncpy(ai.engineName, "LunarWM", XR_MAX_ENGINE_NAME_SIZE - 1);
- ai.engineVersion = 1;
- ai.apiVersion = XR_API_VERSION_1_0;
-
- char const* exts[] = {
- XR_EXT_DEBUG_UTILS_EXTENSION_NAME,
- XR_KHR_OPENGL_ENABLE_EXTENSION_NAME,
- };
-
- XrInstanceCreateInfo ic { XR_TYPE_INSTANCE_CREATE_INFO };
- ic.applicationInfo = ai;
- ic.enabledExtensionCount = sizeof(exts) / sizeof(exts[0]);
- ic.enabledExtensionNames = exts;
-
- if (xrCreateInstance(&ic, &xr->instance) != XR_SUCCESS) {
- wlr_log(WLR_ERROR, "Failed to create OpenXR instance");
- return false;
- }
-
- XrSystemGetInfo sgi { XR_TYPE_SYSTEM_GET_INFO };
- sgi.formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
- XrSystemId system_id;
- if (xrGetSystem(xr->instance, &sgi, &system_id) != XR_SUCCESS) {
- wlr_log(WLR_ERROR, "xrGetSystem failed");
- return false;
- }
-
- PFN_xrGetOpenGLGraphicsRequirementsKHR get_reqs;
- xrGetInstanceProcAddr(xr->instance, "xrGetOpenGLGraphicsRequirementsKHR",
- reinterpret_cast(&get_reqs));
- XrGraphicsRequirementsOpenGLKHR gl_reqs {
- XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR
- };
- get_reqs(xr->instance, system_id, &gl_reqs);
-
- Display* dpy = XOpenDisplay(nullptr);
- if (!dpy) {
- wlr_log(WLR_ERROR, "Failed to open X display");
- return false;
- }
- int screen = DefaultScreen(dpy);
- static int vis_attrs[] = { GLX_X_RENDERABLE, True, GLX_DRAWABLE_TYPE,
- GLX_WINDOW_BIT, GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_X_VISUAL_TYPE,
- GLX_TRUE_COLOR, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8,
- GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, True, None };
- int fbcount;
- GLXFBConfig* fbcs = glXChooseFBConfig(dpy, screen, vis_attrs, &fbcount);
- if (!fbcs || !fbcount) {
- wlr_log(WLR_ERROR, "No GLXFBConfig found");
- return false;
- }
- GLXFBConfig fbc = fbcs[0];
- XFree(fbcs);
-
- XVisualInfo* vi = glXGetVisualFromFBConfig(dpy, fbc);
- Window root = RootWindow(dpy, screen);
- XSetWindowAttributes swa;
- swa.colormap = XCreateColormap(dpy, root, vi->visual, AllocNone);
- swa.event_mask = ExposureMask;
- Window win = XCreateWindow(dpy, root, 0, 0, 16, 16, 0, vi->depth,
- InputOutput, vi->visual, CWColormap | CWEventMask, &swa);
- GLXContext ctx
- = glXCreateNewContext(dpy, fbc, GLX_RGBA_TYPE, nullptr, True);
- glXMakeContextCurrent(dpy, win, win, ctx);
-
- XrGraphicsBindingOpenGLXlibKHR bind {
- XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR
- };
- bind.xDisplay = dpy;
- bind.visualid = vi->visualid;
- bind.glxFBConfig = fbc;
- bind.glxDrawable = win;
- bind.glxContext = ctx;
-
- XrSessionCreateInfo sci { XR_TYPE_SESSION_CREATE_INFO };
- sci.next = &bind;
- sci.systemId = system_id;
- if (xrCreateSession(xr->instance, &sci, &xr->session) != XR_SUCCESS) {
- wlr_log(WLR_ERROR, "xrCreateSession failed");
- return false;
- }
- // Create reference space
- XrReferenceSpaceCreateInfo spaceInfo {
- XR_TYPE_REFERENCE_SPACE_CREATE_INFO
- };
- spaceInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_LOCAL;
- spaceInfo.poseInReferenceSpace = { { 0, 0, 0, 1 }, { 0, 0, 0 } };
- if (xrCreateReferenceSpace(xr->session, &spaceInfo, &xr->app_space)
- != XR_SUCCESS) {
- wlr_log(WLR_ERROR, "xrCreateReferenceSpace failed");
- return false;
- }
- // Get recommended view configuration
- uint32_t viewCount;
- xrEnumerateViewConfigurationViews(xr->instance, system_id,
- XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO, 0, &viewCount, nullptr);
- std::vector viewConfigs(
- viewCount, { XR_TYPE_VIEW_CONFIGURATION_VIEW });
- xrEnumerateViewConfigurationViews(xr->instance, system_id,
- XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO, viewCount, &viewCount,
- viewConfigs.data());
- xr->width = viewConfigs[0].recommendedImageRectWidth;
- xr->height = viewConfigs[0].recommendedImageRectHeight;
- // Create swapchain
- uint32_t formatCount;
- xrEnumerateSwapchainFormats(xr->session, 0, &formatCount, nullptr);
- std::vector formats(formatCount);
- xrEnumerateSwapchainFormats(
- xr->session, formatCount, &formatCount, formats.data());
- int64_t swapFormat = formats.empty() ? 0 : formats[0];
- XrSwapchainCreateInfo swapchain_ci { XR_TYPE_SWAPCHAIN_CREATE_INFO };
- swapchain_ci.usageFlags = XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT;
- swapchain_ci.format = swapFormat;
- swapchain_ci.sampleCount = 1;
- swapchain_ci.width = xr->width;
- swapchain_ci.height = xr->height;
- swapchain_ci.faceCount = 1;
- swapchain_ci.arraySize = viewCount;
- swapchain_ci.mipCount = 1;
- if (xrCreateSwapchain(xr->session, &swapchain_ci, &xr->swapchain)
- != XR_SUCCESS) {
- wlr_log(WLR_ERROR, "xrCreateSwapchain failed");
- return false;
- }
- // Enumerate swapchain images
- uint32_t imageCount;
- xrEnumerateSwapchainImages(xr->swapchain, 0, &imageCount, nullptr);
- xr->swapchain_images.resize(
- imageCount, { XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR });
- xrEnumerateSwapchainImages(xr->swapchain, imageCount, &imageCount,
- reinterpret_cast(
- xr->swapchain_images.data()));
- // Create framebuffers for each image
- xr->framebuffers.resize(imageCount);
- for (uint32_t i = 0; i < imageCount; ++i) {
- GLuint fbo;
- glGenFramebuffers(1, &fbo);
- glBindFramebuffer(GL_FRAMEBUFFER, fbo);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D, xr->swapchain_images[i].image, 0);
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- xr->framebuffers[i] = fbo;
- }
-
- xr->output = static_cast(calloc(1, sizeof(wlr_output)));
- if (xr->output) {
- wlr_output_init(
- xr->output, &xr->base, &output_impl, xr->event_loop, nullptr);
- wlr_output_set_name(xr->output, "OpenXR");
- wlr_output_create_global(xr->output, xr->display);
- }
-
- xr->started = true;
- wlr_log(WLR_INFO, "OpenXR backend started");
- return true;
-}
-
-static void backend_destroy(wlr_backend* backend)
-{
- auto* xr = reinterpret_cast(backend);
- // destroy swapchain and framebuffers
- if (xr->swapchain) {
- xrDestroySwapchain(xr->swapchain);
- xr->swapchain = XR_NULL_HANDLE;
- }
- for (auto fbo : xr->framebuffers) {
- glDeleteFramebuffers(1, &fbo);
- }
- // destroy reference space
- if (xr->app_space) {
- xrDestroySpace(xr->app_space);
- xr->app_space = XR_NULL_HANDLE;
- }
- // destroy XR session and instance
- if (xr->session) {
- xrDestroySession(xr->session);
- }
- if (xr->instance) {
- xrDestroyInstance(xr->instance);
- }
- free(xr);
-}
-
-static int backend_get_drm_fd(wlr_backend* backend)
-{
- (void)backend;
- return -1;
-}
-
-static wlr_backend_impl const backend_impl = {
- .start = backend_start,
- .destroy = backend_destroy,
- .get_drm_fd = backend_get_drm_fd,
-};
-
-wlr_backend* wlr_openxr_backend_create(wl_display* display, wl_event_loop* loop)
-{
- openxr_backend* b = static_cast(calloc(1, sizeof(*b)));
-
- if (!b)
- return nullptr;
- b->display = display;
- b->event_loop = loop;
- wlr_backend_init(&b->base, &backend_impl);
- return &b->base;
-}
-
-bool wlr_backend_is_openxr(wlr_backend* backend)
-{
- return backend->impl == &backend_impl;
-}
diff --git a/src/wlr/openxr_gl.h b/src/wlr/openxr_gl.h
deleted file mode 100644
index 754386a..0000000
--- a/src/wlr/openxr_gl.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct wlr_backend;
-struct wl_display;
-struct wl_event_loop;
-
-struct wlr_backend* wlr_openxr_backend_create(
- struct wl_display* display, struct wl_event_loop* loop);
-
-bool wlr_backend_is_openxr(struct wlr_backend* backend);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/src/wlr/output.cpp b/src/wlr/output.cpp
deleted file mode 100644
index bed5a0c..0000000
--- a/src/wlr/output.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-extern "C" {
-#include
-#include
-#include
-}
-
-extern "C" {
-
-static void parse_setup(struct wlr_output* output)
-{
- (void)output;
- // TODO: parse your backend’s setup (e.g. native display info)
-}
-
-static bool output_set_custom_mode(struct wlr_output* wlr_output, int32_t width,
- int32_t height, int32_t refresh)
-{
- (void)wlr_output;
- (void)width;
- (void)height;
- (void)refresh;
- // Intentionally left blank
- return true;
-}
-
-static void output_destroy(struct wlr_output* wlr_output) { (void)wlr_output; }
-
-static bool output_test(
- struct wlr_output* wlr_output, const struct wlr_output_state* state)
-{
- (void)wlr_output;
- (void)state;
- // TODO: check if this state is supported
- return true;
-}
-
-static bool output_commit(
- struct wlr_output* wlr_output, const struct wlr_output_state* state)
-{
- (void)wlr_output;
- (void)state;
- // TODO: apply enable/disable, mode, buffer, etc.
- return true;
-}
-
-static bool output_set_cursor(struct wlr_output* wlr_output,
- struct wlr_buffer* buffer, int32_t hotspot_x, int32_t hotspot_y)
-{
- (void)wlr_output;
- (void)buffer;
- (void)hotspot_x;
- (void)hotspot_y;
- // TODO: upload cursor image
- return false;
-}
-
-static bool output_move_cursor(struct wlr_output* wlr_output, int x, int y)
-{
- (void)wlr_output;
- (void)x;
- (void)y;
- // TODO: move cursor to x, y
- return true;
-}
-
-static const struct wlr_drm_format_set* output_get_primary_formats(
- struct wlr_output* wlr_output, uint32_t buffer_caps)
-{
- (void)wlr_output;
- (void)buffer_caps;
- // TODO: return DRM/SHM formats your backend supports
- return NULL;
-}
-
-static const struct wlr_output_impl output_impl = {
- .set_cursor = output_set_cursor,
- .move_cursor = output_move_cursor,
- .destroy = output_destroy,
- .test = output_test,
- .commit = output_commit,
- .get_primary_formats = output_get_primary_formats,
-};
-
-struct wlr_output* wlr_my_output_create(struct wlr_backend* backend)
-{
- (void)backend;
- // TODO: alloc + init your output struct and call
- // wlr_output_init(&output->base, backend, &output_impl, …)
- return NULL;
-}
-}
diff --git a/tools/clang-format.sh b/tools/clang-format.sh
deleted file mode 100755
index 33e87d3..0000000
--- a/tools/clang-format.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-cd $(dirname $0)/.. || exit 1
-find src '(' -name '*.c' -o -name '*.h' -o -name '*.cpp' -o -name '*.hpp' ')' -print0 | xargs -0 clang-format -i
-
-echo 'Formatted source files in src/'
\ No newline at end of file
diff --git a/tools/tokei.sh b/tools/tokei.sh
deleted file mode 100755
index e845393..0000000
--- a/tools/tokei.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-cd $(dirname $0)/.. || exit 1
-tokei src
-
-exit 0
\ No newline at end of file
diff --git a/wlroots b/wlroots
deleted file mode 160000
index 8c7041c..0000000
--- a/wlroots
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 8c7041c4e842c9fb029a6371eb53f73aa98e7b31