Compare commits

...

61 Commits

Author SHA1 Message Date
39990e587b Update CMakeLists.txt 2024-05-23 19:33:53 -04:00
Redacted
51d370e045 Update CMakeLists.txt 2024-05-22 20:34:33 -04:00
Redacted
4ee4cafad7 Update CMakeLists.txt 2024-05-22 20:15:36 -04:00
maxbyte9p
e1c0cdd1a2 Fixed left and right shift scan codes 2024-05-22 13:51:57 -04:00
maxbyte9p
7b149594fe Make window start as a floating window because fuck i3 2024-05-22 13:39:22 -04:00
Redacted
350b12aa6d Update CMakeLists.txt 2024-05-22 12:19:16 -04:00
a8da7b6bdf Update 2024-05-22 07:23:57 -07:00
50ccfe3860 Update J3ML 2024-05-21 13:16:06 -04:00
orange bowler hat
3572ef01cd More Windows Update
Several minor changes to code and build setup
Demo runs now
2024-05-13 23:14:04 +01:00
orange bowler hat
664d213c04 Several smaller updates
Windows version of ReWindow now compiling
Added to gitignore
2024-05-13 13:40:11 +01:00
d3a971d598 Fix 2024-05-08 22:15:28 -04:00
orange bowler hat
52e1b6eb00 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
2024-05-09 00:00:32 +01:00
orange bowler hat
f47e6bc786 Lets try that last one again
Comments as previous commit
2024-05-03 23:57:40 +01:00
orange bowler hat
1d9169679f Updates to windows version
Many changes to flesh out windows version of ReWindow.
Incomplete, not compiled or tested.
Almost certainly won't work as is but a lot closer to a functioning Windows version
2024-05-03 23:49:35 +01:00
Redacted
a7b7de93dd fix cmake & vsync 2024-04-30 14:45:43 -07:00
orange bowler hat
124cbedf4d Updates to windows version (Thanks Steven)
Many changes to flesh out windows version of ReWindow.
Incomplete, not compiled or tested.
Almost certainly won't work as is but a lot closer to a functioning Windows version
2024-04-29 19:13:25 -04:00
orange bowler hat
4db3b5f908 Updates to windows version
Many changes to flesh out windows version of ReWindow.
Incomplete, not compiled or tested.
Almost certainly won't work as is but a lot closer to a functioning Windows version
2024-04-29 23:03:35 +01:00
9a4a4dddcc Merge remote-tracking branch 'origin/main' 2024-04-09 16:38:49 -04:00
04fa303a81 Migrate to J3ML Release 1 2024-04-09 16:38:39 -04:00
4facfb11fa Update window.cpp
vsync fix
2024-03-26 11:47:59 -04:00
ef257765fe Migrate to J3ML v20 2024-03-21 13:05:09 -04:00
5696dd4ed8 Un-break 2024-02-24 08:42:42 -05:00
Redacted
9f0a511022 Update CMakeLists.txt 2024-02-24 07:48:37 -05:00
ffe49e4c67 Implement static GetMouseCoordinates() ? 2024-02-22 00:31:04 -05:00
28f904783f Fix SIGILL 2024-02-21 23:46:42 -05:00
6969568549 Attempt to fix broken integration 2024-02-21 23:38:12 -05:00
bcc74ea3d4 Integrate Event module 2024-02-21 23:12:36 -05:00
ef57fb0732 Implement RWindow::isKeyDown 2024-02-21 20:21:37 -05:00
2930391ee4 Implement CursorStyles, minor refactors 2024-02-21 20:10:06 -05:00
b1dfab70a1 Lil Cleanup 2024-02-21 05:37:12 -05:00
bdc1427626 Clear TODOs 2024-02-21 05:35:20 -05:00
158fafaa79 Implement Window::getCursorPos, also fixed Window::getPos 2024-02-21 05:35:08 -05:00
426b02b3ea Migrate to latest J3ML 2024-02-20 03:52:24 -05:00
227ecdb64c Implementing Window::GetSize() 2024-02-14 20:38:26 -05:00
089b110b87 Implementing more of the Windows/X11 KeyMap 2024-02-13 20:24:06 -05:00
7e8a1b4030 Remove JGL dependency 2024-02-13 19:59:02 -05:00
f0bf6c5871 Fix public linkage of JGL turning into build dependency for entire lib 2024-02-13 17:25:36 -05:00
46e947eb77 Fully Deprecate GLM 2024-02-13 16:28:29 -05:00
fe6638c4be Technically working, however values are incorrect (So is result of RWindow::getPos()) 2024-02-07 16:11:42 -05:00
70e41a56cb XError Kekekek 2024-02-07 15:05:24 -05:00
scientiist
3306c6acba Implement MouseDelta check (WIP) 2024-02-07 11:40:54 -06:00
scientiist
01eed78c48 Implement Mouse Input (TODO: Event only fires when mouse **begins** and **stops** moving) 2024-02-07 08:29:53 -06:00
scientiist
ef7e8b1211 Fix fucked up header 2024-02-07 05:29:33 -06:00
432d1818f3 Refactoring 2024-02-06 23:37:46 -05:00
983428f69d Merge All Branches 2024-01-25 20:10:46 -05:00
1336297ac0 Merge pull request 'vsync-test' (#4) from vsync-test into main
Reviewed-on: #4
2024-01-25 20:02:42 -05:00
103c5b2001 Merge remote-tracking branch 'origin/vsync-test' into vsync-test
# Conflicts:
#	CMakeLists.txt
#	include/rewindow/data/X11Scancodes.h
#	include/rewindow/types/event.h
#	include/rewindow/types/key.h
#	include/rewindow/types/window.h
#	main.cpp
#	src/linux/window.cpp
2024-01-25 20:02:02 -05:00
89a6fa57b6 Update window.cpp 2024-01-25 20:01:30 -05:00
04ced07c18 Update window.cpp
Fixed a problem that'd cause setting vsync to behave strangely and overlays to crash.
2024-01-25 20:00:05 -05:00
353def8ba9 update 2024-01-25 19:55:57 -05:00
c3605a052f Update CMakeLists.txt 2024-01-25 19:54:52 -05:00
d122da68fd vsync test 2024-01-25 19:54:50 -05:00
b49f44855f Merge pull request 'virtual-window' (#3) from virtual-window into main
Reviewed-on: #3
2024-01-25 19:43:58 -05:00
7343a95a45 Update window.cpp 2024-01-24 22:16:29 -05:00
62568e3252 Update window.cpp 2024-01-24 22:09:58 -05:00
ae5aebae5e Tryna Implement Fullscreen 2024-01-24 20:19:39 -05:00
2714c41167 Refactoring 2024-01-24 19:28:53 -05:00
6f8fbf18bd Implementing WindowsScancodes 2024-01-05 13:02:30 -05:00
10a8105f71 Implementing WindowsScancodes 2024-01-05 12:47:25 -05:00
eed5f10413 Implementing X11Scancodes 2024-01-04 17:26:41 -05:00
6afccc34a5 Implementing Stuff 2024-01-04 07:29:59 -05:00
18 changed files with 1715 additions and 293 deletions

2
.gitignore vendored
View File

@@ -1,2 +1,4 @@
/cmake-build-debug
/.idea
build/*
.vscode/*

View File

@@ -10,37 +10,72 @@ endif()
set(CMAKE_CXX_STANDARD 20)
if (WIN32)
set(CMAKE_CXX_FLAGS "-municode")
endif()
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
# Enable Package Managers
# include(cmake/CPM.cmake)
include(cmake/CPM.cmake)
CPMAddPackage(
NAME J3ML
URL https://git.redacted.cc/josh/j3ml/archive/Release-7.zip
)
CPMAddPackage(
NAME Event
URL https://git.redacted.cc/josh/Event/archive/Release-5.zip
)
find_package(OpenGL REQUIRED)
include_directories({$OPENGL_INCLUDE_DIRS})
include_directories(${OPENGL_INCLUDE_DIRS})
include_directories(${J3ML_SOURCE_DIR}/include)
file(GLOB_RECURSE HEADERS "include/*.h" "include/*.hpp")
if(UNIX AND NOT APPLE)
file(GLOB_RECURSE SOURCES "src/linux/*.cpp")
file(GLOB_RECURSE SOURCES "src/rewindow/*.cpp" "src/linux/*.cpp")
endif()
if(WIN32)
file(GLOB_RECURSE SOURCES "src/windows/*.cpp")
file(GLOB_RECURSE SOURCES "src/rewindow/*.cpp" "src/windows/*.cpp")
endif()
include_directories("include")
add_library(ReWindowLibrary SHARED ${SOURCES})
if(UNIX)
add_library(ReWindowLibrary SHARED ${SOURCES})
endif()
if(WIN32)
add_library(ReWindowLibrary STATIC ${SOURCES})
endif()
target_include_directories(ReWindowLibrary PUBLIC ${Event_SOURCE_DIR}/include)
# Why god???
set_target_properties(ReWindowLibrary PROPERTIES LINKER_LANGUAGE CXX)
if(UNIX AND NOT APPLE)
target_link_libraries(ReWindowLibrary PUBLIC X11 ${OPENGL_LIBRARIES})
target_link_libraries(ReWindowLibrary PUBLIC X11)
target_link_libraries(ReWindowLibrary PUBLIC ${OPENGL_LIBRARIES})
target_link_libraries(ReWindowLibrary PUBLIC J3ML)
target_link_libraries(ReWindowLibrary PUBLIC Event)
add_executable(ReWindowLibraryDemo main.cpp)
#target_include_directories(ReWindowLibraryDemo PRIVATE ${JGL_SOURCE_DIR}/include)
target_link_libraries(ReWindowLibraryDemo PUBLIC ReWindowLibrary)
#target_link_libraries(ReWindowLibraryDemo PRIVATE JGL)
endif()
if(WIN32)
#target_compile_options(ReWindowLibrary PRIVATE -Wno-multichar)
target_link_libraries(ReWindowLibrary PUBLIC ${OPENGL_LIBRARIES})
target_link_libraries(ReWindowLibrary PUBLIC J3ML)
target_link_libraries(ReWindowLibrary PUBLIC Event)
add_executable(ReWindowLibraryDemo main.cpp)
#target_compile_options(ReWindowLibraryDemo PRIVATE)
target_link_libraries(ReWindowLibraryDemo PUBLIC ReWindowLibrary)
endif()

98
build/CMakeCache.txt Normal file
View File

@@ -0,0 +1,98 @@
# This is the CMakeCache file.
# For build in directory: d:/Work/ReWindow/build
# It was generated by CMake: C:/Program Files/CMake/bin/cmake.exe
# You can edit this file to change values found and used by cmake.
# If you do not want to change any of the values, simply exit the editor.
# If you do want to change a value, simply edit, save, and exit the editor.
# The syntax for the file is as follows:
# KEY:TYPE=VALUE
# KEY is the name of a variable in the cache.
# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!.
# VALUE is the current value for the KEY.
########################
# EXTERNAL cache entries
########################
//Value Computed by CMake.
CMAKE_FIND_PACKAGE_REDIRECTS_DIR:STATIC=D:/Work/ReWindow/build/CMakeFiles/pkgRedirects
//Program used to build from makefiles.
CMAKE_MAKE_PROGRAM:STRING=nmake
//Value Computed by CMake
CMAKE_PROJECT_DESCRIPTION:STATIC=
//Value Computed by CMake
CMAKE_PROJECT_HOMEPAGE_URL:STATIC=
//Value Computed by CMake
CMAKE_PROJECT_NAME:STATIC=ReWindowLibrary
//Value Computed by CMake
CMAKE_PROJECT_VERSION:STATIC=1.0
//Value Computed by CMake
CMAKE_PROJECT_VERSION_MAJOR:STATIC=1
//Value Computed by CMake
CMAKE_PROJECT_VERSION_MINOR:STATIC=0
//Value Computed by CMake
CMAKE_PROJECT_VERSION_PATCH:STATIC=
//Value Computed by CMake
CMAKE_PROJECT_VERSION_TWEAK:STATIC=
//Value Computed by CMake
ReWindowLibrary_BINARY_DIR:STATIC=D:/Work/ReWindow/build
//Value Computed by CMake
ReWindowLibrary_IS_TOP_LEVEL:STATIC=ON
//Value Computed by CMake
ReWindowLibrary_SOURCE_DIR:STATIC=D:/Work/ReWindow
########################
# INTERNAL cache entries
########################
//This is the directory where this CMakeCache.txt was created
CMAKE_CACHEFILE_DIR:INTERNAL=d:/Work/ReWindow/build
//Major version of cmake used to create the current loaded cache
CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3
//Minor version of cmake used to create the current loaded cache
CMAKE_CACHE_MINOR_VERSION:INTERNAL=29
//Patch version of cmake used to create the current loaded cache
CMAKE_CACHE_PATCH_VERSION:INTERNAL=2
//Path to CMake executable.
CMAKE_COMMAND:INTERNAL=C:/Program Files/CMake/bin/cmake.exe
//Path to cpack program executable.
CMAKE_CPACK_COMMAND:INTERNAL=C:/Program Files/CMake/bin/cpack.exe
//Path to ctest program executable.
CMAKE_CTEST_COMMAND:INTERNAL=C:/Program Files/CMake/bin/ctest.exe
//Path to cache edit program executable.
CMAKE_EDIT_COMMAND:INTERNAL=C:/Program Files/CMake/bin/cmake-gui.exe
//Name of external makefile project generator.
CMAKE_EXTRA_GENERATOR:INTERNAL=
//Name of generator.
CMAKE_GENERATOR:INTERNAL=NMake Makefiles
//Generator instance identifier.
CMAKE_GENERATOR_INSTANCE:INTERNAL=
//Name of generator platform.
CMAKE_GENERATOR_PLATFORM:INTERNAL=
//Name of generator toolset.
CMAKE_GENERATOR_TOOLSET:INTERNAL=
//Source directory with the top level CMakeLists.txt file for this
// project
CMAKE_HOME_DIRECTORY:INTERNAL=D:/Work/ReWindow
//ADVANCED property for variable: CMAKE_MAKE_PROGRAM
CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1
//number of local generators
CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=1
//Platform information initialized
CMAKE_PLATFORM_INFO_INITIALIZED:INTERNAL=1
//Path to CMake installation.
CMAKE_ROOT:INTERNAL=C:/Program Files/CMake/share/cmake-3.29

View File

@@ -0,0 +1,15 @@
set(CMAKE_HOST_SYSTEM "Windows-10.0.15063")
set(CMAKE_HOST_SYSTEM_NAME "Windows")
set(CMAKE_HOST_SYSTEM_VERSION "10.0.15063")
set(CMAKE_HOST_SYSTEM_PROCESSOR "AMD64")
set(CMAKE_SYSTEM "Windows-10.0.15063")
set(CMAKE_SYSTEM_NAME "Windows")
set(CMAKE_SYSTEM_VERSION "10.0.15063")
set(CMAKE_SYSTEM_PROCESSOR "AMD64")
set(CMAKE_CROSSCOMPILING "FALSE")
set(CMAKE_SYSTEM_LOADED 1)

View File

@@ -0,0 +1,11 @@
---
events:
-
kind: "message-v1"
backtrace:
- "C:/Program Files/CMake/share/cmake-3.29/Modules/CMakeDetermineSystem.cmake:205 (message)"
- "CMakeLists.txt:2 (project)"
message: |
The system is: Windows - 10.0.15063 - AMD64
...

View File

@@ -0,0 +1 @@
# This file is generated by cmake for dependency checking of the CMakeCache.txt file

24
cmake/CPM.cmake Normal file
View File

@@ -0,0 +1,24 @@
# SPDX-License-Identifier: MIT
#
# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors
set(CPM_DOWNLOAD_VERSION 0.38.7)
set(CPM_HASH_SUM "83e5eb71b2bbb8b1f2ad38f1950287a057624e385c238f6087f94cdfc44af9c5")
if(CPM_SOURCE_CACHE)
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
elseif(DEFINED ENV{CPM_SOURCE_CACHE})
set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
else()
set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
endif()
# Expand relative path. This is important if the provided path contains a tilde (~)
get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE)
file(DOWNLOAD
https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake
${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM}
)
include(${CPM_DOWNLOAD_LOCATION})

View File

@@ -0,0 +1,95 @@
#pragma once
enum class WindowsScancode {
Nothing = 0,
ESCAPE = 0x01,
ONE = 0x02,
TWO = 0x03,
THREE = 0x04,
FOUR = 0x05,
FIVE = 0x06,
SIX = 0x07,
SEVEN = 0x08,
EIGHT = 0x09,
NINE = 0x0A,
ZERO = 0x0B,
MINUS = 0x0C,
EQUALS = 0x0D,
BACKSPACE = 0x0E,
TAB = 0x0F,
Q = 0x10,
W = 0x11,
E = 0x12,
R = 0x13,
T = 0x14,
Y = 0x15,
U = 0x16,
I = 0x17,
O = 0x18,
P = 0x19,
LEFT_BRACKET = 0x1A,
RIGHT_BRACKET = 0x1B,
ENTER = 0x1C,
CTRL = 0x1D,
A = 0x1E,
S = 0x1F,
D = 0x20,
F = 0x21,
G = 0x22,
H = 0x23,
J = 0x24,
K = 0x25,
L = 0x26,
SEMICOLON = 0x27,
SINGLEQUOTE = 0x28,
GRAVE = 0x29,
LEFT_SHIFT = 0x2A,
BACKSLASH = 0x2B,
Z = 0x2C,
X = 0x2D,
C = 0x2E,
V = 0x2F,
B = 0x30,
N = 0x30,
M = 0x32,
COMMA = 0x33,
PERIOD = 0x34,
SLASH = 0x35,
RIGHT_SHIFT = 0x36,
PRINTSCREEN = 0x37,
ALT = 0x38,
SPACE = 0x39,
CAPS_LOCK = 0x3A,
F1 = 0x3B,
F2 = 0x3C,
F3 = 0x3D,
F4 = 0x3E,
F5 = 0x3F,
F6 = 0x40,
F7 = 0x41,
F8 = 0x42,
F9 = 0x43,
F10 = 0x44,
NUM_LOCK = 0x45,
SCROLL_LOCK = 0x46,
HOME = 0x47,
UP_ARROW = 0x48,
LEFT_ARROW,
DOWN_ARROW,
RIGHT_ARROW,
PAGE_UP = 0x49,
NUMPAD_MINUS = 0x4A,
NUMPAD_4 = 0x4B,
NUMPAD_5 = 0x4C,
NUMPAD_6 = 0x4D,
NUMPAD_PLUS = 0x4E,
NUMPAD_ONE = 0x4F,
NUMPAD_TWO = 0x50,
NUMPAD_THREE = 0x51,
NUMPAD_ZERO = 0x52,
DELETE = 0x53,
F11 = 0x85,
F12 = 0x86, // FIX
};

View File

@@ -1,11 +1,9 @@
#pragma once
#if __linux__
#include <X11/Xlib.h>
#include <chrono>
#endif
// @file X11Scancodes.h
// @
//This is also the x11 scancodes.
enum class SCANCODE {
#pragma once
enum class X11Scancode {
KP_0 = 90,
KP_1 = 87,
KP_2 = 88,
@@ -93,54 +91,20 @@ enum class SCANCODE {
SUPER = 133,
LEFT_CTRL = 37,
ESCAPE = 9,
FUNCTION_ONE = 67,
FUNCTION_TWO = 68,
FUNCTION_THREE = 69,
FUNCTION_FOUR = 70,
FUNCTION_FIVE = 71,
FUNCTION_SIX = 72,
FUNCTION_SEVEN = 73,
FUNCTION_EIGHT = 74,
FUNCTION_NINE = 75,
FUNCTION_TEN = 76,
FUNCTION_ELEVEN = 77,
FUNCTION_TWELVE = 78,
F1 = 67,
F2 = 68,
F3 = 69,
F4 = 70,
F5 = 71,
F6 = 72,
F7 = 73,
F8 = 74,
F9 = 75,
F10 = 76,
F11 = 95,
F12 = 96,
PRINT = 107,
SCROLL_LOCK = 78,
BREAK = 127,
};
enum class MOUSEBUTTONCODE {
LEFT_CLICK = 1,
MIDDLE_CLICK = 2,
RIGHT_CLICK = 3,
SCROLL_UP = 4,
SCROLL_DOWN = 5,
SIDE_FORWARD = 9,
SIDE_BACK = 8
};
class RWindowEvent {
private:
std::chrono::high_resolution_clock::time_point timePoint;
public:
std::chrono::high_resolution_clock::time_point timeStamp();
virtual ~RWindowEvent() = default;
virtual bool empty();
RWindowEvent() {
timePoint = std::chrono::high_resolution_clock::now();
}
};
const RWindowEvent EmptyRWindowEvent;
class KeyDownEvent : public RWindowEvent {
public:
SCANCODE key;
};
const KeyDownEvent EmptyKeyDownEvent{};
class MouseButtonDownEvent : public RWindowEvent {
public:
MOUSEBUTTONCODE button;
};
const MouseButtonDownEvent EmptyMouseButtonDownEvent{};

View File

@@ -0,0 +1,80 @@
#pragma once
#if __linux__
#include <X11/cursorfont.h>
#endif
namespace ReWindow
{
#if __linux__
enum class X11CursorStyle
{
Default = XC_left_ptr,
X = XC_X_cursor,
Arrow = XC_arrow,
IBeam = XC_xterm,
BottomLeftCorner = XC_bottom_left_corner,
BottomRightCorner = XC_bottom_right_corner,
BottomSide = XC_bottom_side,
Dot = XC_dot,
DoubleArrow = XC_double_arrow,
Exchange = XC_exchange,
Hand = XC_hand2,
LeftSide = XC_left_side,
Plus = XC_plus,
RightSide = XC_right_side,
Pencil = XC_pencil
};
class CursorStyle {
public:
X11CursorStyle X11Cursor;
CursorStyle(X11CursorStyle style) : X11Cursor(style) {}
};
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};
}
#else
// https://learn.microsoft.com/en-us/windows/win32/menurc/about-cursors
enum WindowsCursorStyle {
Arrow,
IBeam,
Wait,
Cross,
Hand,
AppStarting,
};
class CursorStyle {
public:
WindowsCursorStyle WindowsCursor;
CursorStyle (WindowsCursorStyle style): WindowsCursor(style) {}
};
namespace Cursors {
static const CursorStyle Default {WindowsCursorStyle::Arrow};
static const CursorStyle Arrow {WindowsCursorStyle::Arrow};
static const CursorStyle IBeam {WindowsCursorStyle::IBeam};
static const CursorStyle Cross {WindowsCursorStyle::Cross};
static const CursorStyle Wait {WindowsCursorStyle::Wait};
static const CursorStyle Hand {WindowsCursorStyle::Hand};
static const CursorStyle AppStarting {WindowsCursorStyle::AppStarting};
}
#endif
}

View File

@@ -0,0 +1,200 @@
//
// ~DAWSH
#pragma once
#include <vector>
#include <J3ML/LinearAlgebra/Vector2.h>
#include <stdexcept>
#include <iostream>
#if __linux__
#include <X11/X.h>
#endif
#include "rewindow/data/X11Scancodes.h"
#include "rewindow/data/WindowsScancodes.h"
using J3ML::LinearAlgebra::Vector2;
class Key
{
private:
static std::vector<Key> keyboard;
public:
static std::vector<Key> GetKeyboard();
Key();
Key(char charcode, X11Scancode scancode, WindowsScancode wSc);
char CharCode;
X11Scancode x11ScanCode;
WindowsScancode winScanCode;
bool operator==(const Key& rhs) const;
bool operator<(const Key& rhs) const;
Key(const Key&) = default;
};
namespace Keys {
// TODO: Encode both Uppercase and Lowercase version for each keymap
static const Key Escape {'\b', X11Scancode::ESCAPE, WindowsScancode::ESCAPE};
static const Key F1 {'\u000f', X11Scancode::F1, WindowsScancode::F1};
static const Key F2 {'\u000f', X11Scancode::F2, WindowsScancode::F2};
static const Key F3 {'\u000f', X11Scancode::F3, WindowsScancode::F3};
static const Key F4 {'\u000f', X11Scancode::F4, WindowsScancode::F4};
static const Key F5 {'\u000f', X11Scancode::F5, WindowsScancode::F5};
static const Key F6 {'\u000f', X11Scancode::F6, WindowsScancode::F6};
static const Key F7 {'\u000f', X11Scancode::F7, WindowsScancode::F7};
static const Key F8 {'\u000f', X11Scancode::F8, WindowsScancode::F8};
static const Key F9 {'\u000f', X11Scancode::F9, WindowsScancode::F9};
static const Key F10 {'\u000f', X11Scancode::F10, WindowsScancode::F10};
static const Key F11 {'\u000f', X11Scancode::F11, WindowsScancode::F11};
static const Key F12 {'\u000f', X11Scancode::F12, WindowsScancode::F12};
static const Key NumPad1 {'\b', X11Scancode::KP_1, WindowsScancode::NUMPAD_ONE};
static const Key NumPad2 {'\b', X11Scancode::KP_2, WindowsScancode::NUMPAD_TWO};
static const Key NumPad3 {'\b', X11Scancode::KP_3, WindowsScancode::NUMPAD_THREE};
static const Key NumPad4 {'\b', X11Scancode::KP_4, WindowsScancode::NUMPAD_ONE};
static const Key NumPad5 {'\b', X11Scancode::KP_5, WindowsScancode::NUMPAD_ONE};
static const Key NumPad6 {'\b', X11Scancode::KP_6, WindowsScancode::NUMPAD_ONE};
static const Key NumPad7 {'\b', X11Scancode::KP_7, WindowsScancode::NUMPAD_ONE};
static const Key NumPad8 {'\b', X11Scancode::KP_8, WindowsScancode::NUMPAD_ONE};
static const Key NumPad9 {'\b', X11Scancode::KP_9, WindowsScancode::NUMPAD_ONE};
static const Key NumPad0 {'\b', X11Scancode::KP_0, WindowsScancode::NUMPAD_ONE};
static const Key One {'1', X11Scancode::ONE, WindowsScancode::ONE};
static const Key Two {'2', X11Scancode::TWO, WindowsScancode::TWO};
static const Key Three {'3', X11Scancode::THREE, WindowsScancode::THREE};
static const Key Four {'4', X11Scancode::FOUR, WindowsScancode::FOUR};
static const Key Five {'5', X11Scancode::FIVE, WindowsScancode::FIVE};
static const Key Six {'6', X11Scancode::SIX, WindowsScancode::SIX};
static const Key Seven {'7', X11Scancode::SEVEN, WindowsScancode::SEVEN};
static const Key Eight {'8', X11Scancode::EIGHT, WindowsScancode::EIGHT};
static const Key Nine {'9', X11Scancode::NINE, WindowsScancode::NINE};
static const Key Zero {'0', X11Scancode::ZERO, WindowsScancode::ZERO};
static const Key Q {'Q', X11Scancode::Q, WindowsScancode::Q};
static const Key W {'W', X11Scancode::W, WindowsScancode::W};
static const Key E {'E', X11Scancode::E, WindowsScancode::E};
static const Key R {'R', X11Scancode::R, WindowsScancode::R};
static const Key T {'T', X11Scancode::T, WindowsScancode::T};
static const Key Y {'Y', X11Scancode::Y, WindowsScancode::Y};
static const Key U {'U', X11Scancode::U, WindowsScancode::U};
static const Key I {'I', X11Scancode::I, WindowsScancode::I};
static const Key O {'O', X11Scancode::O, WindowsScancode::O};
static const Key P {'P', X11Scancode::P, WindowsScancode::P};
static const Key A {'A', X11Scancode::A, WindowsScancode::A};
static const Key S {'S', X11Scancode::S, WindowsScancode::S};
static const Key D {'D', X11Scancode::D, WindowsScancode::D};
static const Key F {'F', X11Scancode::F, WindowsScancode::F};
static const Key G {'G', X11Scancode::G, WindowsScancode::G};
static const Key H {'H', X11Scancode::H, WindowsScancode::H};
static const Key J {'J', X11Scancode::J, WindowsScancode::J};
static const Key K {'K', X11Scancode::K, WindowsScancode::K};
static const Key L {'L', X11Scancode::L, WindowsScancode::L};
static const Key Semicolon {';', X11Scancode::SEMICOLON, WindowsScancode::SEMICOLON};
static const Key SingeQuote {'\'', X11Scancode::SINGLEQUOTE, WindowsScancode::SEMICOLON};
static const Key Enter {'\n', X11Scancode::RETURN, WindowsScancode::ENTER};
//static const Key KeyPadEnter {'\n', X11Scancode::KP_RETURN};
static const Key Minus {'-', X11Scancode::MINUS, WindowsScancode::MINUS};
//static const Key KeyPadMinus {'-', X11Scancode::KP_MINUS};
static const Key Equals {'=', X11Scancode::EQUALS, WindowsScancode::EQUALS};
static const Key Z {'Z', X11Scancode::Z, WindowsScancode::Z};
static const Key X {'X', X11Scancode::X, WindowsScancode::X};
static const Key C {'C', X11Scancode::C, WindowsScancode::C};
static const Key V {'V', X11Scancode::V, WindowsScancode::V};
static const Key B {'B', X11Scancode::B, WindowsScancode::B};
static const Key N {'N', X11Scancode::N, WindowsScancode::N};
static const Key M {'M', X11Scancode::M, WindowsScancode::M};
static const Key Period {'.', X11Scancode::PERIOD, WindowsScancode::PERIOD};
static const Key ForwardSlash {'/', X11Scancode::SLASH, WindowsScancode::SLASH};
static const Key BackSlash {'\\', X11Scancode::BACKSLASH, WindowsScancode::BACKSLASH};
static const Key Space {' ', X11Scancode::SPACE, WindowsScancode::SPACE};
static const Key LControl {'\\', X11Scancode::LEFT_CTRL, WindowsScancode::CTRL};
static const Key RControl {'\\', X11Scancode::RIGHT_CONTROL, WindowsScancode::CTRL};
static const Key LAlt {'\\', X11Scancode::LEFT_ALT, WindowsScancode::ALT};
static const Key RAlt {'\\', X11Scancode::RIGHT_ALT, WindowsScancode::ALT};
static const Key LShift {'\\', X11Scancode::LEFT_SHIFT, WindowsScancode::LEFT_SHIFT};
static const Key RShift {'\\', X11Scancode::RIGHT_SHIFT, WindowsScancode::RIGHT_SHIFT};
// TODO: Get the right character codes for these
static const Key UpArrow {'\u000a', X11Scancode::UP, WindowsScancode::UP_ARROW};
static const Key DownArrow {'\u000a', X11Scancode::DOWN, WindowsScancode::DOWN_ARROW};
static const Key LeftArrow {'\u000a', X11Scancode::LEFT, WindowsScancode::LEFT_ARROW};
static const Key RightArrow {'\u000a', X11Scancode::RIGHT, WindowsScancode::RIGHT_ARROW};
static const Key Super {'\000a', X11Scancode::SUPER, WindowsScancode::Nothing};
static const Key Backspace {'\b', X11Scancode::BACKSPACE, WindowsScancode::BACKSPACE};
static const Key LeftBracket {'[', X11Scancode::OPENING_SQUARE_BRACKET, WindowsScancode::LEFT_BRACKET};
static const Key RightBracket {']', X11Scancode::CLOSING_SQUARE_BRACKET, WindowsScancode::RIGHT_BRACKET};
}
class GamepadButton {};
class MouseButton {};
using J3ML::LinearAlgebra::Vector2;
class InputService {
public:
static Vector2 GetLeftJoystick();
static Vector2 GetRightJoystick();
};
namespace GamepadButtons {
static const GamepadButton X;
static const GamepadButton Y;
static const GamepadButton A;
static const GamepadButton B;
}
namespace MouseButtons
{
static const MouseButton Left;
static const MouseButton Right;
static const MouseButton Middle;
static const MouseButton Side1;
static const MouseButton Side2;
}
#if __linux__
static MouseButton GetMouseButtonFromXButton(unsigned int button) {
switch(button) {
case Button1: return MouseButtons::Left;
case Button2: return MouseButtons::Right;
case Button3: return MouseButtons::Middle;
case Button4: return MouseButtons::Side1;
case Button5: return MouseButtons::Side2;
default:
{
throw std::runtime_error("Undefined XButtonCode: " + button);
break;
}
}
}
static Key GetKeyFromX11Scancode(X11Scancode code) {
for (auto& key : Key::GetKeyboard()) {
if (key.x11ScanCode == code)
return key;
}
std::cout << "Unavaliable Scancode: " + std::to_string((int)code) << std::endl;
return Keys::Space;
}
#else
static Key GetKeyFromWindowsScancode(WindowsScancode code) {
for (auto& key : Key::GetKeyboard()) {
if (key.winScanCode == code)
return key;
}
std::cout << "Unavaliable Scancode: " + std::to_string((int)code) << std::endl;
return Keys::Space;
}
#endif

View File

@@ -2,7 +2,17 @@
#include <cstdint>
#include <vector>
#include <memory>
#include "event.h"
#include <Event.h>
#include <functional>
#include <map>
#include <thread>
#include <rewindow/types/key.h>
#if WIN32
#include <windows.h>
#include <windowsx.h>
#include <wingdi.h>
#endif
#if __linux__
#include <X11/Xlib.h>
@@ -11,40 +21,247 @@
#include <GL/glx.h>
#endif
#include <rewindow/types/cursors.h>
using namespace std::chrono_literals;
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 = 3
IN_FOCUS,
FULLSCREEN,
RESIZABLE,
VSYNC,
QUIT,
MAX_FLAG
};
enum class RenderingAPI: uint8_t {
OPENGL = 0,
//Vulkan is unimplemented.
VULKAN = 1,
OPENGL = 0,
//Vulkan is unimplemented.
VULKAN = 1,
};
class RWindow {
private:
bool flags[4];
std::vector<RWindowEvent*> events;
public:
bool getFlag(RWindowFlags flag);
void setFlag(RWindowFlags flag, bool state);
void init(RenderingAPI api, const char* title, int width, int height, bool vsync);
static void setVsyncEnabled(bool b);
void destroyWindow();
void pollEvents();
void setSize(int width, int height);
std::unique_ptr<int[]> getPos();
std::unique_ptr<int[]> getSize();
void setPos(int x, int y);
bool keyDown(SCANCODE scancode);
bool mouseButtonDown(MOUSEBUTTONCODE buttoncode);
KeyDownEvent getEvent(SCANCODE scancode);
MouseButtonDownEvent getEvent(MOUSEBUTTONCODE buttoncode);
static void glSwapBuffers();
//Initialize to false because it's not guaranteed that they will be cleared first
RWindow() : flags(false,false,false,false) {}
enum class KeyState {Pressed, Released};
};
namespace ReWindow
{
using J3ML::LinearAlgebra::Vector2;
class TimestampedEvent {
private:
public:
precision_timestamp Timestamp;
TimestampedEvent() : Timestamp(precision_clock::now())
{ }
};
class RWindowEvent : public TimestampedEvent {
public:
RWindowEvent() : TimestampedEvent() { }
};
const RWindowEvent EmptyRWindowEvent;
namespace WindowEvents
{
class KeyboardState {
public:
std::map<Key, bool> PressedKeys;
};
class GamepadState {
public:
std::map<GamepadButton, bool> PressedButtons;
};
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 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 KeyUpEvent : public KeyboardEvent {
public:
KeyUpEvent(Key key) : KeyboardEvent(key, KeyState::Released) {}
};
class MouseButtonDownEvent : public MouseEvent {
public:
MouseButton Button;
};
class MouseButtonUpEvent : public MouseEvent {
public:
MouseButton Button;
};
class WindowResizeRequestEvent : public RWindowEvent
{
public:
Vector2 Size;
};
}
using namespace WindowEvents;
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;
#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&) {}
#pragma endregion
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();
}
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___
//RWindow(HINSTANCE hInst);
void setRect (int nx, int ny, int nw, int nh) {
setPos(nx, 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[5];
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;
};
class WindowsImplementationRWindow: public RWindow {
};
class X11ImplementationRWindow: public RWindow {
};
}

125
main.cpp
View File

@@ -1,27 +1,102 @@
#include <iostream>
#include "include/rewindow/types/window.h"
#include <rewindow/types/window.h>
Vector2 mouse_pos;
// TODO: Move to J3ML::LinearAlgebra::Vector2
std::ostream& operator<<(std::ostream& os, const Vector2& v) {
return os << "{" << v.x << ", " << v.y << "}";
}
class MyWindow : public ReWindow::RWindow {
public:
MyWindow(const std::string& title, int w, int h) : ReWindow::RWindow(title, w, h)
{}
void OnMouseMove(const ReWindow::MouseMoveEvent& e) override {
}
void OnKeyDown(const ReWindow::KeyDownEvent& e) override {
}
void OnRefresh(float elapsed) override {
glSwapBuffers ();
auto pos = getCursorPos ();
//std::cout << pos.x << ", " << pos.y << std::endl;
#if __linux__
if (isKeyDown(Keys::L)) {
this->setCursorStyle (ReWindow::Cursors::Pencil);
}
else this->setCursorStyle (ReWindow::Cursors::Default);
#else
if (isKeyDown (Keys::L)) {
this->setCursorStyle (ReWindow::Cursors::Cross);
}
else this->setCursorStyle (ReWindow::Cursors::Arrow);
#endif
}
bool OnResizeRequest(const ReWindow::WindowResizeRequestEvent& e) override {
std::cout << "resized to " << e.Size.x << ", " << e.Size.y << std::endl;
return true;
}
};
#if __linux__
int main() {
auto* window = new(RWindow);
window->init(RenderingAPI::OPENGL, "name",1152,864, false);
window->setFlag(RWindowFlags::RESIZABLE, false);
int i;
while (true) {
if (i <= 10)
window->pollEvents();
window->glSwapBuffers();
i++;
std::cout << i << std::endl;
if (window->keyDown(SCANCODE::A)) {
std::cout << "A" << std::endl;
std::cout << (int64_t) window->getEvent(SCANCODE::A).empty() << std::endl;
}
if (window->mouseButtonDown(MOUSEBUTTONCODE::LEFT_CLICK))
std::cout << window->mouseButtonDown(MOUSEBUTTONCODE::LEFT_CLICK) << std::endl;
//std::cout << window->events.size() << std::endl;
//window->resize(800,600);
//std::cout << window->getPos()[1] << std::endl;
//auto* d = new(KeyDownEvent);
//d->key = SCANCODE::A;
//window->events.push_back(d);
}
}
auto* window = new MyWindow("Test Window", 600, 480);
window->setRenderer(RenderingAPI::OPENGL);
window->Open();
// TODO: Cannot set flags until after window is open
// Make this work somehow
window->setFullscreen(false);
window->setVsyncEnabled(false);
window->setResizable(false);
window->OnKeyDownEvent += [&] (ReWindow::KeyDownEvent e)
{
if (e.key == Keys::LeftArrow)
{
std::cout << "Left Arrow Hit" << std::endl;
}
};
while (window->isAlive()) {
window->pollEvents();
window->refresh();
}
}
#endif
#ifdef WIN32
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
int wmain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow) {
auto* window = new MyWindow ("Test Window", 600, 480);
window->raise ();
window->OnKeyDownEvent += [&] (ReWindow::KeyDownEvent e) {
if (e.key == Keys::LeftArrow) {
std::cout << "Left Arrow Hit" << std::endl;
}
};
while (window->isAlive()) {
window->pollEvents();
window->refresh();
}
return 0;
}
#endif

View File

@@ -1,10 +0,0 @@
#include "../include/rewindow/types/event.h"
bool RWindowEvent::empty() {
if (timePoint == EmptyRWindowEvent.timePoint || this->timePoint == EmptyKeyDownEvent.timePoint || this->timePoint == EmptyMouseButtonDownEvent.timePoint)
return true;
return false;
}
std::chrono::high_resolution_clock::time_point RWindowEvent::timeStamp() {
return timePoint;
}

View File

@@ -1,7 +1,23 @@
#include <iostream>
#include "rewindow/types/window.h"
#include <rewindow/types/window.h>
#include <rewindow/data/WindowsScancodes.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/cursorfont.h>
#include <cstdlib>
#include <cstring>
#include <thread>
#include "rewindow/types/cursors.h"
#include "../../include/rewindow/types/window.h"
// TODO: Move all "global" members to be instantiated class members of Window
// Doing this would break the intended "Platform-Specific" Encapsulation
// So should we do derived platform-specific subclasses?
// The intended goal of the ReWindow class is a one-stop object that handles window management on **ALL** platforms
bool vsync = false;
Window window;
XEvent xev;
Display* display = XOpenDisplay(nullptr);
@@ -10,199 +26,386 @@ XVisualInfo* visual;
XSetWindowAttributes xSetWindowAttributes;
XWindowAttributes windowAttributes;
Atom wmDeleteWindow;
// Make it start as floating because fuck tiling WMs
Atom windowTypeAtom;
Atom windowTypeUtilityAtom;
XSizeHints hints;
GLXContext glContext;
PFNGLXSWAPINTERVALEXTPROC _glXSwapIntervalEXT = nullptr; //It causes issues if it's named just "glXSwapIntervalEXT".
void RWindow::init(RenderingAPI api, const char* title, int width, int height, bool sync) {
if (api == RenderingAPI::OPENGL) {
namespace ReWindow {
RWindow::RWindow() {
title = "ReWindow Application";
width = 640;
height = 480;
//RWindow::singleton = this;
}
RWindow::RWindow(const std::string& title, int width, int height) : flags(false,false,false,false) {
this->title = title;
this->width = width;
this->height = height;
//RWindow::singleton = this;
}
RWindow::RWindow(const std::string& title, int width, int height, RenderingAPI renderer) :
title(title), width(width), height(height), renderer(renderer)
{
//RWindow::singleton = this;
}
void RWindow::raise() const { XRaiseWindow(display, window); }
void RWindow::lower() const { XLowerWindow(display, window); }
void RWindow::destroyWindow() {
XDestroySubwindows(display, window);
XAutoRepeatOn(display);
XDestroyWindow(display, window);
delete this;
}
void RWindow::refresh() {
// TODO: Implement refresh time keeping
OnRefresh(0.f);
// TODO: Check if mouse coords have changed, only then fire OnMouseMove event
Vector2 mouse_coords = getCursorPos();
auto eventData = MouseMoveEvent(mouse_coords);
OnMouseMove(eventData);
std::this_thread::sleep_for(1ms);
}
bool RWindow::getFlag(RWindowFlags flag) const
{
if (flags[(int)flag])
return true;
return false;
}
void RWindow::setFlag(RWindowFlags flag, bool state) {
XGetWindowAttributes(display,window,&windowAttributes);
flags[(int) flag] = state;
//Once you've done this you cannot make it resizable again.
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);
}
}
void RWindow::pollEvents() {
while(XPending(display)) {
XNextEvent(display, &xev);
if (xev.type == ClientMessage) {
if (xev.xclient.message_type == XInternAtom(display, "WM_PROTOCOLS", False) &&
static_cast<Atom>(xev.xclient.data.l[0]) == wmDeleteWindow) {
destroyWindow();
exit(0);
}
}
if (xev.type == FocusIn) {
XAutoRepeatOff(display);
//focusGained.Invoke();
RWindowEvent event {};
OnFocusGain(event);
setFlag(RWindowFlags::IN_FOCUS, true);
}
if (xev.type == FocusOut) {
XAutoRepeatOn(display);
//focusLost.Invoke();
RWindowEvent event {};
OnFocusLost(event);
setFlag(RWindowFlags::IN_FOCUS, false);
}
if (xev.type == KeyRelease) {
auto scancode = (X11Scancode) xev.xkey.keycode;
auto key = GetKeyFromX11Scancode(scancode);
liftKey (key);
}
if (xev.type == KeyPress) {
auto scancode = (X11Scancode) xev.xkey.keycode;
auto key = GetKeyFromX11Scancode(scancode);
pressKey (key);
//eventLog.push_back(eventData);
}
if (xev.type == ButtonRelease) {
MouseButton button = GetMouseButtonFromXButton(xev.xbutton.button);
auto eventData = MouseButtonUpEvent();
eventData.Button = button;
OnMouseButtonUp(eventData);
}
if (xev.type == ButtonPress)
{
MouseButton button = GetMouseButtonFromXButton(xev.xbutton.button);
auto eventData = MouseButtonDownEvent();
eventData.Button = button;
OnMouseButtonDown(eventData);
}
if (xev.type == Expose) {
}
// NOTE: This event is functionally useless, as it only informs of the very beginning and end of a mouse movement.
if (xev.type == MotionNotify)
{
//auto eventData = MouseMoveEvent(xev.xmotion.x, xev.xmotion.y);
//OnMouseMove(eventData);
}
if (xev.type == ResizeRequest)
{
auto eventData = WindowResizeRequestEvent();
lastKnownWindowSize = eventData.Size;
eventData.Size = {(float)xev.xresizerequest.width, (float)xev.xresizerequest.height};
lastKnownWindowSize = eventData.Size;
OnResizeRequest(eventData);
}
}
previousKeyboard = currentKeyboard;
}
// Might make the window go off the screen on some window managers.
void RWindow::setSize(int newWidth, int newHeight)
{
if (!getFlag(RWindowFlags::RESIZABLE))
return;
this->width = newWidth;
this->height = newHeight;
XResizeWindow(display, window, width, height);
}
void RWindow::setSize(const Vector2& size)
{
this->width = size.x;
this->height = size.y;
this->setSize(size.x, size.y);
}
Vector2 RWindow::getCursorPos() const {
Window root = XDefaultRootWindow(display);
Window root_return;
Window child_return;
int root_x_ret;
int root_y_ret;
int win_x_ret;
int win_y_ret;
uint32_t mask_return;
unsigned m;
bool mouseAvailable = XQueryPointer(display, window, &root_return, &child_return, &root_x_ret, &root_y_ret, &win_x_ret, &win_y_ret, &mask_return);
if (mouseAvailable)
{
// TODO: process retrieved mouse coordinates
// TODO: normalize coordinates from displaySpace to windowSpace
// TODO: fire mouse movement event
//std::cout << win_x_ret << ", " << win_y_ret << std::endl;
// TODO: Compensate for height of window TitleBar + window border width
float window_border_width = 2;
float window_titlebar_height = 18;
Vector2 mouse_coords_raw = {(float)win_x_ret+window_border_width, (float)win_y_ret+window_titlebar_height};
auto window_pos = getPos();
return mouse_coords_raw - window_pos;
}
return Vector2::Zero;
}
// TODO: implement integer vector2/3 types
Vector2 RWindow::getSize() const
{
XGetWindowAttributes(display,window,&windowAttributes);
return {(float)windowAttributes.width, (float)windowAttributes.height};
}
// TODO: implement integer vector2/3 types
Vector2 RWindow::getPos() const
{
XGetWindowAttributes(display,window,&windowAttributes);
return {(float)windowAttributes.x, (float)windowAttributes.y};
}
void RWindow::setPos(int x, int y)
{
XMoveWindow(display, window, x, y);
}
void RWindow::setPos(const Vector2& pos)
{
this->setPos(pos.x, pos.y);
}
void RWindow::glSwapBuffers() {
glXSwapBuffers(display,window);
}
bool RWindow::isResizable() const {
return this->getFlag(RWindowFlags::RESIZABLE);
}
bool RWindow::isAlive() const {
return true;
}
void RWindow::setResizable(bool resizable) {
this->resizable = resizable;
this->setFlag(RWindowFlags::RESIZABLE, resizable);
}
void RWindow::setFullscreen(bool fs) {
if (fs)
fullscreen();
else
restoreFromFullscreen();
}
void RWindow::fullscreen() {
fullscreenmode = true;
XEvent xev;
Atom wm_state = XInternAtom (display, "_NET_WM_STATE", true );
Atom wm_fullscreen = XInternAtom (display, "_NET_WM_STATE_FULLSCREEN", true );
XChangeProperty(display, window, wm_state, XA_ATOM, 32,
PropModeReplace, (unsigned char *)&wm_fullscreen, 1);
memset(&xev, 0, sizeof(xev));
xev.type = ClientMessage;
xev.xclient.window = window;
xev.xclient.message_type = wm_state;
xev.xclient.format = 32;
xev.xclient.data.l[0] = 1; // _NET_WM_STATE_ADD
xev.xclient.data.l[1] = fullscreenmode;
xev.xclient.data.l[2] = 0;
XSendEvent(display, DefaultRootWindow(display), False,
SubstructureNotifyMask | SubstructureRedirectMask, &xev);
}
void RWindow::restoreFromFullscreen() {
fullscreenmode = false;
XEvent xev;
Atom wm_state = XInternAtom(display, "_NET_WM_STATE", False);
Atom fullscreen = XInternAtom(display, "_NET_WM_STATE_FULLSCREEN", False);
memset(&xev, 0, sizeof(xev));
xev.type = ClientMessage;
xev.xclient.window = window;
xev.xclient.message_type = wm_state;
xev.xclient.format = 32;
xev.xclient.data.l[0] = 0; // _NET_WM_STATE_REMOVE
xev.xclient.data.l[1] = fullscreenmode;
xev.xclient.data.l[2] = 0;
XSendEvent(display, DefaultRootWindow(display), False,
SubstructureNotifyMask | SubstructureRedirectMask, &xev);
}
void RWindow::setVsyncEnabled(bool b) {
PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT;
glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddressARB((const GLubyte*)"glXSwapIntervalEXT");
glXSwapIntervalEXT(display, window, b);
}
bool RWindow::isFullscreen() const {
return fullscreenmode;
}
void 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);
}
void RWindow::Open() {
xSetWindowAttributes.border_pixel = BlackPixel(display, defaultScreen);
xSetWindowAttributes.background_pixel = BlackPixel(display, defaultScreen);
xSetWindowAttributes.override_redirect = True;
xSetWindowAttributes.event_mask = ExposureMask;
GLint glAttributes[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None};
visual = glXChooseVisual(display, defaultScreen, glAttributes);
glContext = glXCreateContext(display, visual, nullptr, GL_TRUE);
vsync = sync;
//setVsyncEnabled(vsync);
if (renderer == RenderingAPI::OPENGL)
{
GLint glAttributes[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None};
visual = glXChooseVisual(display, defaultScreen, glAttributes);
glContext = glXCreateContext(display, visual, nullptr, GL_TRUE);
}
xSetWindowAttributes.colormap = XCreateColormap(display, RootWindow(display, defaultScreen), visual->visual,
AllocNone);
window = XCreateWindow(display, RootWindow(display, defaultScreen), 0, 0, width, height, 0, visual->depth,
InputOutput, visual->visual, CWBackPixel | CWColormap | CWBorderPixel | NoEventMask,
&xSetWindowAttributes);
// Set window to floating because fucking tiling WMs
windowTypeAtom = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
windowTypeUtilityAtom = XInternAtom(display, "_NET_WM_WINDOW_TYPE_UTILITY", False);
XChangeProperty(display, window, windowTypeAtom, XA_ATOM, 32, PropModeReplace,
(unsigned char *)&windowTypeUtilityAtom, 1);
//
XSelectInput(display, window,
ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
Button1MotionMask | Button2MotionMask | Button3MotionMask | Button4MotionMask | Button5MotionMask |
PointerMotionMask |
PointerMotionHintMask | FocusChangeMask | StructureNotifyMask | SubstructureRedirectMask |
SubstructureNotifyMask | CWColormap);
SubstructureNotifyMask | CWColormap | ResizeRequest | ResizeRedirectMask);
XMapWindow(display, window);
XStoreName(display, window, title);
XStoreName(display, window, title.c_str());
wmDeleteWindow = XInternAtom(display, "WM_DELETE_WINDOW", False);
XSetWMProtocols(display, window, &wmDeleteWindow, 1);
glXMakeCurrent(display, window, glContext);
setVsyncEnabled(vsync);
} else {exit(0);}
}
if (renderer == RenderingAPI::OPENGL)
{
glXMakeCurrent(display, window, glContext);
}
void RWindow::destroyWindow() {
XDestroySubwindows(display, window);
XAutoRepeatOn(XOpenDisplay(nullptr));
XDestroyWindow(display, window);
delete this;
}
//setVsyncEnabled(vsync);
bool RWindow::getFlag(RWindowFlags flag) {
if (flags[(int)flag])
return true;
return false;
}
void RWindow::setFlag(RWindowFlags flag, bool state) {
XGetWindowAttributes(display,window,&windowAttributes);
flags[(int) flag] = state;
//Once you've done this you cannot make it resizable again.
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);
open = true;
}
}
void RWindow::pollEvents() {
while(XPending(display)) {
XNextEvent(display, &xev);
if (xev.type == ClientMessage) {
if (xev.xclient.message_type == XInternAtom(display, "WM_PROTOCOLS", False) &&
static_cast<Atom>(xev.xclient.data.l[0]) == wmDeleteWindow) {
destroyWindow();
exit(0);
}
}
if (xev.type == FocusIn) {
XAutoRepeatOff(display);
setFlag(RWindowFlags::IN_FOCUS, true);
}
if (xev.type == FocusOut) {
XAutoRepeatOn(display);
setFlag(RWindowFlags::IN_FOCUS, false);
}
if (xev.type == KeyRelease) {
for (unsigned int i = 0; i < events.size(); i++) {
if (auto *e = dynamic_cast<KeyDownEvent *>(events[i])) {
if ((int) e->key == (int) xev.xkey.keycode) {
delete events[i];
events.erase(events.begin() + i);
}
}
}
}
if (xev.type == KeyPress) {
//On Windows you'll have to do this the long way.
//The keycodes won't be the same :shrug:
auto *kD = new(KeyDownEvent);
kD->key = (SCANCODE) xev.xkey.keycode;
events.push_back(kD);
}
if (xev.type == ButtonRelease) {
for (unsigned int i = 0; i < events.size(); i++) {
if (auto *e = dynamic_cast<MouseButtonDownEvent *>(events[i])) {
if ((int) e->button == (int) xev.xbutton.button) {
delete events[i];
events.erase(events.begin() + i);
}
}
}
}
if (xev.type == ButtonPress) {
std::cout << (int) xev.xbutton.button << std::endl;
auto *mBD = new(MouseButtonDownEvent);
mBD->button = (MOUSEBUTTONCODE) xev.xbutton.button;
events.push_back(mBD);
}
if (xev.type == Expose) {
}
void RWindow::setTitle(const std::string &title) {
this->title = title;
XStoreName(display, window, title.c_str());
}
}
//Might make the window go off the screen on some window managers.
void RWindow::setSize(int width, int height) {
if (!getFlag(RWindowFlags::RESIZABLE))
return;
XResizeWindow(display, window, width, height);
}
std::unique_ptr<int[]> RWindow::getSize() {
XGetWindowAttributes(display,window,&windowAttributes);
std::unique_ptr<int[]> size = std::make_unique<int[]>(2);
size[0] = windowAttributes.width;
size[1] = windowAttributes.height;
return size;
}
//I'm unsure why this doesn't work as you'd expect.
std::unique_ptr<int[]> RWindow::getPos() {
XGetWindowAttributes(display,window,&windowAttributes);
std::unique_ptr<int[]> pos = std::make_unique<int[]>(2);
pos[0] = windowAttributes.x;
pos[1] = windowAttributes.y;
return pos;
}
void RWindow::setPos(int x, int y) {
XMoveWindow(display, window, x, y);
}
bool RWindow::keyDown(SCANCODE scancode) {
for (auto & ev : events) {
if (auto *e = dynamic_cast<KeyDownEvent *>(ev)) {
if (e->key == scancode) { return true;}
}
std::string RWindow::getTitle() const {
return this->title;
}
return false;
}
KeyDownEvent RWindow::getEvent(SCANCODE scancode) {
for (auto & ev : events) {
if (auto *e = dynamic_cast<KeyDownEvent *>(ev)) {
if (e->key == scancode) { return *e;}
}
bool RWindow::isKeyDown(Key key) const {
if (!currentKeyboard.PressedKeys.contains(key))
return false;
return currentKeyboard.PressedKeys.at(key);
}
return EmptyKeyDownEvent;
}
bool RWindow::mouseButtonDown(MOUSEBUTTONCODE buttoncode) {
for (auto & ev : events) {
if (auto *e = dynamic_cast<MouseButtonDownEvent *>(ev)) {
if (e->button == buttoncode) { return true;}
}
// TODO: Implement MouseButton map
bool RWindow::isMouseButtonDown(MouseButton button) const
{
return false;
}
return false;
}
MouseButtonDownEvent RWindow::getEvent(MOUSEBUTTONCODE buttoncode) {
for (auto & ev : events) {
if (auto *e = dynamic_cast<MouseButtonDownEvent *>(ev)) {
if (e->button == buttoncode) { return *e;}
}
void RWindow::setRenderer(RenderingAPI api) {
renderer = api;
}
return EmptyMouseButtonDownEvent;
}
void RWindow::glSwapBuffers() {
glXSwapBuffers(display,window);
// TODO: Implement ControllerButton map
}
void RWindow::setVsyncEnabled(bool b) {
vsync = b;
_glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddressARB((const GLubyte*)"glXSwapIntervalEXT");
_glXSwapIntervalEXT(display, window, vsync);
}

View File

@@ -0,0 +1,24 @@
#include <rewindow/types/key.h>
std::vector<Key> Key::keyboard = {};
std::vector<Key> Key::GetKeyboard() { return keyboard; }
Key::Key() {
keyboard.push_back(*this);
}
Key::Key(char charcode, X11Scancode scancode, WindowsScancode sc)
: CharCode(charcode), x11ScanCode(scancode), winScanCode(sc)
{
keyboard.push_back(*this);
}
bool Key::operator==(const Key &rhs) const {
return (this->CharCode == rhs.CharCode);
}
bool Key::operator<(const Key &rhs) const {
return (this->CharCode < rhs.CharCode);
}

View File

View File

@@ -1 +1,389 @@
#include "../../include/rewindow/types/window.h"
#include <rewindow/types/window.h>
#include <rewindow/types/cursors.h>
#include <GL/gl.h>
typedef BOOL (APIENTRY* PFNWGLSWAPINTERVALEXTPROC)(int interval);
LRESULT CALLBACK ReWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
ReWindow::RWindow* subject = (ReWindow::RWindow*) GetWindowLongPtrA (hwnd, GWLP_USERDATA);
switch (uMsg) {
case WM_DESTROY:
PostQuitMessage (0);
break;
case WM_SETFOCUS: {
ReWindow::RWindowEvent event {};
subject->OnFocusGain (event);
subject->setFlag (RWindowFlags::IN_FOCUS, true);
break;
}
case WM_KILLFOCUS: {
ReWindow::RWindowEvent event {};
subject->OnFocusLost (event);
subject->setFlag (RWindowFlags::IN_FOCUS, false);
break;
}
case WM_KEYDOWN: {
auto key = GetKeyFromWindowsScancode ((WindowsScancode) wParam);
subject->pressKey (key);
break;
}
case WM_KEYUP: {
auto key = GetKeyFromWindowsScancode ((WindowsScancode) wParam);
subject->liftKey (key);
break;
}
case WM_LBUTTONDOWN: {
auto event = ReWindow::WindowEvents::MouseButtonDownEvent();
event.Button = MouseButtons::Left;
subject->OnMouseButtonDown(event);
break;
}
case WM_RBUTTONDOWN: {
auto event = ReWindow::WindowEvents::MouseButtonDownEvent();
event.Button = MouseButtons::Right;
subject->OnMouseButtonDown(event);
break;
}
case WM_MBUTTONDOWN: {
auto event = ReWindow::WindowEvents::MouseButtonDownEvent();
event.Button = MouseButtons::Middle;
subject->OnMouseButtonDown(event);
break;
}
case WM_LBUTTONUP: {
auto event = ReWindow::WindowEvents::MouseButtonUpEvent();
event.Button = MouseButtons::Left;
subject->OnMouseButtonUp(event);
break;
}
case WM_RBUTTONUP: {
auto event = ReWindow::WindowEvents::MouseButtonUpEvent();
event.Button = MouseButtons::Right;
subject->OnMouseButtonUp(event);
break;
}
case WM_MBUTTONUP: {
auto event = ReWindow::WindowEvents::MouseButtonUpEvent();
event.Button = MouseButtons::Middle;
subject->OnMouseButtonUp(event);
break;
}
case WM_MOUSEMOVE: {
auto event = ReWindow::WindowEvents::MouseMoveEvent (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam));
subject->OnMouseMove(event);
break;
}
case WM_SHOWWINDOW:
if (wParam) {
// as for Expose event in linux
}
break;
case WM_WINDOWPOSCHANGED: {
WINDOWPOS *pos = (WINDOWPOS *) lParam;
subject->setRect (pos->x, pos->y, pos->cx, pos->cy);
auto event = ReWindow::WindowEvents::WindowResizeRequestEvent();
event.Size = {(float) pos->cx, (float) pos->cy};
subject->OnResizeRequest (event);
break;
}
default:
return DefWindowProcA (hwnd, uMsg, wParam, lParam);
}
return TRUE;
}
static HWND hwnd = NULL;
static HDC hdc = NULL;
static ATOM reClass = 0;
static HGLRC glrc = NULL;
static DEVMODEA mode;
void registerClass () {
if (!reClass) {
HINSTANCE module = GetModuleHandleA (NULL);
WNDCLASSA rewc = {CS_HREDRAW | CS_VREDRAW,
ReWindowProc, 0, 0, module, NULL, LoadCursor (NULL, IDC_ARROW),
(HBRUSH) GetStockObject (BLACK_BRUSH), NULL, "ReWindowClass"
};
reClass = RegisterClassA (&rewc);
}
}
ReWindow::RWindow::RWindow() {
registerClass ();
for (int num = 0; num < (int) RWindowFlags::MAX_FLAG; ++num) {
flags[num] = false;
}
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);
}
ReWindow::RWindow::RWindow (const std::string& title, int width, int height) {
registerClass ();
for (int num = 0; num < (int) RWindowFlags::MAX_FLAG; ++num) {
flags[num] = false;
}
hwnd = CreateWindowA ("ReWindowClass", title.c_str (), WS_TILEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, width, height,
NULL, NULL, NULL, 0);
SetWindowLongPtrA (hwnd, GWLP_USERDATA, (LONG_PTR) this);
}
void ReWindow::RWindow::raise() const {
SetForegroundWindow (hwnd);
SetActiveWindow (hwnd);
SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
ShowWindow (hwnd, SW_SHOW);
// Redraw to prevent the window blank
RedrawWindow (hwnd, NULL, 0, RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
}
void ReWindow::RWindow::lower() const {
ShowWindow (hwnd, SW_MINIMIZE);
}
void ReWindow::RWindow::destroyWindow() {
if (hwnd) {
if (hdc) {
if (glrc) {
wglMakeCurrent (NULL, NULL);
wglDeleteContext (glrc);
}
ReleaseDC (hwnd, hdc);
}
DestroyWindow (hwnd);
}
delete this;
}
void ReWindow::RWindow::refresh() {
// TODO: Implement refresh time keeping
OnRefresh (0.f);
// TODO: Check if mouse coords have changed, only then fire OnMouseMove event
Vector2 mouse_coords = getCursorPos();
auto eventData = MouseMoveEvent(mouse_coords);
OnMouseMove(eventData);
std::this_thread::sleep_for(1ms);
}
bool ReWindow::RWindow::getFlag (RWindowFlags flag) const {
return (flags[(int) flag]);
}
void ReWindow::RWindow::setFlag (RWindowFlags flag, bool state) {
DWORD style = GetWindowLongA (hwnd, GWL_STYLE);
flags[(int) flag] = state;
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);
}
}
}
}
void ReWindow::RWindow::pollEvents() {
MSG msg;
while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT) {
setFlag (RWindowFlags::QUIT, true);
}
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
// Might make the window go off the screen on some window managers.
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;
MoveWindow (hwnd, x, y, size.x, size.y, TRUE);
}
Vector2 ReWindow::RWindow::getCursorPos() const {
POINT pos;
GetCursorPos (&pos);
// TODO: normalize coordinates from displaySpace to windowSpace
// TODO: fire mouse movement event
//std::cout << win_x_ret << ", " << win_y_ret << std::endl;
// TODO: Compensate for height of window TitleBar + window border width
Vector2 mouse_coords_raw = {(float) pos.x, (float) pos.y};
auto window_pos = getPos();
return mouse_coords_raw - window_pos;
}
// TODO: implement integer vector2/3 types
Vector2 ReWindow::RWindow::getSize() const {
return {(float) width, (float) height};
}
// TODO: implement integer vector2/3 types
Vector2 ReWindow::RWindow::getPos() const {
return Vector2 ((float) x, (float) y);
}
void ReWindow::RWindow::setPos(int nx, int ny) {
MoveWindow (hwnd, nx, ny, width, height, TRUE);
}
void ReWindow::RWindow::setPos(const Vector2& pos) {
MoveWindow (hwnd, pos.x, pos.y, width, height, TRUE);
}
void ReWindow::RWindow::glSwapBuffers() {
SwapBuffers (hdc);
}
bool ReWindow::RWindow::isResizable() const {
return this->getFlag (RWindowFlags::RESIZABLE);
}
bool ReWindow::RWindow::isAlive() const {
return !getFlag (RWindowFlags::QUIT);
}
void ReWindow::RWindow::setResizable(bool resizable) {
this->resizable = resizable;
this->setFlag(RWindowFlags::RESIZABLE, resizable);
}
void ReWindow::RWindow::setFullscreen(bool fs) {
if (fs) {
fullscreen();
}
else restoreFromFullscreen();
}
void ReWindow::RWindow::fullscreen() {
DEVMODEA screen = {sizeof (DEVMODEA)};
screen.dmBitsPerPel = 32;
screen.dmPelsWidth = width;
screen.dmPelsHeight = height;
screen.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
if (ChangeDisplaySettingsA (&screen, 0) == DISP_CHANGE_SUCCESSFUL) {
fullscreenmode = true;
}
}
void ReWindow::RWindow::restoreFromFullscreen() {
if (ChangeDisplaySettingsA (&mode, 0) == DISP_CHANGE_SUCCESSFUL) {
fullscreenmode = false;
}
}
void ReWindow::RWindow::setVsyncEnabled (bool b) {
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
wglSwapIntervalEXT(b);
}
bool ReWindow::RWindow::isFullscreen() const {
return fullscreenmode;
}
void ReWindow::RWindow::setCursorStyle (CursorStyle style) const {
int idcs[] ={32512, 32513, 32514, 325123, 32649, 32650};
SetClassLongPtr (hwnd, GCLP_HCURSOR, (LONG_PTR) LoadCursor (NULL, MAKEINTRESOURCE (idcs[style.WindowsCursor])));
}
void ReWindow::RWindow::Open() {
if (hwnd) {
hdc = GetDC (hwnd);
PIXELFORMATDESCRIPTOR pfd = {
sizeof (PIXELFORMATDESCRIPTOR),
1, PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW,
PFD_TYPE_RGBA, 24, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 32,
0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0
};
int ipf = ChoosePixelFormat (hdc, &pfd);
if (ipf) {
SetPixelFormat (hdc, ipf, &pfd);
glrc = wglCreateContext (hdc);
if (glrc) {
wglMakeCurrent (hdc, glrc);
EnumDisplaySettingsA (NULL, ENUM_CURRENT_SETTINGS, &mode);
open = true;
}
}
}
}
void ReWindow::RWindow::setTitle (const std::string &title) {
this->title = title;
SetWindowTextA (hwnd, title.c_str ());
}
std::string ReWindow::RWindow::getTitle () const {
return this->title;
}
bool ReWindow::RWindow::isKeyDown (Key key) const {
auto find = currentKeyboard.PressedKeys.find (key);
if (find != currentKeyboard.PressedKeys.end ()) {
return currentKeyboard.PressedKeys.at (key);
}
return false;
}
// TODO: Implement MouseButton map
bool ReWindow::RWindow::isMouseButtonDown(MouseButton button) const {
return false;
}
void ReWindow::RWindow::setRenderer (RenderingAPI api) {
renderer = api;
}