More Windows compatibility

Almost everything addressed

Couldn't figure out where the process handle is stored, if it is

Some cpp problems about CursorStyle classes. I tried several ways to solve this but nothing seemed to work so I'm really not sure what its actually complaining about now
This commit is contained in:
orange bowler hat
2024-05-09 00:00:32 +01:00
parent f47e6bc786
commit 52e1b6eb00
9 changed files with 258 additions and 277 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
/cmake-build-debug
/.idea
build/CMakeCache.txt
build/CMakeCache.txt

View File

@@ -1,25 +0,0 @@
Build started at 2024-04-29T21:04:24.529054
Main binary: C:\Program Files\Meson\meson.exe
Python system: Windows
The Meson build system
Version: 0.49.0
Source dir: d:\Work\ReWindow
Build dir: d:\Work\ReWindow\builddir
Build type: native build
Project name: verse
Project version: 0.1.0
Sanity testing C compiler: gcc
Is cross compiler: False.
Sanity check compiler command line: gcc d:\Work\ReWindow\builddir\meson-private\sanitycheckc.c -o d:\Work\ReWindow\builddir\meson-private\sanitycheckc.exe
Sanity check compile stdout:
-----
Sanity check compile stderr:
-----
Running test binary command: d:\Work\ReWindow\builddir\meson-private\sanitycheckc.exe
Native C compiler: gcc (gcc 9.2.0 "gcc (tdm64-1) 9.2.0")
meson.build:1:0: ERROR: Unknown compiler(s): ['cc']
The follow exceptions were encountered:
Running "cc --version" gave "[WinError 2] The system cannot find the file specified"

View File

@@ -1 +0,0 @@
int main(int argc, char **argv) { int class=0; return class; }

View File

@@ -27,22 +27,22 @@ namespace ReWindow
};
namespace Cursors {
static const CursorStyle Default {X11CursorStyle::Default};
static const CursorStyle X {X11CursorStyle::X};
static const CursorStyle Arrow {X11CursorStyle::Arrow};
static const CursorStyle IBeam {X11CursorStyle::IBeam};
static const CursorStyle BottomLeftCorner {X11CursorStyle::BottomLeftCorner};
static const CursorStyle BottomRightCorner {X11CursorStyle::BottomRightCorner};
static const CursorStyle BottomSide {X11CursorStyle::BottomSide};
static const CursorStyle Dot {X11CursorStyle::Dot};
static const CursorStyle DoubleArrow {X11CursorStyle::DoubleArrow};
static const CursorStyle Exchange {X11CursorStyle::Exchange};
static const CursorStyle Hand {X11CursorStyle::Hand};
static const CursorStyle LeftSide {X11CursorStyle::LeftSide};
static const CursorStyle Plus {X11CursorStyle::Plus};
static const CursorStyle RightSide {X11CursorStyle::RightSide};
static const CursorStyle Pencil {X11CursorStyle::Pencil};
}
static const CursorStyle Default {X11CursorStyle::Default};
static const CursorStyle X {X11CursorStyle::X};
static const CursorStyle Arrow {X11CursorStyle::Arrow};
static const CursorStyle IBeam {X11CursorStyle::IBeam};
static const CursorStyle BottomLeftCorner {X11CursorStyle::BottomLeftCorner};
static const CursorStyle BottomRightCorner {X11CursorStyle::BottomRightCorner};
static const CursorStyle BottomSide {X11CursorStyle::BottomSide};
static const CursorStyle Dot {X11CursorStyle::Dot};
static const CursorStyle DoubleArrow {X11CursorStyle::DoubleArrow};
static const CursorStyle Exchange {X11CursorStyle::Exchange};
static const CursorStyle Hand {X11CursorStyle::Hand};
static const CursorStyle LeftSide {X11CursorStyle::LeftSide};
static const CursorStyle Plus {X11CursorStyle::Plus};
static const CursorStyle RightSide {X11CursorStyle::RightSide};
static const CursorStyle Pencil {X11CursorStyle::Pencil};
}
class CursorStyle {
public:
@@ -63,7 +63,7 @@ namespace ReWindow
class CursorStyle {
public:
WindowsCursorStyle WindowsCursor;
CursorStyle(WindowsCursorStyle style) : WindowsCursor(style) {}
CursorStyle (WindowsCursorStyle style): WindowsCursor(style) {}
};
#endif

View File

@@ -10,6 +10,7 @@
#if WIN32
#include <windows.h>
#include <windowsx.h>
#include <wingdi.h>
#endif
@@ -27,225 +28,242 @@ using precision_clock = std::chrono::high_resolution_clock;
using precision_timestamp = precision_clock::time_point;
enum class RWindowFlags: uint8_t {
IN_FOCUS = 0,
FULLSCREEN = 1,
RESIZABLE = 2,
VSYNC = 4
IN_FOCUS = 0,
FULLSCREEN = 1,
RESIZABLE = 2,
VSYNC = 4
};
enum class RenderingAPI: uint8_t {
OPENGL = 0,
//Vulkan is unimplemented.
VULKAN = 1,
OPENGL = 0,
//Vulkan is unimplemented.
VULKAN = 1,
};
enum class KeyState { Pressed, Released };
enum class KeyState {Pressed, Released};
namespace ReWindow
{
using J3ML::LinearAlgebra::Vector2;
using J3ML::LinearAlgebra::Vector2;
class TimestampedEvent {
private:
class TimestampedEvent {
private:
public:
precision_timestamp Timestamp;
TimestampedEvent() : Timestamp(precision_clock::now())
{ }
};
public:
precision_timestamp Timestamp;
TimestampedEvent() : Timestamp(precision_clock::now())
{ }
};
class RWindowEvent : public TimestampedEvent {
public:
RWindowEvent() : TimestampedEvent() { }
};
const RWindowEvent EmptyRWindowEvent;
class RWindowEvent : public TimestampedEvent {
public:
RWindowEvent() : TimestampedEvent() { }
};
const RWindowEvent EmptyRWindowEvent;
namespace WindowEvents
{
class KeyboardState {
public:
std::map<Key, bool> PressedKeys;
};
namespace WindowEvents
{
class KeyboardState {
public:
std::map<Key, bool> PressedKeys;
};
class GamepadState {
public:
std::map<GamepadButton, bool> PressedButtons;
};
class GamepadState {
public:
std::map<GamepadButton, bool> PressedButtons;
};
class InputState {
public:
KeyboardState Keyboard;
GamepadState Gamepad;
};
class InputState {
public:
KeyboardState Keyboard;
GamepadState Gamepad;
};
class KeyboardEvent : public RWindowEvent {
public:
Key key;
KeyState state;
KeyboardEvent(Key key, KeyState state) : RWindowEvent(), key(key), state(state) {}
};
class MouseEvent : public RWindowEvent {};
class GamepadEvent : public RWindowEvent {};
class KeyboardEvent : public RWindowEvent {
public:
Key key;
KeyState state;
KeyboardEvent(Key key, KeyState state) : RWindowEvent(), key(key), state(state) {}
};
class MouseEvent : public RWindowEvent {};
class GamepadEvent : public RWindowEvent {};
class MouseMoveEvent : public MouseEvent {
public:
Vector2 Position;
Vector2 Delta;
MouseMoveEvent(const Vector2 &pos) : MouseEvent(), Position(pos)
{}
MouseMoveEvent(int x, int y) : MouseEvent(), Position(Vector2(x, y))
{}
};
class MouseMoveEvent : public MouseEvent {
public:
Vector2 Position;
Vector2 Delta;
MouseMoveEvent(const Vector2 &pos) : MouseEvent(), Position(pos)
{}
MouseMoveEvent(int x, int y) : MouseEvent(), Position(Vector2(x, y))
{}
};
class KeyDownEvent : public KeyboardEvent {
public:
KeyDownEvent(Key key) : KeyboardEvent(key, KeyState::Pressed) {}
};
class KeyDownEvent : public KeyboardEvent {
public:
KeyDownEvent(Key key) : KeyboardEvent(key, KeyState::Pressed) {}
};
class KeyUpEvent : public KeyboardEvent {
public:
KeyUpEvent(Key key) : KeyboardEvent(key, KeyState::Released) {}
};
class KeyUpEvent : public KeyboardEvent {
public:
KeyUpEvent(Key key) : KeyboardEvent(key, KeyState::Released) {}
};
class MouseButtonDownEvent : public MouseEvent {
public:
MouseButton Button;
};
class MouseButtonDownEvent : public MouseEvent {
public:
MouseButton Button;
};
class MouseButtonUpEvent : public MouseEvent {
public:
MouseButton Button;
};
class MouseButtonUpEvent : public MouseEvent {
public:
MouseButton Button;
};
class WindowResizeRequestEvent : public RWindowEvent
{
public:
Vector2 Size;
};
}
class WindowResizeRequestEvent : public RWindowEvent
{
public:
Vector2 Size;
};
}
using namespace WindowEvents;
using namespace WindowEvents;
class RWindow {
public:
class RWindow {
public:
#pragma region Callbacks
/// Bindable Non-intrusive event handlers
/// Use these when you can't override the base window class
Event<RWindowEvent> OnFocusLostEvent;
Event<RWindowEvent> OnFocusGainEvent;
Event<float> OnRefreshEvent;
Event<WindowResizeRequestEvent> OnResizeRequestEvent;
Event<KeyDownEvent> OnKeyDownEvent;
Event<KeyUpEvent> OnKeyUpEvent;
Event<MouseMoveEvent> OnMouseMoveEvent;
Event<MouseButtonDownEvent> OnMouseButtonDownEvent;
Event<MouseButtonUpEvent> OnMouseButtonUpEvent;
/// Bindable Non-intrusive event handlers
/// Use these when you can't override the base window class
Event<RWindowEvent> OnFocusLostEvent;
Event<RWindowEvent> OnFocusGainEvent;
Event<float> OnRefreshEvent;
Event<WindowResizeRequestEvent> OnResizeRequestEvent;
Event<KeyDownEvent> OnKeyDownEvent;
Event<KeyUpEvent> OnKeyUpEvent;
Event<MouseMoveEvent> OnMouseMoveEvent;
Event<MouseButtonDownEvent> OnMouseButtonDownEvent;
Event<MouseButtonUpEvent> OnMouseButtonUpEvent;
#pragma endregion
#pragma region Overrides
virtual void OnFocusLost(const RWindowEvent& e) {}
virtual void OnFocusGain(const RWindowEvent& e) {}
virtual void OnRefresh(float elapsed) {}
virtual void OnResizeSuccess() {}
virtual bool OnResizeRequest(const WindowResizeRequestEvent& e) { return true;}
virtual void OnKeyDown(const KeyDownEvent&) {}
virtual void OnKeyUp(const KeyUpEvent&) {}
virtual void OnMouseMove(const MouseMoveEvent&) {}
virtual void OnMouseButtonDown(const MouseButtonDownEvent&) {}
virtual void OnMouseButtonUp(const MouseButtonUpEvent&) {}
virtual void OnFocusLost(const RWindowEvent& e) {}
virtual void OnFocusGain(const RWindowEvent& e) {}
virtual void OnRefresh(float elapsed) {}
virtual void OnResizeSuccess() {}
virtual bool OnResizeRequest(const WindowResizeRequestEvent& e) { return true;}
virtual void OnKeyDown(const KeyDownEvent&) {}
virtual void OnKeyUp(const KeyUpEvent&) {}
virtual void OnMouseMove(const MouseMoveEvent&) {}
virtual void OnMouseButtonDown(const MouseButtonDownEvent&) {}
virtual void OnMouseButtonUp(const MouseButtonUpEvent&) {}
#pragma endregion
RWindow();
RWindow(const std::string& title, int width, int height);
RWindow(const std::string& title, int width, int height, RenderingAPI renderer);
RWindow();
RWindow(const std::string& title, int width, int height);
RWindow(const std::string& title, int width, int height, RenderingAPI renderer);
Vector2 GetMouseCoordinates() const
{
return getCursorPos();
}
Vector2 GetMouseCoordinates() const {
return getCursorPos();
}
void liftKey (Key key) {
currentKeyboard.PressedKeys[key] = false;
auto event = ReWindow::WindowEvents::KeyUpEvent(key);
OnKeyUp(event);
}
void pressKey (Key key) {
currentKeyboard.PressedKeys[key] = true;
auto eventData = KeyDownEvent(key);
OnKeyDown(eventData);
}
#ifndef __linux___
void setRect (int nx, int ny, int nw, int nh) {
x = nx;
y = ny;
width = nw;
height = nh;
}
#endif
void setRenderer(RenderingAPI api);
void Open();
void Close();
void CloseAndReopenInPlace();
// TODO: Must be implemented from scratch as a Motif Window in x11
void MessageBox();
bool isFocused() const;
bool isFullscreen() const;
bool isResizable() const;
bool isVsyncEnabled() const;
bool isAlive() const;
void setMouseVisible(bool visible);
void setMouseLocked();
void setMouseCenter();
void restoreMouseFromLastCenter(); // Feels nicer for users
bool isKeyDown(Key key) const;
bool isMouseButtonDown(MouseButton button) const;
void setFullscreen(bool fs);
void setResizable(bool resizable);
void setVsyncEnabled(bool);
void setTitle(const std::string& title);
std::string getTitle() const;
void fullscreen();
void restoreFromFullscreen();
bool getFlag(RWindowFlags flag) const;
void setFlag(RWindowFlags flag, bool state);
//void init(RenderingAPI api, const char* title, int width, int height, bool vsync);
void destroyWindow();
void pollEvents();
void refresh();
void setSize(int width, int height);
void setSize(const Vector2& size);
/// Returns the position of the window's top-left corner relative to the display
Vector2 getPos() const;
Vector2 getSize() const;
void setPos(int x, int y);
void setPos(const Vector2& pos);
Vector2 getCursorPos() const;
void raise() const;
void lower() const;
void setCursorStyle(CursorStyle style) const;
void setCursorCustomIcon() const;
static void glSwapBuffers();
//Initialize to false because it's not guaranteed that they will be cleared first
private:
Vector2 lastKnownWindowSize {0, 0};
bool flags[4];
std::vector<RWindowEvent> eventLog;
KeyboardState currentKeyboard; // Current Frame's Keyboard State
KeyboardState previousKeyboard; // Previous Frame's Keyboard State
bool fullscreenmode = false;
std::string title;
#ifndef __linux__
int x;
int y;
#endif
int width;
int height;
RenderingAPI renderer;
bool open = false;
bool resizable;
//You can't do this because you can't initialize a static member inside the class constructor.
//static RWindow* singleton;
};
void setRenderer(RenderingAPI api);
void Open();
void Close();
void CloseAndReopenInPlace();
class WindowsImplementationRWindow : public RWindow {
};
// TODO: Must be implemented from scratch as a Motif Window in x11
void MessageBox();
bool isFocused() const;
bool isFullscreen() const;
bool isResizable() const;
bool isVsyncEnabled() const;
bool isAlive() const;
void setMouseVisible(bool visible);
void setMouseLocked();
void setMouseCenter();
void restoreMouseFromLastCenter(); // Feels nicer for users
bool isKeyDown(Key key) const;
bool isMouseButtonDown(MouseButton button) const;
void setFullscreen(bool fs);
void setResizable(bool resizable);
void setVsyncEnabled(bool);
void setTitle(const std::string& title);
std::string getTitle() const;
void fullscreen();
void restoreFromFullscreen();
bool getFlag(RWindowFlags flag) const;
void setFlag(RWindowFlags flag, bool state);
//void init(RenderingAPI api, const char* title, int width, int height, bool vsync);
void destroyWindow();
void pollEvents();
void refresh();
void setSize(int width, int height);
void setSize(const Vector2& size);
/// Returns the position of the window's top-left corner relative to the display
Vector2 getPos() const;
Vector2 getSize() const;
void setPos(int x, int y);
void setPos(const Vector2& pos);
Vector2 getCursorPos() const;
void raise() const;
void lower() const;
//void setCursorStyle(CursorStyle style) const;
void setCursorCustomIcon() const;
static void glSwapBuffers();
//Initialize to false because it's not guaranteed that they will be cleared first
private:
Vector2 lastKnownWindowSize {0, 0};
bool flags[4];
std::vector<RWindowEvent> eventLog;
KeyboardState currentKeyboard; // Current Frame's Keyboard State
KeyboardState previousKeyboard; // Previous Frame's Keyboard State
bool fullscreenmode = false;
std::string title;
int width;
int height;
RenderingAPI renderer;
bool open = false;
bool resizable;
//You can't do this because you can't initialize a static member inside the class constructor.
//static RWindow* singleton;
};
class WindowsImplementationRWindow : public RWindow
{
};
class X11ImplementationRWindow : public RWindow
{
};
class X11ImplementationRWindow : public RWindow {
};
}

View File

@@ -129,17 +129,13 @@ namespace ReWindow {
if (xev.type == KeyRelease) {
auto scancode = (X11Scancode) xev.xkey.keycode;
auto key = GetKeyFromX11Scancode(scancode);
currentKeyboard.PressedKeys[key] = false;
auto eventData = KeyUpEvent(key);
OnKeyUp(eventData);
liftKey (key);
}
if (xev.type == KeyPress) {
auto scancode = (X11Scancode) xev.xkey.keycode;
auto key = GetKeyFromX11Scancode(scancode);
currentKeyboard.PressedKeys[key] = true;
auto eventData = KeyDownEvent(key);
OnKeyDown(eventData);
pressKey (key);
eventLog.push_back(eventData);
}

View File

@@ -28,18 +28,13 @@ LRESULT CALLBACK ReWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPara
case WM_KEYDOWN: {
auto key = GetKeyFromWindowsScancode ((WindowsScancode) wParam);
currentKeyboard.PressedKeys[key] = true;
auto event = ReWindow::WindowEvents::KeyDownEvent(key);
subject->OnKeyDown(event);
eventLog.push_back (event);
subject->pressKey (key);
break;
}
case WM_KEYUP: {
auto key = GetKeyFromWindowsScancode ((WindowsScancode) wParam);
currentKeyboard.PressedKeys[key] = false;
auto event = ReWindow::WindowEvents::KeyUpEvent(key);
subject->OnKeyUp(event);
subject->liftKey (key);
break;
}
@@ -86,7 +81,7 @@ LRESULT CALLBACK ReWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPara
}
case WM_MOUSEMOVE: {
auto event = ReWindow::WindowEvents::MouseMoveEvent (xev.xmotion.x, xev.xmotion.y);
auto event = ReWindow::WindowEvents::MouseMoveEvent (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam));
subject->OnMouseMove(event);
break;
}
@@ -98,11 +93,11 @@ LRESULT CALLBACK ReWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPara
break;
case WM_SIZE: {
case WM_WINDOWPOSCHANGED: {
WINDOWPOS *pos = (WINDOWPOS *) lParam;
subject->setRect (pos->x, pos->y, pos->cx, pos->cy);
auto event = ReWindow::WindowEvents::WindowResizeRequestEvent();
lastKnownWindowSize = event.Size;
event.Size = {LOWORD (lParam), HIWORD (lParam)};
lastKnownWindowSize = event.Size;
event.Size = {(float) pos->cx, (float) pos->cy};
subject->OnResizeRequest (event);
break;
}
@@ -130,7 +125,7 @@ ReWindow::RWindow::RWindow() {
reClass = RegisterClassA (&rewc);
}
hwnd = CreateWindowA (reClass, "ReWindow", WS_TILEDWINDOW,
hwnd = CreateWindowA ("ReWindowClass", "ReWindow", WS_TILEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, NULL, 0);
SetWindowLongPtrA (hwnd, GWLP_USERDATA, (LONG_PTR) this);
@@ -184,14 +179,22 @@ void ReWindow::RWindow::refresh() {
}
void ReWindow::RWindow::setFlag (RWindowFlags flag, bool state) {
XGetWindowAttributes(display,window,&windowAttributes);
DWORD style = GetWindowLongA (hwnd, GWL_STYLE);
flags[(int) flag] = state;
if (flag == RWindowFlags::RESIZABLE && !state) {
hints.flags = PMinSize | PMaxSize;
hints.min_width = hints.max_width = windowAttributes.width;
hints.min_height = hints.max_height = windowAttributes.height;
XSetWMNormalHints(display, window, &hints);
if (flag == RWindowFlags::RESIZABLE) {
if (style & WS_THICKFRAME) {
if (!state) {
style &= ~WS_THICKFRAME;
SetWindowLongA (hwnd, GWL_STYLE, style);
}
}
else {
if (state) {
style |= WS_THICKFRAME;
SetWindowLongA (hwnd, GWL_STYLE, style);
}
}
}
}
@@ -205,18 +208,14 @@ void ReWindow::RWindow::refresh() {
}
// Might make the window go off the screen on some window managers.
void ReWindow::RWindow::setSize (int newWidth, int newHeight) {
if (!getFlag(RWindowFlags::RESIZABLE)) return;
width = newWidth;
height = newHeight;
MoveWindow (hwnd, x, y, width, height, TRUE);
void ReWindow::RWindow::setSize (int w, int h) {
if (!getFlag (RWindowFlags::RESIZABLE)) return;
MoveWindow (hwnd, x, y, w, h, TRUE);
}
void ReWindow::RWindow::setSize(const Vector2& size)
if (!getFlag(RWindowFlags::RESIZABLE)) return;
width = size.x;
height = size.y;
MoveWindow (hwnd, x, y, width, height, TRUE);
void ReWindow::RWindow::setSize(const Vector2& size) {
if (!getFlag (RWindowFlags::RESIZABLE)) return;
MoveWindow (hwnd, x, y, size.x, size.y, TRUE);
}
Vector2 ReWindow::RWindow::getCursorPos() const {
@@ -234,26 +233,20 @@ void ReWindow::RWindow::refresh() {
// TODO: implement integer vector2/3 types
Vector2 ReWindow::RWindow::getSize() const {
RECT area;
GetClientRect (hwnd, &area);
return {(float) area.right, (float) area.bottom};
return {(float) width, (float) height};
}
// TODO: implement integer vector2/3 types
Vector2 ReWindow::RWindow::getPos() const {
RECT area;
GetWindowRect (hwnd, &area);
return Vector2 ((float) area.left, (float) area.top);
return Vector2 ((float) x, (float) y);
}
void ReWindow::RWindow::setPos(int newx, int newy) {
x = newx;
y = newy;
MoveWindow (hwnd, x, y, width, height, TRUE);
void ReWindow::RWindow::setPos(int nx, int ny) {
MoveWindow (hwnd, nx, ny, width, height, TRUE);
}
void ReWindow::RWindow::setPos(const Vector2& pos) {
this->setPos(pos.x, pos.y);
MoveWindow (hwnd, pos.x, pos.y, width, height, TRUE);
}
void ReWindow::RWindow::glSwapBuffers() {
@@ -309,9 +302,8 @@ void ReWindow::RWindow::refresh() {
}
void ReWindow::RWindow::setCursorStyle (CursorStyle style) const {
u32 x11_cursor_resolved_enum = static_cast<u32>(style.X11Cursor);
Cursor c = XCreateFontCursor(display, x11_cursor_resolved_enum);
XDefineCursor(display, window, c);
uint ids = [IDC_ARROW, IDC_IBEAM, IDC_WAIT, IDC_CROSS, IDC_HAND, IDC_APPSTARTING];
SetClassLongPtr (hwnd, GCLIP_HCURSOR, LoadCursor (NULL, ids[style]));
}
void ReWindow::RWindow::Open() {