@@ -5,11 +5,11 @@ ColumnLimit: 80
|
|||||||
|
|
||||||
AlignEscapedNewlines: DontAlign
|
AlignEscapedNewlines: DontAlign
|
||||||
AlignTrailingComments:
|
AlignTrailingComments:
|
||||||
Kind: Always
|
Kind: Always
|
||||||
OverEmptyLines: 0
|
OverEmptyLines: 0
|
||||||
BasedOnStyle: WebKit
|
BasedOnStyle: WebKit
|
||||||
BraceWrapping:
|
BraceWrapping:
|
||||||
AfterFunction: true
|
AfterFunction: true
|
||||||
BreakBeforeBraces: Custom
|
BreakBeforeBraces: Custom
|
||||||
BreakBeforeInheritanceComma: true
|
BreakBeforeInheritanceComma: true
|
||||||
BreakConstructorInitializers: BeforeComma
|
BreakConstructorInitializers: BeforeComma
|
||||||
@@ -18,8 +18,8 @@ IndentRequiresClause: false
|
|||||||
InsertNewlineAtEOF: true
|
InsertNewlineAtEOF: true
|
||||||
LineEnding: LF
|
LineEnding: LF
|
||||||
NamespaceIndentation: None
|
NamespaceIndentation: None
|
||||||
PointerAlignment: Right # east pointer
|
PointerAlignment: Right # east pointer
|
||||||
QualifierAlignment: Right # east const
|
QualifierAlignment: Right # east const
|
||||||
RemoveSemicolon: true
|
RemoveSemicolon: true
|
||||||
RequiresClausePosition: WithFollowing
|
RequiresClausePosition: WithFollowing
|
||||||
RequiresExpressionIndentation: OuterScope
|
RequiresExpressionIndentation: OuterScope
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ pkg_check_modules(WAYLAND REQUIRED IMPORTED_TARGET GLOBAL wayland-server)
|
|||||||
pkg_check_modules(EGL REQUIRED IMPORTED_TARGET egl)
|
pkg_check_modules(EGL REQUIRED IMPORTED_TARGET egl)
|
||||||
pkg_check_modules(GLES2 REQUIRED IMPORTED_TARGET glesv2)
|
pkg_check_modules(GLES2 REQUIRED IMPORTED_TARGET glesv2)
|
||||||
pkg_check_modules(WLROOTS REQUIRED IMPORTED_TARGET wlroots-0.19)
|
pkg_check_modules(WLROOTS REQUIRED IMPORTED_TARGET wlroots-0.19)
|
||||||
|
pkg_check_modules(XKBCOMMON REQUIRED IMPORTED_TARGET xkbcommon)
|
||||||
pkg_check_modules(OPENXR REQUIRED IMPORTED_TARGET openxr)
|
pkg_check_modules(OPENXR REQUIRED IMPORTED_TARGET openxr)
|
||||||
|
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
@@ -45,6 +46,7 @@ target_sources(${PROJECT_NAME} PUBLIC FILE_SET CXX_MODULES FILES
|
|||||||
src/LunarWM.cppm
|
src/LunarWM.cppm
|
||||||
)
|
)
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC
|
target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||||
|
PkgConfig::XKBCOMMON
|
||||||
PkgConfig::WAYLAND
|
PkgConfig::WAYLAND
|
||||||
PkgConfig::EGL
|
PkgConfig::EGL
|
||||||
PkgConfig::GLES2
|
PkgConfig::GLES2
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
# For wlroots
|
# For wlroots
|
||||||
libxkbcommon
|
libxkbcommon
|
||||||
|
libxkbcommon.dev
|
||||||
libdrm
|
libdrm
|
||||||
xorg.libxcb
|
xorg.libxcb
|
||||||
pixman
|
pixman
|
||||||
|
|||||||
3029
src/LunarWM.cppm
3029
src/LunarWM.cppm
File diff suppressed because it is too large
Load Diff
328
src/Math.cppm
328
src/Math.cppm
@@ -7,195 +7,205 @@ export module LunarWM.Math;
|
|||||||
export namespace LunarWM {
|
export namespace LunarWM {
|
||||||
namespace Math {
|
namespace Math {
|
||||||
|
|
||||||
template <typename T = float>
|
template<typename T = float>
|
||||||
requires std::is_arithmetic_v<T>
|
requires std::is_arithmetic_v<T> struct Vec2 {
|
||||||
struct Vec2 {
|
template<typename U = T>
|
||||||
template <typename U = T>
|
requires std::is_arithmetic_v<U> Vec2<U> operator+(Vec2<U> const &other)
|
||||||
requires std::is_arithmetic_v<U>
|
{
|
||||||
Vec2<U> operator+(Vec2<U> const &other) {
|
return { x + other.x, y + other.y };
|
||||||
return {x + other.x, y + other.y};
|
}
|
||||||
}
|
template<typename U = T>
|
||||||
template <typename U = T>
|
requires std::is_arithmetic_v<U> Vec2<U> operator-(Vec2<U> const &other)
|
||||||
requires std::is_arithmetic_v<U>
|
{
|
||||||
Vec2<U> operator-(Vec2<U> const &other) {
|
return { x - other.x, y - other.y };
|
||||||
return {x - other.x, y - other.y};
|
}
|
||||||
}
|
template<typename U = T>
|
||||||
template <typename U = T>
|
requires std::is_arithmetic_v<U> Vec2<U> operator*(Vec2<U> const &other)
|
||||||
requires std::is_arithmetic_v<U>
|
{
|
||||||
Vec2<U> operator*(Vec2<U> const &other) {
|
return { x * other.x, y * other.x };
|
||||||
return {x * other.x, y * other.x};
|
}
|
||||||
}
|
template<typename U = T>
|
||||||
template <typename U = T>
|
requires std::is_arithmetic_v<U> Vec2<U> operator*(T scalar)
|
||||||
requires std::is_arithmetic_v<U>
|
{
|
||||||
Vec2<U> operator*(T scalar) {
|
return { x * scalar, y * scalar };
|
||||||
return {x * scalar, y * scalar};
|
}
|
||||||
}
|
template<typename U = T>
|
||||||
template <typename U = T>
|
requires std::is_arithmetic_v<U> Vec2<U> operator/(T scalar)
|
||||||
requires std::is_arithmetic_v<U>
|
{
|
||||||
Vec2<U> operator/(T scalar) {
|
return { x / scalar, y / scalar };
|
||||||
return {x / scalar, y / scalar};
|
}
|
||||||
}
|
template<typename U = T>
|
||||||
template <typename U = T>
|
requires std::is_arithmetic_v<U> Vec2 operator-()
|
||||||
requires std::is_arithmetic_v<U>
|
{
|
||||||
Vec2 operator-() {
|
return { -x, -y };
|
||||||
return {-x, -y};
|
}
|
||||||
}
|
T length() const { return std::sqrt(x * x + y * y); }
|
||||||
T length() const { return std::sqrt(x * x + y * y); }
|
T lengthSquared() const { return x * x + y * y; }
|
||||||
T lengthSquared() const { return x * x + y * y; }
|
Vec2<T> normalized() const
|
||||||
Vec2<T> normalized() const {
|
{
|
||||||
T len = length();
|
T len = length();
|
||||||
if (len == T(0))
|
if (len == T(0))
|
||||||
return {T(0), T(0)};
|
return { T(0), T(0) };
|
||||||
return *this / len;
|
return *this / len;
|
||||||
}
|
}
|
||||||
|
|
||||||
T x, y;
|
T x, y;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template<typename T>
|
||||||
requires std::is_arithmetic_v<T>
|
requires std::is_arithmetic_v<T> Vec2<T> operator*(T scalar, Vec2<T> const &v)
|
||||||
Vec2<T> operator*(T scalar, Vec2<T> const &v) {
|
{
|
||||||
return {v.x * scalar, v.y * scalar};
|
return { v.x * scalar, v.y * scalar };
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T = float>
|
template<typename T = float>
|
||||||
requires std::is_arithmetic_v<T>
|
requires std::is_arithmetic_v<T> struct Rect {
|
||||||
struct Rect {
|
Rect(Vec2<T> pos, Vec2<T> size)
|
||||||
Rect(Vec2<T> pos, Vec2<T> size) : pos(pos), size(size) {}
|
: pos(pos)
|
||||||
Rect(T x, T y, T w, T h) : pos({x, y}), size({w, h}) {}
|
, size(size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
Rect(T x, T y, T w, T h)
|
||||||
|
: pos({ x, y })
|
||||||
|
, size({ w, h })
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
T &x() { return pos.x; }
|
T &x() { return pos.x; }
|
||||||
T &y() { return pos.y; }
|
T &y() { return pos.y; }
|
||||||
T &w() { return size.x; }
|
T &w() { return size.x; }
|
||||||
T &h() { return size.y; }
|
T &h() { return size.y; }
|
||||||
|
|
||||||
T x() const { return pos.x; }
|
T x() const { return pos.x; }
|
||||||
T y() const { return pos.y; }
|
T y() const { return pos.y; }
|
||||||
T w() const { return size.x; }
|
T w() const { return size.x; }
|
||||||
T h() const { return size.y; }
|
T h() const { return size.y; }
|
||||||
|
|
||||||
T left() const { return x(); }
|
T left() const { return x(); }
|
||||||
T right() const { return x() + w(); }
|
T right() const { return x() + w(); }
|
||||||
T top() const { return y(); }
|
T top() const { return y(); }
|
||||||
T bottom() const { return y() + h(); }
|
T bottom() const { return y() + h(); }
|
||||||
|
|
||||||
T &left() { return x(); }
|
T &left() { return x(); }
|
||||||
T &top() { return y(); }
|
T &top() { return y(); }
|
||||||
|
|
||||||
Vec2<T> pos, size;
|
Vec2<T> pos, size;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T = float>
|
template<typename T = float>
|
||||||
requires std::is_arithmetic_v<T>
|
requires std::is_arithmetic_v<T> struct Box {
|
||||||
struct Box {
|
template<typename U = int>
|
||||||
template <typename U = int>
|
requires std::is_arithmetic_v<U> Vec2<T> &operator[](U const index)
|
||||||
requires std::is_arithmetic_v<U>
|
{
|
||||||
Vec2<T> &operator[](U const index) {
|
if (index < 0 || index > 1)
|
||||||
if (index < 0 || index > 1)
|
throw std::out_of_range("A box only has two points");
|
||||||
throw std::out_of_range("A box only has two points");
|
return m_data[index];
|
||||||
return m_data[index];
|
}
|
||||||
}
|
Vec2<T> &first() { return m_data[0]; }
|
||||||
Vec2<T> &first() { return m_data[0]; }
|
Vec2<T> &second() { return m_data[1]; }
|
||||||
Vec2<T> &second() { return m_data[1]; }
|
T &x0() { return m_data[0].x; }
|
||||||
T &x0() { return m_data[0].x; }
|
T &y0() { return m_data[0].y; }
|
||||||
T &y0() { return m_data[0].y; }
|
T &x1() { return m_data[1].x; }
|
||||||
T &x1() { return m_data[1].x; }
|
T &y1() { return m_data[1].y; }
|
||||||
T &y1() { return m_data[1].y; }
|
T &left()
|
||||||
T &left() {
|
{
|
||||||
if (x0() < x1())
|
if (x0() < x1())
|
||||||
return x0();
|
return x0();
|
||||||
return x1();
|
return x1();
|
||||||
}
|
}
|
||||||
T &right() {
|
T &right()
|
||||||
if (x0() > x1())
|
{
|
||||||
return x0();
|
if (x0() > x1())
|
||||||
return x1();
|
return x0();
|
||||||
}
|
return x1();
|
||||||
T &top() {
|
}
|
||||||
if (y0() < y1())
|
T &top()
|
||||||
return y0();
|
{
|
||||||
return y1();
|
if (y0() < y1())
|
||||||
}
|
return y0();
|
||||||
T &bottom() {
|
return y1();
|
||||||
if (y0() > y1())
|
}
|
||||||
return y0();
|
T &bottom()
|
||||||
return y1();
|
{
|
||||||
}
|
if (y0() > y1())
|
||||||
|
return y0();
|
||||||
|
return y1();
|
||||||
|
}
|
||||||
|
|
||||||
Box() {}
|
Box() { }
|
||||||
Box(Rect<T> rect) {
|
Box(Rect<T> rect)
|
||||||
this->m_data[0] = rect.pos;
|
{
|
||||||
this->m_data[1] = rect.pos + rect.size;
|
this->m_data[0] = rect.pos;
|
||||||
}
|
this->m_data[1] = rect.pos + rect.size;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vec2<T> m_data[2] = {};
|
Vec2<T> m_data[2] = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T = int>
|
template<typename T = int>
|
||||||
requires std::is_arithmetic_v<T>
|
requires std::is_arithmetic_v<T> std::vector<Math::Rect<T>> subtract_rect(
|
||||||
std::vector<Math::Rect<T>> subtract_rect(Math::Rect<T> const &src,
|
Math::Rect<T> const &src, Math::Rect<T> const &clip)
|
||||||
Math::Rect<T> const &clip) {
|
{
|
||||||
std::vector<Math::Rect<T>> result;
|
std::vector<Math::Rect<T>> result;
|
||||||
|
|
||||||
auto sx = src.x();
|
auto sx = src.x();
|
||||||
auto sy = src.y();
|
auto sy = src.y();
|
||||||
auto sw = src.w();
|
auto sw = src.w();
|
||||||
auto sh = src.h();
|
auto sh = src.h();
|
||||||
|
|
||||||
auto cx = clip.x();
|
auto cx = clip.x();
|
||||||
auto cy = clip.y();
|
auto cy = clip.y();
|
||||||
auto cw = clip.w();
|
auto cw = clip.w();
|
||||||
auto ch = clip.h();
|
auto ch = clip.h();
|
||||||
|
|
||||||
T s_right = sx + sw;
|
T s_right = sx + sw;
|
||||||
T s_bottom = sy + sh;
|
T s_bottom = sy + sh;
|
||||||
|
|
||||||
T c_right = cx + cw;
|
T c_right = cx + cw;
|
||||||
T c_bottom = cy + ch;
|
T c_bottom = cy + ch;
|
||||||
|
|
||||||
// No overlap → keep src
|
// No overlap → keep src
|
||||||
if (c_right <= sx || cx >= s_right || c_bottom <= sy || cy >= s_bottom) {
|
if (c_right <= sx || cx >= s_right || c_bottom <= sy || cy >= s_bottom) {
|
||||||
result.push_back(src);
|
result.push_back(src);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Top piece
|
// Top piece
|
||||||
if (cy > sy) {
|
if (cy > sy) {
|
||||||
result.emplace_back(sx, sy, sw, cy - sy);
|
result.emplace_back(sx, sy, sw, cy - sy);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bottom piece
|
// Bottom piece
|
||||||
if (c_bottom < s_bottom) {
|
if (c_bottom < s_bottom) {
|
||||||
result.emplace_back(sx, c_bottom, sw, s_bottom - c_bottom);
|
result.emplace_back(sx, c_bottom, sw, s_bottom - c_bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Middle pieces left and right of clip
|
// Middle pieces left and right of clip
|
||||||
T middle_top = std::max(sy, cy);
|
T middle_top = std::max(sy, cy);
|
||||||
T middle_bottom = std::min(s_bottom, c_bottom);
|
T middle_bottom = std::min(s_bottom, c_bottom);
|
||||||
T middle_height = middle_bottom - middle_top;
|
T middle_height = middle_bottom - middle_top;
|
||||||
|
|
||||||
if (middle_height > 0) {
|
if (middle_height > 0) {
|
||||||
// Left piece
|
// Left piece
|
||||||
if (cx > sx) {
|
if (cx > sx) {
|
||||||
result.emplace_back(sx, middle_top, cx - sx, middle_height);
|
result.emplace_back(sx, middle_top, cx - sx, middle_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Right piece
|
// Right piece
|
||||||
if (c_right < s_right) {
|
if (c_right < s_right) {
|
||||||
result.emplace_back(c_right, middle_top, s_right - c_right,
|
result.emplace_back(
|
||||||
middle_height);
|
c_right, middle_top, s_right - c_right, middle_height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T = float>
|
template<typename T = float>
|
||||||
requires std::is_arithmetic_v<T>
|
requires std::is_arithmetic_v<T> struct Viewport {
|
||||||
struct Viewport {
|
Rect<T> rect;
|
||||||
Rect<T> rect;
|
Vec2<T> depth_limits;
|
||||||
Vec2<T> depth_limits;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Math
|
} // namespace Math
|
||||||
|
|||||||
8
tools/format.sh
Executable file
8
tools/format.sh
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ROOT="$(git rev-parse --show-toplevel)"
|
||||||
|
|
||||||
|
find "$ROOT/src" -type f -name '*.cppm' -print0 | while IFS= read -r -d '' f; do
|
||||||
|
clang-format -i --style=file "$f"
|
||||||
|
done
|
||||||
Reference in New Issue
Block a user