Update windows/Window.cpp
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 5m22s

On windows everything will be in the same cpp because their event loop is bad.
This commit is contained in:
2025-01-29 13:01:52 -05:00
parent d6c4c0b0f5
commit 3fd2a8ce14
3 changed files with 248 additions and 270 deletions

View File

@@ -1,140 +0,0 @@
#pragma once
#ifdef _WIN32
#include <Windows.h>
#include <ReWindow/types/Window.h>
using namespace ReWindow;
//Event loop.
// TODO move this. It can't be in the RWindow class because it has to be publicly visible.
inline LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
RWindow* window = reinterpret_cast<RWindow*>( GetWindowLongPtr(hwnd, GWLP_USERDATA) );
switch (uMsg) {
case WM_CLOSE: {
DestroyWindow(hwnd);
window->processOnClose();
}
case WM_DESTROY: {
exit(0);
}
case WM_SIZE: {
window->SetSizeWithoutEvent({ LOWORD(lParam), HIWORD(lParam) });
auto eventData = WindowResizeRequestEvent();
eventData.Size = { window->GetWidth(), window->GetHeight() };
window->SetLastKnownWindowSize({ window->GetWidth(), window->GetHeight() });
// TODO: Implement eWindow->processOnResize()
window->OnResizeRequest(eventData);
window->OnResizeRequestEvent(eventData);
break;
}
case WM_SETFOCUS: {
window->processFocusIn();
window->SetFlag(WindowFlag::IN_FOCUS, true);
// TODO actually check if it's flashing.
FLASHWINFO fi;
fi.cbSize = sizeof(FLASHWINFO);
fi.hwnd = hwnd;
fi.dwFlags = FLASHW_STOP;
fi.uCount = 0;
fi.dwTimeout = 0;
FlashWindowEx(&fi);
break;
}
case WM_KILLFOCUS: {
window->processFocusOut();
window->SetFlag(WindowFlag::IN_FOCUS, false);
}
case WM_SETCURSOR: {
if (LOWORD(lParam) == HTCLIENT && window->GetCursorVisible() == false)
SetCursor(nullptr);
break;
}
case WM_KEYDOWN: {
auto key = GetKeyFromWindowsScancode((WindowsScancode) wParam);
//Key repeat fix.
if (!window->previousKeyboard.PressedKeys[key])
window->processKeyPress(key);
break;
}
case WM_KEYUP: {
auto key = GetKeyFromWindowsScancode((WindowsScancode) wParam);
window->processKeyRelease(key);
break;
}
//Mouse Buttons.
case WM_MOUSEWHEEL: {
int wheel_delta = GET_WHEEL_DELTA_WPARAM(wParam);
// TODO: Determine sign of wheel_delta for each direction, (and on linux too), and document this.
window->processMouseWheel(wheel_delta);\
break;
}
case WM_LBUTTONDOWN: {
window->processMousePress(MouseButtons::Left);
break;
}
case WM_LBUTTONUP: {
window->processMouseRelease(MouseButtons::Left);
break;
}
case WM_RBUTTONDOWN: {
window->processMousePress(MouseButtons::Right);
break;
}
case WM_RBUTTONUP: {
window->processMouseRelease(MouseButtons::Right);
break;
}
case WM_MBUTTONDOWN: {
window->processMousePress(MouseButtons::Middle);
break;
}
case WM_MBUTTONUP: {
window->processMouseRelease(MouseButtons::Middle);
break;
}
case WM_XBUTTONDOWN: {
WORD button = GET_XBUTTON_WPARAM(wParam);
if (button == XBUTTON1)
window->processMousePress(MouseButtons::Mouse4);
if (button == XBUTTON2)
window->processMousePress(MouseButtons::Mouse5);
break;
}
case WM_XBUTTONUP: {
WORD button = GET_XBUTTON_WPARAM(wParam);
if (button == XBUTTON1)
window->processMouseRelease(MouseButtons::Mouse4);
if (button == XBUTTON2)
window->processMouseRelease(MouseButtons::Mouse5);
break;
}
//This is the same as "Motion Notify" in the X Window System.
case WM_MOUSEMOVE:
break;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
#endif

View File

@@ -1,128 +0,0 @@
#include <ReWindow/types/Window.h>
#include <ReWindow/data/WindowsEventLoop.h>
#include <ReWindow/Logger.h>
#include <GL/gl.h>
class RWindow::Platform {
public:
HINSTANCE hInstance;
HWND hwnd;
HDC hdc;
};
using namespace ReWindow;
HGLRC glContext;
HMODULE gl_lib = nullptr;
bool constructor_success = true;
namespace OpenGL {
typedef const GLubyte* (APIENTRY *GLGETSTRINGPROC)(GLenum name);
GLGETSTRINGPROC glGetString = nullptr;
typedef BOOL (WINAPI *WGLMAKECURRENTPROC)(HDC hdc, HGLRC hglrc);
WGLMAKECURRENTPROC wglMakeCurrent = nullptr;
typedef FARPROC (WINAPI *WGLGETPROCADDRPROC)(LPCSTR lpszProc);
WGLGETPROCADDRPROC wglGetProcAddress = nullptr;
typedef HGLRC (WINAPI *WGLCREATECONTEXTPROC)(HDC hdc);
WGLCREATECONTEXTPROC wglCreateContext = nullptr;
}
bool OpenGLWindow::Open() {
if (!constructor_success)
return false;
platform->hInstance = GetModuleHandle(nullptr);
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = platform->hInstance;
wc.lpszClassName = "RWindowClass";
RegisterClass(&wc);
platform->hwnd = CreateWindowEx(
0,
"RWindowClass",
title.c_str(),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, width, height,
nullptr,
nullptr,
platform->hInstance,
nullptr
);
SetWindowLongPtr(platform->hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24,
8,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
platform->hdc = GetDC(platform->hwnd);
int pixelFormat = ChoosePixelFormat(platform->hdc, &pfd);
SetPixelFormat(platform->hdc, pixelFormat, &pfd);
glContext = OpenGL::wglCreateContext(platform->hdc);
OpenGL::wglMakeCurrent(platform->hdc, glContext);
ShowWindow(platform->hwnd, SW_SHOW);
open = true;
return true;
}
std::string OpenGLWindow::GetGraphicsDriverVendor() {
return std::string(reinterpret_cast<const char*>(OpenGL::glGetString(GL_VENDOR)));
}
void OpenGLWindow::SwapBuffers() {
::SwapBuffers(platform->hdc);
}
void OpenGLWindow::SetVsyncEnabled(bool b) {
typedef BOOL(WINAPI* PFNWGLSWAPINTERVALEXTPROC)(int interval);
auto wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) OpenGL::wglGetProcAddress("wglSwapIntervalEXT");
if (wglSwapIntervalEXT)
wglSwapIntervalEXT(b ? 1 : 0);
}
bool OpenGLWindow::SoftwareRendered() {
std::string renderer(reinterpret_cast<const char*>(OpenGL::glGetString(GL_RENDERER)));
if (renderer.find("llvmpipe"))
return true;
if (renderer.find("softpipe"))
return true;
if (renderer.find("GDI Generic"))
return true;
if (GetGraphicsDriverVendor().find("Mesa"))
return true;
return false;
}
OpenGLWindow::OpenGLWindow(const std::string& title, int width, int height, uint8_t gl_major, uint8_t gl_minor)
: gl_major(gl_major), gl_minor(gl_minor), RWindow(title, width, height) {
gl_lib = LoadLibrary("opengl32.dll");
if (!gl_lib)
Logger::Error("opengl32.dll couldn't be found. If you have it, you can try putting it in the same directory as the executable."),
constructor_success = false;
OpenGL::glGetString = (OpenGL::GLGETSTRINGPROC) GetProcAddress(gl_lib, "glGetString");
OpenGL::wglMakeCurrent = (OpenGL::WGLMAKECURRENTPROC) GetProcAddress(gl_lib, "wglMakeCurrent");
OpenGL::wglGetProcAddress = (OpenGL::WGLGETPROCADDRPROC) GetProcAddress(gl_lib, "wglGetProcAddress");
OpenGL::wglCreateContext = (OpenGL::WGLCREATECONTEXTPROC) GetProcAddress(gl_lib, "wglCreateContext");
}

View File

@@ -1,6 +1,8 @@
#include <Windows.h>
#include <gl/GL.h>
#include <rewindow/types/window.h>
#include <ReWindow/types/Window.h>
#include <ReWindow/Logger.h>
class ReWindow::RWindow::Platform {
public:
@@ -10,6 +12,135 @@ public:
};
using namespace ReWindow;
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
auto* window = reinterpret_cast<RWindow*>( GetWindowLongPtr(hwnd, GWLP_USERDATA) );
switch (uMsg) {
case WM_CLOSE: {
DestroyWindow(hwnd);
window->processOnClose();
}
case WM_DESTROY: {
exit(0);
}
case WM_SIZE: {
window->SetSizeWithoutEvent({ LOWORD(lParam), HIWORD(lParam) });
auto eventData = WindowResizeRequestEvent();
eventData.Size = { window->GetWidth(), window->GetHeight() };
window->SetLastKnownWindowSize({ window->GetWidth(), window->GetHeight() });
// TODO: Implement eWindow->processOnResize()
window->OnResizeRequest(eventData);
window->OnResizeRequestEvent(eventData);
break;
}
case WM_SETFOCUS: {
window->processFocusIn();
window->SetFlag(WindowFlag::IN_FOCUS, true);
// TODO actually check if it's flashing.
FLASHWINFO fi;
fi.cbSize = sizeof(FLASHWINFO);
fi.hwnd = hwnd;
fi.dwFlags = FLASHW_STOP;
fi.uCount = 0;
fi.dwTimeout = 0;
FlashWindowEx(&fi);
break;
}
case WM_KILLFOCUS: {
window->processFocusOut();
window->SetFlag(WindowFlag::IN_FOCUS, false);
}
case WM_SETCURSOR: {
if (LOWORD(lParam) == HTCLIENT && window->GetCursorVisible() == false)
SetCursor(nullptr);
break;
}
case WM_KEYDOWN: {
auto key = GetKeyFromWindowsScancode((WindowsScancode) wParam);
//Key repeat fix.
if (!window->previousKeyboard.PressedKeys[key])
window->processKeyPress(key);
break;
}
case WM_KEYUP: {
auto key = GetKeyFromWindowsScancode((WindowsScancode) wParam);
window->processKeyRelease(key);
break;
}
//Mouse Buttons.
case WM_MOUSEWHEEL: {
int wheel_delta = GET_WHEEL_DELTA_WPARAM(wParam);
// TODO: Determine sign of wheel_delta for each direction, (and on linux too), and document this.
window->processMouseWheel(wheel_delta);\
break;
}
case WM_LBUTTONDOWN: {
window->processMousePress(MouseButtons::Left);
break;
}
case WM_LBUTTONUP: {
window->processMouseRelease(MouseButtons::Left);
break;
}
case WM_RBUTTONDOWN: {
window->processMousePress(MouseButtons::Right);
break;
}
case WM_RBUTTONUP: {
window->processMouseRelease(MouseButtons::Right);
break;
}
case WM_MBUTTONDOWN: {
window->processMousePress(MouseButtons::Middle);
break;
}
case WM_MBUTTONUP: {
window->processMouseRelease(MouseButtons::Middle);
break;
}
case WM_XBUTTONDOWN: {
WORD button = GET_XBUTTON_WPARAM(wParam);
if (button == XBUTTON1)
window->processMousePress(MouseButtons::Mouse4);
if (button == XBUTTON2)
window->processMousePress(MouseButtons::Mouse5);
break;
}
case WM_XBUTTONUP: {
WORD button = GET_XBUTTON_WPARAM(wParam);
if (button == XBUTTON1)
window->processMouseRelease(MouseButtons::Mouse4);
if (button == XBUTTON2)
window->processMouseRelease(MouseButtons::Mouse5);
break;
}
//This is the same as "Motion Notify" in the X Window System.
case WM_MOUSEMOVE:
break;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
bool fullscreenmode = false;
bool open = false;
@@ -124,4 +255,119 @@ vsync(wVsync), flags{false,wFullscreen,wResizable,wVsync} {
void RWindow::UniqueFunctionNameForMessageBoxBecauseMicrosoftUsesMacros(const std::string& title, const std::string& message_box_text) {
MessageBox(nullptr, message_box_text.c_str(), title.c_str(), MB_OK);
}
}
HGLRC glContext;
HMODULE gl_lib = nullptr;
bool constructor_success = true;
namespace OpenGL {
typedef const GLubyte* (APIENTRY *GLGETSTRINGPROC)(GLenum name);
GLGETSTRINGPROC glGetString = nullptr;
typedef BOOL (WINAPI *WGLMAKECURRENTPROC)(HDC hdc, HGLRC hglrc);
WGLMAKECURRENTPROC wglMakeCurrent = nullptr;
typedef FARPROC (WINAPI *WGLGETPROCADDRPROC)(LPCSTR lpszProc);
WGLGETPROCADDRPROC wglGetProcAddress = nullptr;
typedef HGLRC (WINAPI *WGLCREATECONTEXTPROC)(HDC hdc);
WGLCREATECONTEXTPROC wglCreateContext = nullptr;
}
bool OpenGLWindow::Open() {
if (!constructor_success)
return false;
platform->hInstance = GetModuleHandle(nullptr);
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = platform->hInstance;
wc.lpszClassName = "RWindowClass";
RegisterClass(&wc);
platform->hwnd = CreateWindowEx(
0,
"RWindowClass",
title.c_str(),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, width, height,
nullptr,
nullptr,
platform->hInstance,
nullptr
);
SetWindowLongPtr(platform->hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24,
8,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
platform->hdc = GetDC(platform->hwnd);
int pixelFormat = ChoosePixelFormat(platform->hdc, &pfd);
SetPixelFormat(platform->hdc, pixelFormat, &pfd);
glContext = OpenGL::wglCreateContext(platform->hdc);
OpenGL::wglMakeCurrent(platform->hdc, glContext);
ShowWindow(platform->hwnd, SW_SHOW);
open = true;
return true;
}
std::string OpenGLWindow::GetGraphicsDriverVendor() {
return std::string(reinterpret_cast<const char*>(OpenGL::glGetString(GL_VENDOR)));
}
void OpenGLWindow::SwapBuffers() {
::SwapBuffers(platform->hdc);
}
void OpenGLWindow::SetVsyncEnabled(bool b) {
typedef BOOL(WINAPI* PFNWGLSWAPINTERVALEXTPROC)(int interval);
auto wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) OpenGL::wglGetProcAddress("wglSwapIntervalEXT");
if (wglSwapIntervalEXT)
wglSwapIntervalEXT(b ? 1 : 0);
}
bool OpenGLWindow::SoftwareRendered() {
std::string renderer(reinterpret_cast<const char*>(OpenGL::glGetString(GL_RENDERER)));
if (renderer.find("llvmpipe"))
return true;
if (renderer.find("softpipe"))
return true;
if (renderer.find("GDI Generic"))
return true;
if (GetGraphicsDriverVendor().find("Mesa"))
return true;
return false;
}
OpenGLWindow::OpenGLWindow(const std::string& title, int width, int height, uint8_t gl_major, uint8_t gl_minor)
: gl_major(gl_major), gl_minor(gl_minor), RWindow(title, width, height) {
gl_lib = LoadLibrary("opengl32.dll");
if (!gl_lib)
Logger::Error("opengl32.dll couldn't be found. If you have it, you can try putting it in the same directory as the executable."),
constructor_success = false;
OpenGL::glGetString = (OpenGL::GLGETSTRINGPROC) GetProcAddress(gl_lib, "glGetString");
OpenGL::wglMakeCurrent = (OpenGL::WGLMAKECURRENTPROC) GetProcAddress(gl_lib, "wglMakeCurrent");
OpenGL::wglGetProcAddress = (OpenGL::WGLGETPROCADDRPROC) GetProcAddress(gl_lib, "wglGetProcAddress");
OpenGL::wglCreateContext = (OpenGL::WGLCREATECONTEXTPROC) GetProcAddress(gl_lib, "wglCreateContext");
}