Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions plugins/Window/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
add_subdirectory(GLFW)
add_subdirectory(Win32)
add_subdirectory(X11)
43 changes: 43 additions & 0 deletions plugins/Window/Win32/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
project(cae-window-win32
DESCRIPTION "CAE Win32 Window Plugin"
LANGUAGES C CXX
)

if (NOT WIN32)
message(WARNING "${PROJECT_NAME} can only be build on windows")
return()
endif ()

add_compile_definitions(UNICODE _UNICODE)

find_library(USER32_LIB user32)
find_library(GDI32_LIB gdi32)

if(NOT USER32_LIB)
set(USER32_LIB "user32")
endif()
if(NOT GDI32_LIB)
set(GDI32_LIB "gdi32")
endif()


file(GLOB_RECURSE SOURCE "${PROJECT_SOURCE_DIR}/src/*.cpp")
file(GLOB_RECURSE HEADERS "${PROJECT_SOURCE_DIR}/include/*.hpp")

add_library(${PROJECT_NAME} SHARED
${SOURCE}
${HEADERS}
)

target_include_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/include")
target_compile_options(${PROJECT_NAME} PRIVATE ${WARNING_FLAGS})
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23)
target_link_libraries(${PROJECT_NAME} PRIVATE
cae-modules
${USER32_LIB}
${GDI32_LIB}
)
set_target_properties(${PROJECT_NAME} PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${PLUGIN_DIR}"
RUNTIME_OUTPUT_DIRECTORY "${PLUGIN_DIR}"
)
62 changes: 62 additions & 0 deletions plugins/Window/Win32/include/Win32/Win32.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
///
/// @file Win32.hpp
/// @brief This file contains the Win32 class declaration
/// @namespace cae
///

#pragma once

#include <windows.h>

#include "Interfaces/IWindow.hpp"

namespace cae
{

///
/// @class Win32
/// @brief Class for the Win32 plugin
/// @namespace cae
///
class Win32 final : public IWindow
{

public:
Win32() = default;
~Win32() override = default;

Win32(const Win32 &) = delete;
Win32 &operator=(const Win32 &) = delete;
Win32(Win32 &&) = delete;
Win32 &operator=(Win32 &&) = delete;

[[nodiscard]] std::string getName() const override { return "Win32"; }
[[nodiscard]] utl::PluginType getType() const override { return utl::PluginType::WINDOW; }
[[nodiscard]] utl::PluginPlatform getPlatform() const override { return utl::PluginPlatform::WINDOWS; }

bool create(const std::string &name, WindowSize size) override;
void close() override;

[[nodiscard]] NativeWindowHandle getNativeHandle() const override;
[[nodiscard]] WindowSize getWindowSize() const override;

[[nodiscard]] bool setIcon(const std::string &path) const override;

[[nodiscard]] bool shouldClose() const override { return m_shouldClose; }
void pollEvents() override;

bool wasResized() const override { return m_frameBufferResized; }
void resetResizedFlag() override { m_frameBufferResized = false; }

private:
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);

std::wstring m_title;
HWND m_hwnd = nullptr;
HINSTANCE m_hInstance = nullptr;
WindowSize m_frameBufferSize;
bool m_frameBufferResized = false;
bool m_shouldClose = false;

}; // class Win32
} // namespace cae
8 changes: 8 additions & 0 deletions plugins/Window/Win32/src/entrypoint.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include <memory>

#include "Win32/Win32.hpp"

extern "C"
{
PLUGIN_EXPORT cae::IWindow *entryPoint() { return std::make_unique<cae::Win32>().release(); }
}
125 changes: 125 additions & 0 deletions plugins/Window/Win32/src/win32.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#include <string>

#include "Utils/Logger.hpp"

#include "Win32/Win32.hpp"

constexpr wchar_t WINDOW_CLASS_NAME[] = L"CAE_WindowsWindowClass";

LRESULT CALLBACK cae::Win32::WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
Win32 *self = nullptr;

if (msg == WM_NCCREATE)
{
auto *cs = reinterpret_cast<CREATESTRUCTW *>(lParam);
self = static_cast<Win32 *>(cs->lpCreateParams);
SetWindowLongPtrW(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(self));
return TRUE;
}

self = reinterpret_cast<Win32 *>(GetWindowLongPtrW(hwnd, GWLP_USERDATA));

switch (msg)
{
case WM_SIZE:
if (self != nullptr)
{
self->m_frameBufferResized = true;
self->m_frameBufferSize = {.width=LOWORD(lParam), .height=HIWORD(lParam)};
}
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
}

bool cae::Win32::create(const std::string &name, WindowSize size)
{
m_hInstance = GetModuleHandleW(nullptr);
m_frameBufferSize = size;
m_shouldClose = false;
m_frameBufferResized = false;

const int len = MultiByteToWideChar(CP_UTF8, 0, name.c_str(), -1, nullptr, 0);

m_title.resize(len);

MultiByteToWideChar(CP_UTF8, 0, name.c_str(), -1, m_title.data(), len);

if (!m_title.empty() && m_title.back() == L'\0')
{
m_title.pop_back();
}

static bool classRegistered = false;
if (!classRegistered)
{
WNDCLASSW wc{};
wc.lpfnWndProc = WindowProc;
wc.hInstance = m_hInstance;
wc.lpszClassName = WINDOW_CLASS_NAME;
wc.hCursor = LoadCursorW(nullptr, IDC_ARROW);
wc.hIcon = LoadIconW(nullptr, IDI_APPLICATION);
wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1);

if (RegisterClassW(&wc) == 0U)
{
utl::Logger::log("Failed to register Win32 window class", utl::LogLevel::WARNING);
return false;
}
classRegistered = true;
}
m_hwnd = CreateWindowExW(0, WINDOW_CLASS_NAME, L"TEST TITLE VISIBLE", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
CW_USEDEFAULT, size.width, size.height, nullptr, nullptr, m_hInstance, this);

if (m_hwnd == nullptr) {
return false;
}

SetWindowTextW(m_hwnd, m_title.c_str());

ShowWindow(m_hwnd, SW_SHOW);
UpdateWindow(m_hwnd);
return true;
}

void cae::Win32::close()
{
if (m_hwnd != nullptr)
{
DestroyWindow(m_hwnd);
m_hwnd = nullptr;
}
UnregisterClassW(WINDOW_CLASS_NAME, m_hInstance);
}

cae::NativeWindowHandle cae::Win32::getNativeHandle() const { return {.window = m_hwnd, .display = m_hInstance}; }

cae::WindowSize cae::Win32::getWindowSize() const
{
RECT rect{};
GetClientRect(m_hwnd, &rect);
return {.width = static_cast<uint16_t>(rect.right - rect.left),
.height = static_cast<uint16_t>(rect.bottom - rect.top)};
}

bool cae::Win32::setIcon(const std::string &path) const { return false; }

void cae::Win32::pollEvents()
{
MSG msg{};
while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
m_shouldClose = true;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
2 changes: 1 addition & 1 deletion src/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ cae::Application::Application(const ArgsConfig &argsConfig, const EnvConfig &env
{
m_appConfig.engineConfig = parseEngineConf(argsConfig.config_path);
}
setupEngine("OpenGL", "X11", "GLSL", "SPIRV");
setupEngine("OpenGL", "GLFW", "GLSL", "SPIRV");
}
catch (const std::exception &e)
{
Expand Down
Loading