Merge branch 'vulkan' into shader-nodes

This commit is contained in:
Lynix 2020-05-27 20:04:37 +02:00
commit e4348349da
190 changed files with 41400 additions and 5457 deletions

2
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,2 @@
github: [SirLynix]
custom: ['https://paypal.me/sirlynixvanfrietjes']

12
.gitignore vendored
View File

@ -3,6 +3,12 @@ build/config.lua
# Nazara binaries
bin/*
# Build files
build/gmake*/
build/vs*/
# Nazara libraries
lib/*
# Self-hosted thirdparty libraries binaries
@ -166,9 +172,3 @@ DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html

View File

@ -1,6 +1,6 @@
FROM debian:buster
RUN apt-get update && apt-get install -y build-essential clang libopenal-dev libsndfile1-dev libxcb-cursor-dev libxcb-ewmh-dev libxcb-randr0-dev libxcb-icccm4-dev libxcb-keysyms1-dev libx11-dev libfreetype6-dev mesa-common-dev libgl1-mesa-dev libassimp-dev
RUN apt-get update && apt-get install -y build-essential clang libopenal-dev libsndfile1-dev libfreetype6-dev libassimp-dev libsdl2-dev
RUN mkdir /NazaraEngine
WORKDIR /NazaraEngine

View File

@ -409,6 +409,7 @@ function NazaraBuild:Initialize()
if (f) then
MODULE = {}
self:SetupModuleTable(MODULE)
Config = self.Config
f()
@ -551,6 +552,7 @@ function NazaraBuild:LoadConfig()
AddBoolOption("PremakeProject", "premakeproject", "Add a PremakeProject as a shortcut to call Premake")
AddBoolOption("ServerMode", "server", "Excludes client-only modules/tools/examples")
AddBoolOption("UniteModules", "united", "Builds all the modules as one united library")
AddBoolOption("PlatformSDL2", "platform-sdl2", "Use SDL2 instead of native APIs")
-- AdditionalCompilationOptions
do

View File

@ -2,32 +2,17 @@ MODULE.Name = "Platform"
MODULE.ClientOnly = true
MODULE.Defines = {
"NAZARA_PLATFORM_SDL2"
}
MODULE.Libraries = {
"NazaraCore",
"NazaraUtility"
"NazaraUtility",
"SDL2"
}
MODULE.OsFiles.Windows = {
"../src/Nazara/Platform/Win32/**.hpp",
"../src/Nazara/Platform/Win32/**.cpp"
MODULE.Files = {
"../src/Nazara/Platform/SDL2/**.hpp",
"../src/Nazara/Platform/SDL2/**.cpp"
}
MODULE.OsFiles.Posix = {
"../src/Nazara/Platform/X11/**.hpp",
"../src/Nazara/Platform/X11/**.cpp"
}
MODULE.OsLibraries.Windows = {
"gdi32"
}
MODULE.OsLibraries.Posix = {
"X11",
"xcb",
"xcb-cursor",
"xcb-ewmh",
"xcb-icccm",
"xcb-keysyms",
"xcb-randr"
}

View File

@ -13,22 +13,23 @@ MODULE.Libraries = {
}
MODULE.OsFiles.Windows = {
"../src/Nazara/Renderer/Win32/**.hpp",
"../src/Nazara/Renderer/Win32/**.cpp"
"../src/Nazara/Renderer/Win32/**.hpp",
"../src/Nazara/Renderer/Win32/**.cpp"
}
MODULE.OsFiles.Posix = {
"../src/Nazara/Renderer/GLX/**.hpp",
"../src/Nazara/Renderer/GLX/**.cpp"
"../src/Nazara/Renderer/GLX/**.hpp",
"../src/Nazara/Renderer/GLX/**.cpp"
}
MODULE.OsLibraries.Windows = {
"gdi32",
"opengl32",
"winmm"
"gdi32",
"opengl32",
"winmm"
}
MODULE.OsLibraries.Posix = {
"GL",
"X11"
"GL",
"X11"
}

View File

@ -71,7 +71,7 @@ int main()
std::cout << "Sound position: " << pos << std::endl;
// Si la position de la source atteint une certaine position, ou si l'utilisateur appuie sur echap
if (pos.x > Nz::Vector3f::Left().x*-50.f || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Escape))
if (pos.x > Nz::Vector3f::Left().x*-50.f || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Escape))
sound.Stop(); // On arrête le son (Stoppant également la boucle)
clock.Restart();

View File

@ -9,3 +9,7 @@ EXAMPLE.Files = {
EXAMPLE.Libraries = {
"NazaraSDK"
}
if Config.PlatformSDL2 then
table.insert(EXAMPLE.Defines, "NAZARA_PLATFORM_SDL2")
end

View File

@ -266,6 +266,8 @@ int main()
//Gestion des Evenements
Nz::EventHandler& eventHandler = window.GetEventHandler();
Nz::Mouse::SetRelativeMouseMode(true);
eventHandler.OnMouseMoved.Connect([&camAngles, &cameraNode, &window](const Nz::EventHandler*, const Nz::WindowEvent::MouseMoveEvent& event)
{
if (Ndk::Application::Instance()->IsConsoleEnabled())
@ -285,19 +287,14 @@ int main()
// On applique les angles d'Euler à notre caméra
cameraNode.SetRotation(camAngles);
// Pour éviter que le curseur ne sorte de l'écran, nous le renvoyons au centre de la fenétre
// Cette fonction est codée de sorte à ne pas provoquer d'événement MouseMoved
Nz::Vector2ui size = window.GetSize();
Nz::Mouse::SetPosition(size.x / 2, size.y / 2, window);
});
eventHandler.OnKeyPressed.Connect([&targetPos, &cameraNode, &smoothMovement, &window](const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& event)
{
// Une touche a été pressée !
if (event.code == Nz::Keyboard::Key::Escape)
if (event.virtualKey == Nz::Keyboard::VKey::Escape)
window.Close();
else if (event.code == Nz::Keyboard::F1)
else if (event.virtualKey == Nz::Keyboard::VKey::F1)
{
if (smoothMovement)
{
@ -338,34 +335,34 @@ int main()
if (move)
{
// Si la touche espace est enfoncée, notre vitesse de déplacement est multipliée par deux
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Space))
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Space))
cameraSpeed *= 2.f;
// Pour que nos déplacement soient liés à la rotation de la caméra, nous allons utiliser
// les directions locales de la caméra
// Si la flèche du haut ou la touche Z (vive ZQSD !!) est pressée, on avance
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Up) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Z))
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Up) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Z))
targetPos += cameraNode.GetForward() * cameraSpeed;
// Si la flèche du bas ou la touche S est pressée, on recule
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Down) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::S))
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Down) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::S))
targetPos += cameraNode.GetBackward() * cameraSpeed;
// Etc...
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Left) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Q))
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Left) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Q))
targetPos += cameraNode.GetLeft() * cameraSpeed;
// Etc...
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Right) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::D))
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Right) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::D))
targetPos += cameraNode.GetRight() * cameraSpeed;
// Majuscule pour monter, notez l'utilisation d'une direction globale (Non-affectée par la rotation)
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::LShift) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::RShift))
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::LShift) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::RShift))
targetPos += Nz::Vector3f::Up() * cameraSpeed;
// Contrôle (Gauche ou droite) pour descendre dans l'espace global, etc...
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::LControl) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::RControl))
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::LControl) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::RControl))
targetPos += Nz::Vector3f::Down() * cameraSpeed;
}

View File

@ -12,3 +12,6 @@ EXAMPLE.Libraries = {
"NazaraUtility"
}
if Config.PlatformSDL2 then
table.insert(EXAMPLE.Defines, "NAZARA_PLATFORM_SDL2")
end

View File

@ -680,7 +680,8 @@ void SpacebattleExample::Leave(Ndk::StateMachine& fsm)
{
m_ambientMusic.Stop();
m_onMouseMoved.Disconnect();
m_shared.target->SetCursor(Nz::SystemCursor_Default);
if (m_shared.target)
m_shared.target->SetCursor(Nz::SystemCursor_Default);
m_shared.world3D->RemoveSystem<LaserBeamSystem>();
m_shared.world3D->RemoveSystem<SpaceshipSystem>();
m_turretFireSound.Stop();

View File

@ -11,3 +11,7 @@ EXAMPLE.Files = {
EXAMPLE.Libraries = {
"NazaraSDK"
}
if Config.PlatformSDL2 then
table.insert(EXAMPLE.Defines, "NAZARA_PLATFORM_SDL2")
end

View File

@ -123,17 +123,17 @@ int main()
{
case Nz::WindowEventType_KeyPressed:
{
switch (event.key.code)
switch (event.key.virtualKey)
{
case Nz::Keyboard::Backspace:
case Nz::Keyboard::VKey::Backspace:
stateMachine.ChangeState(shared.demos[demoIndex]);
break;
case Nz::Keyboard::Escape:
case Nz::Keyboard::VKey::Escape:
app.Quit();
break;
case Nz::Keyboard::Left:
case Nz::Keyboard::VKey::Left:
{
if (shared.demos.size() <= 1)
break;
@ -146,7 +146,7 @@ int main()
break;
}
case Nz::Keyboard::Right:
case Nz::Keyboard::VKey::Right:
{
if (shared.demos.size() <= 1)
break;
@ -159,14 +159,14 @@ int main()
break;
}
case Nz::Keyboard::Pause:
case Nz::Keyboard::VKey::Pause:
{
auto& velocitySystem = shared.world3D->GetSystem<Ndk::VelocitySystem>();
velocitySystem.Enable(!velocitySystem.IsEnabled());
break;
}
case Nz::Keyboard::F5:
case Nz::Keyboard::VKey::F5:
{
Nz::Image screenshot;
screenshot.Create(Nz::ImageType_2D, Nz::PixelFormat_RGBA8, 1920, 1080);
@ -197,5 +197,7 @@ int main()
window.Display();
}
shared.target = nullptr;
return EXIT_SUCCESS;
}

View File

@ -18,3 +18,7 @@ EXAMPLE.Libraries = {
"NazaraUtility",
"NazaraSDK"
}
if Config.PlatformSDL2 then
table.insert(EXAMPLE.Defines, "NAZARA_PLATFORM_SDL2")
end

View File

@ -9,3 +9,7 @@ EXAMPLE.Files = {
EXAMPLE.Libraries = {
"NazaraSDK"
}
if Config.PlatformSDL2 then
table.insert(EXAMPLE.Defines, "NAZARA_PLATFORM_SDL2")
end

View File

@ -9,3 +9,7 @@ EXAMPLE.Files = {
EXAMPLE.Libraries = {
"NazaraSDK"
}
if Config.PlatformSDL2 then
table.insert(EXAMPLE.Defines, "NAZARA_PLATFORM_SDL2")
end

View File

@ -33,10 +33,10 @@ int main(int argc, char* argv[])
Nz::EventHandler& eventHandler = mainWindow.GetEventHandler();
eventHandler.OnKeyPressed.Connect([](const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& e)
{
std::cout << Nz::Keyboard::GetKeyName(e.code) << std::endl;
std::cout << Nz::Keyboard::GetKeyName(e.virtualKey) << std::endl;
// Profitons-en aussi pour nous donner un moyen de quitter le programme
if (e.code == Nz::Keyboard::Escape)
if (e.virtualKey == Nz::Keyboard::VKey::Escape)
Ndk::Application::Instance()->Quit(); // Cette ligne casse la boucle Run() de l'application
});

View File

@ -3,7 +3,7 @@
#include <array>
#include <iostream>
#define SPIRV 0
#define SPIRV 1
int main()
{
@ -266,27 +266,27 @@ int main()
float cameraSpeed = 2.f * updateClock.GetSeconds();
updateClock.Restart();
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Up) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Z))
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Up) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Z))
viewerPos += camQuat * Nz::Vector3f::Forward() * cameraSpeed;
// Si la flèche du bas ou la touche S est pressée, on recule
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Down) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::S))
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Down) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::S))
viewerPos += camQuat * Nz::Vector3f::Backward() * cameraSpeed;
// Etc...
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Left) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Q))
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Left) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Q))
viewerPos += camQuat * Nz::Vector3f::Left() * cameraSpeed;
// Etc...
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Right) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::D))
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Right) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::D))
viewerPos += camQuat * Nz::Vector3f::Right() * cameraSpeed;
// Majuscule pour monter, notez l'utilisation d'une direction globale (Non-affectée par la rotation)
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::LShift) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::RShift))
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::LShift) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::RShift))
viewerPos += Nz::Vector3f::Up() * cameraSpeed;
// Contrôle (Gauche ou droite) pour descendre dans l'espace global, etc...
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::LControl) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::RControl))
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::LControl) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::RControl))
viewerPos += Nz::Vector3f::Down() * cameraSpeed;
}

View File

@ -136,6 +136,8 @@ namespace Nz
{
friend CullingList;
using ParentType = Entry<CullTest::Box>;
public:
BoxEntry();
BoxEntry(BoxEntry&&) = default;
@ -154,6 +156,8 @@ namespace Nz
{
friend CullingList;
using ParentType = Entry<CullTest::NoTest>;
public:
NoTestEntry();
NoTestEntry(NoTestEntry&&) = default;
@ -170,6 +174,8 @@ namespace Nz
{
friend CullingList;
using ParentType = Entry<CullTest::Sphere>;
public:
SphereEntry();
SphereEntry(SphereEntry&&) = default;
@ -188,6 +194,8 @@ namespace Nz
{
friend CullingList;
using ParentType = Entry<CullTest::Volume>;
public:
VolumeEntry();
VolumeEntry(VolumeEntry&&) = default;

View File

@ -424,13 +424,13 @@ namespace Nz
template<typename T>
CullingList<T>::BoxEntry::BoxEntry() :
Entry<CullTest::Box>()
ParentType()
{
}
template<typename T>
CullingList<T>::BoxEntry::BoxEntry(CullingList* parent, std::size_t index) :
Entry<CullTest::Box>(parent, index)
ParentType(parent, index)
{
}
@ -444,13 +444,13 @@ namespace Nz
template<typename T>
CullingList<T>::NoTestEntry::NoTestEntry() :
Entry<CullTest::NoTest>()
ParentType()
{
}
template<typename T>
CullingList<T>::NoTestEntry::NoTestEntry(CullingList* parent, std::size_t index) :
Entry<CullTest::NoTest>(parent, index)
ParentType(parent, index)
{
}
@ -458,13 +458,13 @@ namespace Nz
template<typename T>
CullingList<T>::SphereEntry::SphereEntry() :
Entry<CullTest::Sphere>()
ParentType()
{
}
template<typename T>
CullingList<T>::SphereEntry::SphereEntry(CullingList* parent, std::size_t index) :
Entry<CullTest::Sphere>(parent, index)
ParentType(parent, index)
{
}
@ -478,13 +478,13 @@ namespace Nz
template<typename T>
CullingList<T>::VolumeEntry::VolumeEntry() :
Entry<CullTest::Volume>()
ParentType()
{
}
template<typename T>
CullingList<T>::VolumeEntry::VolumeEntry(CullingList* parent, std::size_t index) :
Entry<CullTest::Volume>(parent, index)
ParentType(parent, index)
{
}

View File

@ -28,8 +28,6 @@ namespace Nz
std::shared_ptr<RenderDevice> InstanciateRenderDevice(std::size_t deviceIndex) override;
bool IsBetterThan(const RendererImpl* other) const override;
RenderAPI QueryAPI() const override;
std::string QueryAPIString() const override;
UInt32 QueryAPIVersion() const override;

View File

@ -51,6 +51,7 @@ namespace Nz
WindowEventType_Moved,
WindowEventType_Quit,
WindowEventType_Resized,
WindowEventType_TextEdited,
WindowEventType_TextEntered,
WindowEventType_Max = WindowEventType_TextEntered

View File

@ -9,6 +9,8 @@
#ifndef NAZARA_EVENT_HPP
#define NAZARA_EVENT_HPP
#include <array>
#include <Nazara/Platform/Enums.hpp>
#include <Nazara/Platform/Keyboard.hpp>
#include <Nazara/Platform/Mouse.hpp>
@ -22,7 +24,8 @@ namespace Nz
// -WindowEventType_KeyReleased
struct KeyEvent
{
Keyboard::Key code;
Keyboard::Scancode scancode;
Keyboard::VKey virtualKey;
bool alt;
bool control;
bool repeated;
@ -83,6 +86,14 @@ namespace Nz
char32_t character;
};
// Used by:
// -WindowEventType_TextEdited
struct EditEvent
{
int length;
std::array<char, 32> text;
};
WindowEventType type;
union
@ -116,6 +127,10 @@ namespace Nz
// Used by:
// -WindowEventType_TextEntered
TextEvent text;
// Used by:
// -WindowEventType_TextEntered
EditEvent edit;
};
};
}

View File

@ -49,6 +49,7 @@ namespace Nz
NazaraSignal(OnQuit, const EventHandler* /*eventHandler*/);
NazaraSignal(OnResized, const EventHandler* /*eventHandler*/, const WindowEvent::SizeEvent& /*event*/);
NazaraSignal(OnTextEntered, const EventHandler* /*eventHandler*/, const WindowEvent::TextEvent& /*event*/);
NazaraSignal(OnTextEdited, const EventHandler* /*eventHandler*/, const WindowEvent::EditEvent& /*event*/);
};
}

View File

@ -78,6 +78,10 @@ namespace Nz
case WindowEventType_TextEntered:
OnTextEntered(this, event.text);
break;
case WindowEventType_TextEdited:
OnTextEdited(this, event.edit);
break;
}
}
}

View File

@ -18,7 +18,7 @@ namespace Nz
class NAZARA_PLATFORM_API Keyboard
{
public:
enum Key
enum class Scancode
{
Undefined = -1,
@ -78,6 +78,7 @@ namespace Nz
Decimal,
Divide,
Multiply,
NumpadReturn,
Numpad0,
Numpad1,
Numpad2,
@ -135,6 +136,8 @@ namespace Nz
Space,
Tab,
Tilde,
Menu,
ISOBackslash102,
// Navigator keys
Browser_Back,
@ -161,14 +164,169 @@ namespace Nz
NumLock,
ScrollLock,
Count
Max = ScrollLock
};
enum class VKey
{
Undefined = -1,
// Lettres
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
// Functional keys
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
F13,
F14,
F15,
// Directional keys
Down,
Left,
Right,
Up,
// Numerical pad
Add,
Decimal,
Divide,
Multiply,
NumpadReturn,
Numpad0,
Numpad1,
Numpad2,
Numpad3,
Numpad4,
Numpad5,
Numpad6,
Numpad7,
Numpad8,
Numpad9,
Subtract,
// Various
Backslash,
Backspace,
Clear,
Comma,
Dash,
Delete,
End,
Equal,
Escape,
Home,
Insert,
LAlt,
LBracket,
LControl,
LShift,
LSystem,
Num0,
Num1,
Num2,
Num3,
Num4,
Num5,
Num6,
Num7,
Num8,
Num9,
PageDown,
PageUp,
Pause,
Period,
Print,
PrintScreen,
Quote,
RAlt,
RBracket,
RControl,
Return,
RShift,
RSystem,
Semicolon,
Slash,
Space,
Tab,
Tilde,
Menu,
ISOBackslash102,
// Navigator keys
Browser_Back,
Browser_Favorites,
Browser_Forward,
Browser_Home,
Browser_Refresh,
Browser_Search,
Browser_Stop,
// Lecture control keys
Media_Next,
Media_Play,
Media_Previous,
Media_Stop,
// Volume control keys
Volume_Down,
Volume_Mute,
Volume_Up,
// Locking keys
CapsLock,
NumLock,
ScrollLock,
Max = ScrollLock
};
Keyboard() = delete;
~Keyboard() = delete;
static String GetKeyName(Key key);
static bool IsKeyPressed(Key key);
static String GetKeyName(Scancode scancode);
static String GetKeyName(VKey key);
static bool IsKeyPressed(Scancode scancode);
static bool IsKeyPressed(VKey key);
static void StartTextInput();
static void StopTextInput();
static Scancode ToScanCode(VKey key);
static VKey ToVirtualKey(Scancode key);
};
}

View File

@ -37,6 +37,7 @@ namespace Nz
static Vector2i GetPosition();
static Vector2i GetPosition(const Window& relativeTo);
static bool IsButtonPressed(Button button);
static bool SetRelativeMouseMode(bool relativeMouseMode);
static void SetPosition(const Vector2i& position);
static void SetPosition(const Vector2i& position, const Window& relativeTo, bool ignoreEvent = true);
static void SetPosition(int x, int y);

View File

@ -32,12 +32,12 @@ namespace Nz
static const std::vector<VideoMode>& GetFullscreenModes();
};
bool operator==(const VideoMode& left, const VideoMode& right);
bool operator!=(const VideoMode& left, const VideoMode& right);
bool operator<(const VideoMode& left, const VideoMode& right);
bool operator<=(const VideoMode& left, const VideoMode& right);
bool operator>(const VideoMode& left, const VideoMode& right);
bool operator>=(const VideoMode& left, const VideoMode& right);
bool NAZARA_PLATFORM_API operator==(const VideoMode& left, const VideoMode& right);
bool NAZARA_PLATFORM_API operator!=(const VideoMode& left, const VideoMode& right);
bool NAZARA_PLATFORM_API operator<(const VideoMode& left, const VideoMode& right);
bool NAZARA_PLATFORM_API operator<=(const VideoMode& left, const VideoMode& right);
bool NAZARA_PLATFORM_API operator>(const VideoMode& left, const VideoMode& right);
bool NAZARA_PLATFORM_API operator>=(const VideoMode& left, const VideoMode& right);
}
#endif // NAZARA_VIDEOMODE_HPP

View File

@ -32,13 +32,14 @@ namespace Nz
class NAZARA_PLATFORM_API Window
{
friend WindowImpl;
friend class EventImpl;
friend class Mouse;
friend class Platform;
public:
Window();
inline Window(VideoMode mode, const String& title, WindowStyleFlags style = WindowStyle_Default);
inline explicit Window(WindowHandle handle);
inline explicit Window(void* handle);
Window(const Window&) = delete;
Window(Window&& window);
virtual ~Window();
@ -46,7 +47,7 @@ namespace Nz
inline void Close();
bool Create(VideoMode mode, const String& title, WindowStyleFlags style = WindowStyle_Default);
bool Create(WindowHandle handle);
bool Create(void* handle);
void Destroy();
@ -61,10 +62,10 @@ namespace Nz
inline const CursorRef& GetCursor() const;
inline CursorController& GetCursorController();
inline EventHandler& GetEventHandler();
WindowHandle GetHandle() const;
Vector2i GetPosition() const;
Vector2ui GetSize() const;
WindowStyleFlags GetStyle() const;
WindowHandle GetSystemHandle() const;
String GetTitle() const;
bool HasFocus() const;
@ -106,6 +107,8 @@ namespace Nz
Window& operator=(Window&& window);
protected:
void* GetHandle();
virtual bool OnWindowCreated();
virtual void OnWindowDestroy();
virtual void OnWindowResized();
@ -116,6 +119,9 @@ namespace Nz
void ConnectSlots();
void DisconnectSlots();
inline WindowImpl* GetImpl();
inline const WindowImpl* GetImpl() const;
void IgnoreNextMouseEvent(int mouseX, int mouseY) const;
void HandleEvent(const WindowEvent& event);

View File

@ -19,7 +19,7 @@ namespace Nz
Create(mode, title, style);
}
inline Window::Window(WindowHandle handle) :
inline Window::Window(void* handle) :
Window()
{
ErrorFlags flags(ErrorFlag_ThrowException, true);
@ -109,6 +109,16 @@ namespace Nz
}
}
}
inline WindowImpl* Window::GetImpl()
{
return m_impl;
}
inline const WindowImpl* Window::GetImpl() const
{
return m_impl;
}
}
#include <Nazara/Platform/DebugOff.hpp>

View File

@ -8,21 +8,44 @@
#define NAZARA_WINDOWHANDLE_HPP
#include <Nazara/Prerequisites.hpp>
#if defined(NAZARA_PLATFORM_X11)
#include <xcb/xcb.h>
#endif
#include <Nazara/Utility/Config.hpp>
namespace Nz
{
#if defined(NAZARA_PLATFORM_WINDOWS)
// http://msdn.microsoft.com/en-us/library/aa383751(v=vs.85).aspx
using WindowHandle = void*;
#elif defined(NAZARA_PLATFORM_X11)
// http://en.wikipedia.org/wiki/Xlib#Data_types
using WindowHandle = xcb_window_t;
#else
#error Lack of implementation: WindowHandle
#endif
enum class WindowManager
{
None,
X11,
Wayland,
Windows
};
struct WindowHandle
{
WindowManager type = WindowManager::None;
union
{
struct
{
void* display; //< Display*
void* window; //< Window
} x11;
struct
{
void* display; //< wl_display*
void* surface; //< wl_surface*
void* shellSurface; //< wl_shell_surface*
} wayland;
struct
{
void* window; //< HWND
} windows;
};
};
}
#endif // NAZARA_WINDOWHANDLE_HPP

View File

@ -117,21 +117,17 @@
#endif
#elif defined(__linux__) || defined(__unix__)
#define NAZARA_PLATFORM_LINUX
#define NAZARA_PLATFORM_GLX
#define NAZARA_PLATFORM_POSIX
#define NAZARA_PLATFORM_X11
#define NAZARA_EXPORT __attribute__((visibility ("default")))
#define NAZARA_IMPORT __attribute__((visibility ("default")))
/*#elif defined(__APPLE__) && defined(__MACH__)
#define NAZARA_CORE_API
#define NAZARA_PLATFORM_MACOSX
#define NAZARA_PLATFORM_POSIX*/
#define NAZARA_PLATFORM_MACOSX
#define NAZARA_PLATFORM_POSIX*/
#else
#error This operating system is not fully supported by the Nazara Engine
#define NAZARA_PLATFORM_UNKNOWN
#define NAZARA_CORE_API
#endif
// Detect 64 bits

View File

@ -25,26 +25,26 @@ namespace Nz
{
public:
inline RenderWindow();
inline RenderWindow(VideoMode mode, const String& title, WindowStyleFlags style = WindowStyle_Default, const RenderWindowParameters& parameters = RenderWindowParameters());
inline explicit RenderWindow(WindowHandle handle, const RenderWindowParameters& parameters = RenderWindowParameters());
inline RenderWindow(VideoMode mode, const String &title, WindowStyleFlags style = WindowStyle_Default, const RenderWindowParameters &parameters = RenderWindowParameters());
inline explicit RenderWindow(void* handle, const RenderWindowParameters &parameters = RenderWindowParameters());
inline ~RenderWindow();
inline bool Create(VideoMode mode, const String& title, WindowStyleFlags style = WindowStyle_Default, const RenderWindowParameters& parameters = RenderWindowParameters());
inline bool Create(WindowHandle handle, const RenderWindowParameters& parameters = RenderWindowParameters());
inline bool Create(VideoMode mode, const String &title, WindowStyleFlags style = WindowStyle_Default, const RenderWindowParameters &parameters = RenderWindowParameters());
inline bool Create(void* handle, const RenderWindowParameters &parameters = RenderWindowParameters());
void Display();
void EnableVerticalSync(bool enabled);
inline RenderWindowImpl* GetImpl();
inline RenderWindowImpl *GetImpl();
std::shared_ptr<RenderDevice> GetRenderDevice();
inline bool IsValid() const;
inline void SetFramerateLimit(unsigned int limit);
RenderWindow& operator=(const RenderWindow&) = delete;
RenderWindow& operator=(RenderWindow&&) = delete; ///TODO
RenderWindow &operator=(const RenderWindow &) = delete;
RenderWindow &operator=(RenderWindow &&) = delete; ///TODO
protected:
bool OnWindowCreated() override;
@ -57,8 +57,8 @@ namespace Nz
std::unique_ptr<RenderSurface> m_surface;
RenderWindowParameters m_parameters;
unsigned int m_framerateLimit;
};
}
};
} // namespace Nz
#include <Nazara/Renderer/RenderWindow.inl>

View File

@ -20,7 +20,7 @@ namespace Nz
Create(mode, title, style, parameters);
}
inline RenderWindow::RenderWindow(WindowHandle handle, const RenderWindowParameters& parameters)
inline RenderWindow::RenderWindow(void* handle, const RenderWindowParameters& parameters)
{
ErrorFlags errFlags(ErrorFlag_ThrowException, true);
@ -39,7 +39,7 @@ namespace Nz
return Window::Create(mode, title, style);
}
inline bool RenderWindow::Create(WindowHandle handle, const RenderWindowParameters& parameters)
inline bool RenderWindow::Create(void* handle, const RenderWindowParameters& parameters)
{
m_parameters = parameters;

View File

@ -38,8 +38,6 @@ namespace Nz
virtual std::shared_ptr<RenderDevice> InstanciateRenderDevice(std::size_t deviceIndex) = 0;
virtual bool IsBetterThan(const RendererImpl* other) const = 0;
virtual RenderAPI QueryAPI() const = 0;
virtual std::string QueryAPIString() const = 0;
virtual UInt32 QueryAPIVersion() const = 0;

View File

@ -24,11 +24,11 @@ namespace Nz
inline SimpleTextDrawer::SimpleTextDrawer(const SimpleTextDrawer& drawer) :
m_color(drawer.m_color),
m_outlineColor(drawer.m_outlineColor),
m_text(drawer.m_text),
m_style(drawer.m_style),
m_colorUpdated(false),
m_glyphUpdated(false),
m_outlineColor(drawer.m_outlineColor),
m_characterSpacingOffset(drawer.m_characterSpacingOffset),
m_lineSpacingOffset(drawer.m_lineSpacingOffset),
m_maxLineWidth(drawer.m_maxLineWidth),

View File

@ -30,8 +30,6 @@ namespace Nz
std::shared_ptr<RenderDevice> InstanciateRenderDevice(std::size_t deviceIndex) override;
bool IsBetterThan(const RendererImpl* other) const override;
RenderAPI QueryAPI() const override;
std::string QueryAPIString() const override;
UInt32 QueryAPIVersion() const override;

View File

@ -75,6 +75,7 @@ namespace Ndk
bool HasFocus() const;
inline void Hide();
inline bool IsVisible() const;
void Resize(const Nz::Vector2f& size);
@ -125,9 +126,12 @@ namespace Ndk
virtual void OnMouseExit();
virtual void OnParentResized(const Nz::Vector2f& newSize);
virtual void OnTextEntered(char32_t character, bool repeated);
virtual void OnTextEdited(const std::array<char, 32>& characters, int length);
inline void SetPreferredSize(const Nz::Vector2f& preferredSize);
virtual void ShowChildren(bool show);
private:
inline BaseWidget();

View File

@ -172,6 +172,11 @@ namespace Ndk
return m_children.size();
}
inline void BaseWidget::Hide()
{
return Show(false);
}
inline bool BaseWidget::IsVisible() const
{
return m_visible;

View File

@ -57,6 +57,7 @@ namespace Ndk
void OnEventKeyPressed(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::KeyEvent& event);
void OnEventKeyReleased(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::KeyEvent& event);
void OnEventTextEntered(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::TextEvent& event);
void OnEventTextEdited(const Nz::EventHandler* eventHandler, const Nz::WindowEvent::EditEvent& event);
struct WidgetEntry
{
@ -73,6 +74,7 @@ namespace Ndk
NazaraSlot(Nz::EventHandler, OnMouseMoved, m_mouseMovedSlot);
NazaraSlot(Nz::EventHandler, OnMouseWheelMoved, m_mouseWheelMovedSlot);
NazaraSlot(Nz::EventHandler, OnTextEntered, m_textEnteredSlot);
NazaraSlot(Nz::EventHandler, OnTextEdited, m_textEditedSlot);
std::size_t m_keyboardOwner;
std::size_t m_hoveredWidget;

View File

@ -28,6 +28,7 @@ namespace Ndk
m_mouseMovedSlot.Connect(eventHandler.OnMouseMoved, this, &Canvas::OnEventMouseMoved);
m_mouseWheelMovedSlot.Connect(eventHandler.OnMouseWheelMoved, this, &Canvas::OnEventMouseWheelMoved);
m_textEnteredSlot.Connect(eventHandler.OnTextEntered, this, &Canvas::OnEventTextEntered);
m_textEditedSlot.Connect(eventHandler.OnTextEdited, this, &Canvas::OnEventTextEdited);
}
inline Canvas::~Canvas()

View File

@ -20,7 +20,8 @@ namespace Ndk
*
* \param physics PhysicsComponent2D to copy
*/
inline PhysicsComponent2D::PhysicsComponent2D(const PhysicsComponent2D& physics)
inline PhysicsComponent2D::PhysicsComponent2D(const PhysicsComponent2D& physics) :
m_nodeSynchronizationEnabled(physics.m_nodeSynchronizationEnabled)
{
CopyPhysicsState(*physics.GetRigidBody());
}

View File

@ -55,7 +55,7 @@ namespace Ndk
World* m_world;
};
class NDK_API EntityList::iterator : public std::iterator<std::forward_iterator_tag, const EntityHandle>
class NDK_API EntityList::iterator
{
friend EntityList;
@ -73,6 +73,12 @@ namespace Ndk
friend inline void swap(iterator& lhs, iterator& rhs);
using difference_type = std::ptrdiff_t;
using iterator_category = std::forward_iterator_tag;
using pointer = EntityHandle*;
using reference = EntityHandle&;
using value_type = EntityHandle;
private:
inline iterator(const EntityList* world, std::size_t nextId);

View File

@ -15,6 +15,6 @@ namespace Nz
void DummySurface::Destroy()
{
m_handle = nullptr;
m_handle = WindowHandle{};
}
}

View File

@ -42,14 +42,6 @@ namespace Nz
return m_device;
}
bool OpenGLRenderer::IsBetterThan(const RendererImpl* other) const
{
if (other->QueryAPI() == RenderAPI::OpenGL && QueryAPIVersion() > other->QueryAPIVersion())
return true;
return false; //< OpenGL is mostly a fallback to other renderers
}
bool OpenGLRenderer::Prepare(const ParameterList& parameters)
{
if (!m_opengl32Lib.Load("opengl32" NAZARA_DYNLIB_EXTENSION))

View File

@ -29,12 +29,21 @@ namespace Nz::GL
::ShowWindow(m_window.get(), FALSE);
return Create(baseContext, params, m_window.get(), shareContext);
m_deviceContext = ::GetDC(m_window.get());
if (!m_deviceContext)
{
NazaraError("failed to retrieve dummy window device context: " + Error::GetLastSystemError());
return false;
}
return CreateInternal(baseContext, params, shareContext);
}
bool WGLContext::Create(const WGLContext* baseContext, const ContextParams& params, WindowHandle window, const WGLContext* shareContext)
{
m_deviceContext = ::GetDC(static_cast<HWND>(window));
NazaraAssert(window.type == WindowManager::Windows, "expected Windows window");
m_deviceContext = ::GetDC(static_cast<HWND>(window.windows.window));
if (!m_deviceContext)
{
NazaraError("failed to retrieve window device context: " + Error::GetLastSystemError());

View File

@ -3,15 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Platform/Cursor.hpp>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Platform/Win32/CursorImpl.hpp>
#elif defined(NAZARA_PLATFORM_X11)
#include <Nazara/Platform/X11/CursorImpl.hpp>
#else
#error Lack of implementation: Cursor
#endif
#include <Nazara/Platform/SDL2/CursorImpl.hpp>
#include <Nazara/Platform/Debug.hpp>
namespace Nz

View File

@ -3,15 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Platform/Icon.hpp>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Platform/Win32/IconImpl.hpp>
#elif defined(NAZARA_PLATFORM_X11)
#include <Nazara/Platform/X11/IconImpl.hpp>
#else
#error Lack of implementation: Icon
#endif
#include <Nazara/Platform/SDL2/IconImpl.hpp>
#include <Nazara/Platform/Debug.hpp>
namespace Nz

View File

@ -3,26 +3,48 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Platform/Keyboard.hpp>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Platform/Win32/InputImpl.hpp>
#elif defined(NAZARA_PLATFORM_X11)
#include <Nazara/Platform/X11/InputImpl.hpp>
#else
#error Lack of implementation: Keyboard
#endif
#include <Nazara/Platform/SDL2/InputImpl.hpp>
#include <Nazara/Platform/Debug.hpp>
namespace Nz
{
String Keyboard::GetKeyName(Key key)
String Keyboard::GetKeyName(Scancode scancode)
{
return EventImpl::GetKeyName(scancode);
}
String Keyboard::GetKeyName(VKey key)
{
return EventImpl::GetKeyName(key);
}
bool Keyboard::IsKeyPressed(Key key)
bool Keyboard::IsKeyPressed(Scancode scancode)
{
return EventImpl::IsKeyPressed(scancode);
}
bool Keyboard::IsKeyPressed(VKey key)
{
return EventImpl::IsKeyPressed(key);
}
void Keyboard::StartTextInput()
{
EventImpl::StartTextInput();
}
void Keyboard::StopTextInput()
{
EventImpl::StopTextInput();
}
Keyboard::Scancode Keyboard::ToScanCode(VKey key)
{
return EventImpl::ToScanCode(key);
}
Keyboard::VKey Keyboard::ToVirtualKey(Scancode scancode)
{
return EventImpl::ToVirtualKey(scancode);
}
}

View File

@ -4,15 +4,7 @@
#include <Nazara/Platform/Mouse.hpp>
#include <Nazara/Platform/Window.hpp>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Platform/Win32/InputImpl.hpp>
#elif defined(NAZARA_PLATFORM_X11)
#include <Nazara/Platform/X11/InputImpl.hpp>
#else
#error Lack of implementation: Mouse
#endif
#include <Nazara/Platform/SDL2/InputImpl.hpp>
#include <Nazara/Platform/Debug.hpp>
namespace Nz
@ -32,6 +24,11 @@ namespace Nz
return EventImpl::IsMouseButtonPressed(button);
}
bool Mouse::SetRelativeMouseMode(bool relativeMouseMode)
{
return EventImpl::SetRelativeMouseMode(relativeMouseMode);
}
void Mouse::SetPosition(const Vector2i& position)
{
EventImpl::SetMousePosition(position.x, position.y);

View File

@ -0,0 +1,108 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Error.hpp>
#include <Nazara/Platform/Debug.hpp>
#include <Nazara/Platform/SDL2/CursorImpl.hpp>
#include <Nazara/Utility/Image.hpp>
#include <Nazara/Utility/PixelFormat.hpp>
namespace Nz
{
bool CursorImpl::Create(const Image& cursor, int hotSpotX, int hotSpotY)
{
m_iconImage = cursor;
if (!m_iconImage.Convert(PixelFormat_BGRA8))
{
NazaraError("Failed to convert icon to BGRA8");
return false;
}
m_icon = SDL_CreateRGBSurfaceWithFormatFrom(
m_iconImage.GetPixels(),
m_iconImage.GetWidth(),
m_iconImage.GetHeight(),
32,
32 * m_iconImage.GetWidth(),
SDL_PIXELFORMAT_BGRA8888
);
if (!m_icon)
{
NazaraError(SDL_GetError());
return false;
}
m_cursor = SDL_CreateColorCursor(m_icon, hotSpotX, hotSpotY);
if (!m_cursor)
{
NazaraError(SDL_GetError());
return false;
}
return true;
}
bool CursorImpl::Create(SystemCursor cursor)
{
if (cursor != SystemCursor_None)
m_cursor = SDL_CreateSystemCursor(s_systemCursorIds[cursor]);
else
m_cursor = nullptr;
m_icon = nullptr;
return true;
}
void CursorImpl::Destroy()
{
if (m_icon)
SDL_FreeSurface(m_icon);
if (m_cursor)
SDL_FreeCursor(m_cursor);
}
SDL_Cursor* CursorImpl::GetCursor()
{
return m_cursor;
}
bool CursorImpl::Initialize()
{
return true;
}
void CursorImpl::Uninitialize()
{
}
std::array<SDL_SystemCursor, SystemCursor_Max + 1> CursorImpl::s_systemCursorIds =
{
SDL_SYSTEM_CURSOR_CROSSHAIR, // SystemCursor_Crosshair
SDL_SYSTEM_CURSOR_ARROW, // SystemCursor_Default
SDL_SYSTEM_CURSOR_HAND, // SystemCursor_Hand
SDL_SYSTEM_CURSOR_ARROW, // SystemCursor_Help
SDL_SYSTEM_CURSOR_SIZEALL, // SystemCursor_Move
SDL_NUM_SYSTEM_CURSORS, // SystemCursor_None
SDL_SYSTEM_CURSOR_HAND, // SystemCursor_Pointer
SDL_SYSTEM_CURSOR_WAITARROW, // SystemCursor_Progress
SDL_SYSTEM_CURSOR_SIZEWE, // SystemCursor_ResizeE
SDL_SYSTEM_CURSOR_SIZENS, // SystemCursor_ResizeN
SDL_SYSTEM_CURSOR_SIZENESW, // SystemCursor_ResizeNE
SDL_SYSTEM_CURSOR_SIZENWSE, // SystemCursor_ResizeNW
SDL_SYSTEM_CURSOR_SIZENS, // SystemCursor_ResizeS
SDL_SYSTEM_CURSOR_SIZENWSE, // SystemCursor_ResizeSE
SDL_SYSTEM_CURSOR_SIZENESW, // SystemCursor_ResizeSW
SDL_SYSTEM_CURSOR_SIZEWE, // SystemCursor_ResizeW
SDL_SYSTEM_CURSOR_IBEAM, // SystemCursor_Text
SDL_SYSTEM_CURSOR_WAIT // SystemCursor_Wait
};
static_assert(SystemCursor_Max + 1 == 18, "System cursor array is incomplete");
}

View File

@ -7,10 +7,12 @@
#ifndef NAZARA_CURSORIMPL_HPP
#define NAZARA_CURSORIMPL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Platform/Enums.hpp>
#include <array>
#include <windows.h>
#include <Nazara/Platform/Enums.hpp>
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Utility/Image.hpp>
#include <SDL2/SDL_mouse.h>
namespace Nz
{
@ -26,16 +28,17 @@ namespace Nz
void Destroy();
HCURSOR GetCursor();
SDL_Cursor* GetCursor();
private:
static bool Initialize();
static void Uninitialize();
HCURSOR m_cursor = nullptr;
HICON m_icon = nullptr;
SDL_Cursor* m_cursor = nullptr;
SDL_Surface* m_icon = nullptr;
Image m_iconImage;
static std::array<LPTSTR, SystemCursor_Max + 1> s_systemCursorIds;
static std::array<SDL_SystemCursor, SystemCursor_Max + 1> s_systemCursorIds;
};
}

View File

@ -0,0 +1,49 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Platform/Debug.hpp>
#include <Nazara/Platform/SDL2/IconImpl.hpp>
#include <Nazara/Utility/Image.hpp>
#include <Nazara/Utility/PixelFormat.hpp>
namespace Nz
{
bool IconImpl::Create(const Image& icon)
{
m_iconImage = icon;
if (!m_iconImage.Convert(PixelFormat_BGRA8))
{
NazaraError("Failed to convert icon to BGRA8");
return false;
}
m_icon = SDL_CreateRGBSurfaceWithFormatFrom(
m_iconImage.GetPixels(),
m_iconImage.GetWidth(),
m_iconImage.GetHeight(),
32,
32 * m_iconImage.GetWidth(),
SDL_PIXELFORMAT_BGRA8888
);
if (!m_icon)
{
NazaraError(SDL_GetError());
return false;
}
return true;
}
void IconImpl::Destroy()
{
SDL_FreeSurface(m_icon);
m_iconImage.Destroy();
}
SDL_Surface* IconImpl::GetIcon()
{
return m_icon;
}
}

View File

@ -8,7 +8,8 @@
#define NAZARA_ICONIMPL_HPP
#include <Nazara/Prerequisites.hpp>
#include <windows.h>
#include <Nazara/Utility/Image.hpp>
#include <SDL2/SDL_surface.h>
namespace Nz
{
@ -20,10 +21,12 @@ namespace Nz
bool Create(const Image& image);
void Destroy();
HICON GetIcon();
SDL_Surface* GetIcon();
private:
HICON m_icon = nullptr;
SDL_Surface* m_icon = nullptr;
Image m_iconImage;
};
}

View File

@ -0,0 +1,117 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Error.hpp>
#include <Nazara/Platform/Debug.hpp>
#include <Nazara/Platform/SDL2/InputImpl.hpp>
#include <Nazara/Platform/SDL2/SDLHelper.hpp>
#include <Nazara/Platform/SDL2/WindowImpl.hpp>
#include <Nazara/Platform/Window.hpp>
#include <SDL2/SDL_keyboard.h>
#include <SDL2/SDL_keycode.h>
#include <SDL2/SDL_mouse.h>
namespace Nz
{
String EventImpl::GetKeyName(Keyboard::Scancode key)
{
SDL_Scancode scancode = SDLHelper::ToSDL(key);
String name;
if (scancode != SDL_SCANCODE_UNKNOWN)
name = SDL_GetScancodeName(scancode);
return !name.IsEmpty() ? name : String::Unicode("Unknown");
}
String EventImpl::GetKeyName(Keyboard::VKey key)
{
SDL_Keycode vkey = SDLHelper::ToSDL(key);
String name;
if (vkey != SDLK_UNKNOWN)
name = SDL_GetKeyName(vkey);
return !name.IsEmpty() ? name : String::Unicode("Unknown");
}
Vector2i EventImpl::GetMousePosition()
{
Vector2i pos;
SDL_GetGlobalMouseState(&pos.x, &pos.y);
return pos;
}
Vector2i EventImpl::GetMousePosition(const Window& relativeTo)
{
auto windowPos = relativeTo.GetPosition();
auto mousePos = GetMousePosition();
return mousePos - windowPos;
}
bool EventImpl::IsKeyPressed(Keyboard::Scancode key)
{
return SDL_GetKeyboardState(nullptr)[SDLHelper::ToSDL(key)];
}
bool EventImpl::IsKeyPressed(Keyboard::VKey key)
{
return IsKeyPressed(ToScanCode(key));
}
bool EventImpl::IsMouseButtonPressed(Mouse::Button button)
{
static int vButtons[Mouse::Max + 1] = {
SDL_BUTTON_LMASK, // Button::Left
SDL_BUTTON_MMASK, // Button::Middle
SDL_BUTTON_RMASK, // Button::Right
SDL_BUTTON_X1MASK, // Button::XButton1
SDL_BUTTON_X2MASK // Button::XButton2
};
return (SDL_GetGlobalMouseState(nullptr, nullptr) & vButtons[button]) != 0;
}
bool EventImpl::SetRelativeMouseMode(bool relativeMouseMode)
{
return SDL_SetRelativeMouseMode((relativeMouseMode) ? SDL_TRUE : SDL_FALSE) == 0;
}
void EventImpl::SetMousePosition(int x, int y)
{
if (SDL_WarpMouseGlobal(x, y) != 0)
NazaraWarning(SDL_GetError());
}
void EventImpl::SetMousePosition(int x, int y, const Window& relativeTo)
{
SDL_Window* handle = static_cast<const WindowImpl*>(relativeTo.GetImpl())->GetHandle();
if (handle)
SDL_WarpMouseInWindow(handle, x, y);
else
NazaraError("Invalid window handle");
}
void EventImpl::StartTextInput()
{
SDL_StartTextInput();
}
void EventImpl::StopTextInput()
{
SDL_StopTextInput();
}
Keyboard::Scancode EventImpl::ToScanCode(Keyboard::VKey key)
{
return SDLHelper::FromSDL(SDL_GetScancodeFromKey(SDLHelper::ToSDL(key)));
}
Keyboard::VKey EventImpl::ToVirtualKey(Keyboard::Scancode scancode)
{
return SDLHelper::FromSDL(SDL_GetKeyFromScancode(SDLHelper::ToSDL(scancode)));
}
}

View File

@ -7,8 +7,8 @@
#ifndef NAZARA_INPUTIMPL_HPP
#define NAZARA_INPUTIMPL_HPP
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Platform/Keyboard.hpp>
#include <Nazara/Platform/Mouse.hpp>
@ -17,13 +17,20 @@ namespace Nz
class EventImpl
{
public:
static String GetKeyName(Keyboard::Key key);
static String GetKeyName(Keyboard::Scancode scancode);
static String GetKeyName(Keyboard::VKey key);
static Vector2i GetMousePosition();
static Vector2i GetMousePosition(const Window& relativeTo);
static bool IsKeyPressed(Keyboard::Key key);
static bool IsKeyPressed(Keyboard::Scancode key);
static bool IsKeyPressed(Keyboard::VKey key);
static bool IsMouseButtonPressed(Mouse::Button button);
static bool SetRelativeMouseMode(bool relativeMouseMode);
static void SetMousePosition(int x, int y);
static void SetMousePosition(int x, int y, const Window& relativeTo);
static void StartTextInput();
static void StopTextInput();
static Keyboard::Scancode ToScanCode(Keyboard::VKey key);
static Keyboard::VKey ToVirtualKey(Keyboard::Scancode scancode);
};
}

View File

@ -0,0 +1,586 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Platform/SDL2/SDLHelper.hpp>
namespace Nz
{
namespace
{
SDL_Scancode nzScancodeToSDLScanCode[static_cast<std::size_t>(Keyboard::VKey::Max) + 1] = {
// Lettres
SDL_SCANCODE_A, // Key::A
SDL_SCANCODE_B, // Key::B
SDL_SCANCODE_C, // Key::C
SDL_SCANCODE_D, // Key::D
SDL_SCANCODE_E, // Key::E
SDL_SCANCODE_F, // Key::F
SDL_SCANCODE_G, // Key::G
SDL_SCANCODE_H, // Key::H
SDL_SCANCODE_I, // Key::I
SDL_SCANCODE_J, // Key::J
SDL_SCANCODE_K, // Key::K
SDL_SCANCODE_L, // Key::L
SDL_SCANCODE_M, // Key::M
SDL_SCANCODE_N, // Key::N
SDL_SCANCODE_O, // Key::O
SDL_SCANCODE_P, // Key::P
SDL_SCANCODE_Q, // Key::Q
SDL_SCANCODE_R, // Key::R
SDL_SCANCODE_S, // Key::S
SDL_SCANCODE_T, // Key::T
SDL_SCANCODE_U, // Key::U
SDL_SCANCODE_V, // Key::V
SDL_SCANCODE_W, // Key::W
SDL_SCANCODE_X, // Key::X
SDL_SCANCODE_Y, // Key::Y
SDL_SCANCODE_Z, // Key::Z
// Touches de fonction
SDL_SCANCODE_F1, // Key::F1
SDL_SCANCODE_F2, // Key::F2
SDL_SCANCODE_F3, // Key::F3
SDL_SCANCODE_F4, // Key::F4
SDL_SCANCODE_F5, // Key::F5
SDL_SCANCODE_F6, // Key::F6
SDL_SCANCODE_F7, // Key::F7
SDL_SCANCODE_F8, // Key::F8
SDL_SCANCODE_F9, // Key::F9
SDL_SCANCODE_F10, // Key::F10
SDL_SCANCODE_F11, // Key::F11
SDL_SCANCODE_F12, // Key::F12
SDL_SCANCODE_F13, // Key::F13
SDL_SCANCODE_F14, // Key::F14
SDL_SCANCODE_F15, // Key::F15
// Flèches directionnelles
SDL_SCANCODE_DOWN, // Key::Down
SDL_SCANCODE_LEFT, // Key::Left
SDL_SCANCODE_RIGHT, // Key::Right
SDL_SCANCODE_UP, // Key::Up
// Pavé numérique
SDL_SCANCODE_KP_PLUS, // Key::Add
SDL_SCANCODE_KP_PERIOD, // Key::Decimal
SDL_SCANCODE_KP_DIVIDE, // Key::Divide
SDL_SCANCODE_KP_MULTIPLY, // Key::Multiply
SDL_SCANCODE_KP_ENTER, // Key::NumpadReturn
SDL_SCANCODE_KP_0, // Key::Numpad0
SDL_SCANCODE_KP_1, // Key::Numpad1
SDL_SCANCODE_KP_2, // Key::Numpad2
SDL_SCANCODE_KP_3, // Key::Numpad3
SDL_SCANCODE_KP_4, // Key::Numpad4
SDL_SCANCODE_KP_5, // Key::Numpad5
SDL_SCANCODE_KP_6, // Key::Numpad6
SDL_SCANCODE_KP_7, // Key::Numpad7
SDL_SCANCODE_KP_8, // Key::Numpad8
SDL_SCANCODE_KP_9, // Key::Numpad9
SDL_SCANCODE_KP_MINUS, // Key::Subtract
// Divers
SDL_SCANCODE_BACKSLASH, // Key::Backslash
SDL_SCANCODE_BACKSPACE, // Key::Backspace
SDL_SCANCODE_CLEAR, // Key::Clear
SDL_SCANCODE_COMMA, // Key::Comma,
SDL_SCANCODE_MINUS, // Key::Dash
SDL_SCANCODE_DELETE, // Key::Delete
SDL_SCANCODE_END, // Key::End
SDL_SCANCODE_EQUALS, // Key::Equal
SDL_SCANCODE_ESCAPE, // Key::Escape
SDL_SCANCODE_HOME, // Key::Home
SDL_SCANCODE_INSERT, // Key::Insert
SDL_SCANCODE_LALT, // Key::LAlt
SDL_SCANCODE_LEFTBRACKET, // Key::LBracket
SDL_SCANCODE_LCTRL, // Key::LControl
SDL_SCANCODE_LSHIFT, // Key::LShift
SDL_SCANCODE_LGUI, // Key::LSystem
SDL_SCANCODE_0, // Key::Num0
SDL_SCANCODE_1, // Key::Num1
SDL_SCANCODE_2, // Key::Num2
SDL_SCANCODE_3, // Key::Num3
SDL_SCANCODE_4, // Key::Num4
SDL_SCANCODE_5, // Key::Num5
SDL_SCANCODE_6, // Key::Num6
SDL_SCANCODE_7, // Key::Num7
SDL_SCANCODE_8, // Key::Num8
SDL_SCANCODE_9, // Key::Num9
SDL_SCANCODE_PAGEDOWN, // Key::PageDown
SDL_SCANCODE_PAGEUP, // Key::PageUp
SDL_SCANCODE_PAUSE, // Key::Pause
SDL_SCANCODE_PERIOD, // Key::Period
SDL_SCANCODE_SYSREQ, // Key::Print
SDL_SCANCODE_PRINTSCREEN, // Key::PrintScreen
SDL_SCANCODE_APOSTROPHE, // Key::Quote
SDL_SCANCODE_RALT, // Key::RAlt
SDL_SCANCODE_RIGHTBRACKET, // Key::RBracket
SDL_SCANCODE_RCTRL, // Key::RControl
SDL_SCANCODE_RETURN, // Key::Return
SDL_SCANCODE_RSHIFT, // Key::RShift
SDL_SCANCODE_RGUI, // Key::RSystem
SDL_SCANCODE_SEMICOLON, // Key::Semicolon
SDL_SCANCODE_SLASH, // Key::Slash
SDL_SCANCODE_SPACE, // Key::Space
SDL_SCANCODE_TAB, // Key::Tab
SDL_SCANCODE_GRAVE, // Key::Tilde
SDL_SCANCODE_APPLICATION, // Key::Menu
SDL_SCANCODE_NONUSBACKSLASH,// Key::ISOBackslash102
// Touches navigateur
SDL_SCANCODE_AC_BACK, // Key::Browser_Back
SDL_SCANCODE_AC_BOOKMARKS, // Key::Browser_Favorites
SDL_SCANCODE_AC_FORWARD, // Key::Browser_Forward
SDL_SCANCODE_AC_HOME, // Key::Browser_Home
SDL_SCANCODE_AC_REFRESH, // Key::Browser_Refresh
SDL_SCANCODE_AC_SEARCH, // Key::Browser_Search
SDL_SCANCODE_AC_STOP, // Key::Browser_Stop
// Touches de contrôle
SDL_SCANCODE_AUDIONEXT, // Key::Media_Next,
SDL_SCANCODE_AUDIOPLAY, // Key::Media_PlayPause,
SDL_SCANCODE_AUDIOPREV, // Key::Media_Previous,
SDL_SCANCODE_AUDIOSTOP, // Key::Media_Stop,
// Touches de contrôle du volume
SDL_SCANCODE_VOLUMEDOWN, // Key::Volume_Down
SDL_SCANCODE_MUTE, // Key::Volume_Mute
SDL_SCANCODE_VOLUMEUP, // Key::Volume_Up
// Touches à verrouillage
SDL_SCANCODE_CAPSLOCK, // Key::CapsLock
SDL_SCANCODE_NUMLOCKCLEAR, // Key::NumLock
SDL_SCANCODE_SCROLLLOCK // Key::ScrollLock
};
SDL_Keycode nzVKeyToSDLVKey[static_cast<std::size_t>(Keyboard::VKey::Max) + 1] = {
// Keys
SDLK_a, // VKey::A
SDLK_b, // VKey::B
SDLK_c, // VKey::C
SDLK_d, // VKey::D
SDLK_e, // VKey::E
SDLK_f, // VKey::F
SDLK_g, // VKey::G
SDLK_h, // VKey::H
SDLK_i, // VKey::I
SDLK_j, // VKey::J
SDLK_k, // VKey::K
SDLK_l, // VKey::L
SDLK_m, // VKey::M
SDLK_n, // VKey::N
SDLK_o, // VKey::O
SDLK_p, // VKey::P
SDLK_q, // VKey::Q
SDLK_r, // VKey::R
SDLK_s, // VKey::S
SDLK_t, // VKey::T
SDLK_u, // VKey::U
SDLK_v, // VKey::V
SDLK_w, // VKey::W
SDLK_x, // VKey::X
SDLK_y, // VKey::Y
SDLK_z, // VKey::Z
// Function keys
SDLK_F1, // VKey::F1
SDLK_F2, // VKey::F2
SDLK_F3, // VKey::F3
SDLK_F4, // VKey::F4
SDLK_F5, // VKey::F5
SDLK_F6, // VKey::F6
SDLK_F7, // VKey::F7
SDLK_F8, // VKey::F8
SDLK_F9, // VKey::F9
SDLK_F10, // VKey::F10
SDLK_F11, // VKey::F11
SDLK_F12, // VKey::F12
SDLK_F13, // VKey::F13
SDLK_F14, // VKey::F14
SDLK_F15, // VKey::F15
// Arrows
SDLK_DOWN, // VKey::Down
SDLK_LEFT, // VKey::Left
SDLK_RIGHT, // VKey::Right
SDLK_UP, // VKey::Up
// Keypad
SDLK_KP_PLUS, // VKey::Add
SDLK_KP_PERIOD, // VKey::Decimal
SDLK_KP_DIVIDE, // VKey::Divide
SDLK_KP_MULTIPLY, // VKey::Multiply
SDLK_KP_ENTER, // VKey::NumpadReturn
SDLK_KP_0, // VKey::Numpad0
SDLK_KP_1, // VKey::Numpad1
SDLK_KP_2, // VKey::Numpad2
SDLK_KP_3, // VKey::Numpad3
SDLK_KP_4, // VKey::Numpad4
SDLK_KP_5, // VKey::Numpad5
SDLK_KP_6, // VKey::Numpad6
SDLK_KP_7, // VKey::Numpad7
SDLK_KP_8, // VKey::Numpad8
SDLK_KP_9, // VKey::Numpad9
SDLK_KP_MINUS, // VKey::Subtract
// Divers
SDLK_BACKSLASH, // VKey::Backslash
SDLK_BACKSPACE, // VKey::Backspace
SDLK_CLEAR, // VKey::Clear
SDLK_COMMA, // VKey::Comma,
SDLK_MINUS, // VKey::Dash
SDLK_DELETE, // VKey::Delete
SDLK_END, // VKey::End
SDLK_EQUALS, // VKey::Equal
SDLK_ESCAPE, // VKey::Escape
SDLK_HOME, // VKey::Home
SDLK_INSERT, // VKey::Insert
SDLK_LALT, // VKey::LAlt
SDLK_LEFTBRACKET, // VKey::LBracket
SDLK_LCTRL, // VKey::LControl
SDLK_LSHIFT, // VKey::LShift
SDLK_LGUI, // VKey::LSystem
SDLK_0, // VKey::Num0
SDLK_1, // VKey::Num1
SDLK_2, // VKey::Num2
SDLK_3, // VKey::Num3
SDLK_4, // VKey::Num4
SDLK_5, // VKey::Num5
SDLK_6, // VKey::Num6
SDLK_7, // VKey::Num7
SDLK_8, // VKey::Num8
SDLK_9, // VKey::Num9
SDLK_PAGEDOWN, // VKey::PageDown
SDLK_PAGEUP, // VKey::PageUp
SDLK_PAUSE, // VKey::Pause
SDLK_PERIOD, // VKey::Period
SDLK_SYSREQ, // VKey::Print
SDLK_PRINTSCREEN, // VKey::PrintScreen
SDLK_QUOTE, // VKey::Quote
SDLK_RALT, // VKey::RAlt
SDLK_RIGHTBRACKET, // VKey::RBracket
SDLK_RCTRL, // VKey::RControl
SDLK_RETURN, // VKey::Return
SDLK_RSHIFT, // VKey::RShift
SDLK_RGUI, // VKey::RSystem
SDLK_SEMICOLON, // VKey::Semicolon
SDLK_SLASH, // VKey::Slash
SDLK_SPACE, // VKey::Space
SDLK_TAB, // VKey::Tab
SDLK_BACKQUOTE, // VKey::Tilde
SDLK_APPLICATION, // VKey::Menu
SDLK_UNKNOWN, // VKey::ISOBackslash102
// Browser control
SDLK_AC_BACK, // VKey::Browser_Back
SDLK_AC_BOOKMARKS, // VKey::Browser_Favorites
SDLK_AC_FORWARD, // VKey::Browser_Forward
SDLK_AC_HOME, // VKey::Browser_Home
SDLK_AC_REFRESH, // VKey::Browser_Refresh
SDLK_AC_SEARCH, // VKey::Browser_Search
SDLK_AC_STOP, // VKey::Browser_Stop
// Audio control
SDLK_AUDIONEXT, // VKey::Media_Next,
SDLK_AUDIOPLAY, // VKey::Media_PlayPause,
SDLK_AUDIOPREV, // VKey::Media_Previous,
SDLK_AUDIOSTOP, // VKey::Media_Stop,
// Volume control
SDLK_VOLUMEDOWN, // VKey::Volume_Down
SDLK_MUTE, // VKey::Volume_Mute
SDLK_VOLUMEUP, // VKey::Volume_Up
// Lock keys
SDLK_CAPSLOCK, // VKey::CapsLock
SDLK_NUMLOCKCLEAR, // VKey::NumLock
SDLK_SCROLLLOCK // VKey::ScrollLock
};
}
Keyboard::Scancode SDLHelper::FromSDL(SDL_Scancode scancode)
{
switch (scancode)
{
case SDL_SCANCODE_LCTRL: return Keyboard::Scancode::LControl;
case SDL_SCANCODE_RCTRL: return Keyboard::Scancode::RControl;
case SDL_SCANCODE_LALT: return Keyboard::Scancode::LAlt;
case SDL_SCANCODE_RALT: return Keyboard::Scancode::RAlt;
case SDL_SCANCODE_LSHIFT: return Keyboard::Scancode::LShift;
case SDL_SCANCODE_RSHIFT: return Keyboard::Scancode::RShift;
case SDL_SCANCODE_0: return Keyboard::Scancode::Num0;
case SDL_SCANCODE_1: return Keyboard::Scancode::Num1;
case SDL_SCANCODE_2: return Keyboard::Scancode::Num2;
case SDL_SCANCODE_3: return Keyboard::Scancode::Num3;
case SDL_SCANCODE_4: return Keyboard::Scancode::Num4;
case SDL_SCANCODE_5: return Keyboard::Scancode::Num5;
case SDL_SCANCODE_6: return Keyboard::Scancode::Num6;
case SDL_SCANCODE_7: return Keyboard::Scancode::Num7;
case SDL_SCANCODE_8: return Keyboard::Scancode::Num8;
case SDL_SCANCODE_9: return Keyboard::Scancode::Num9;
case SDL_SCANCODE_A: return Keyboard::Scancode::A;
case SDL_SCANCODE_B: return Keyboard::Scancode::B;
case SDL_SCANCODE_C: return Keyboard::Scancode::C;
case SDL_SCANCODE_D: return Keyboard::Scancode::D;
case SDL_SCANCODE_E: return Keyboard::Scancode::E;
case SDL_SCANCODE_F: return Keyboard::Scancode::F;
case SDL_SCANCODE_G: return Keyboard::Scancode::G;
case SDL_SCANCODE_H: return Keyboard::Scancode::H;
case SDL_SCANCODE_I: return Keyboard::Scancode::I;
case SDL_SCANCODE_J: return Keyboard::Scancode::J;
case SDL_SCANCODE_K: return Keyboard::Scancode::K;
case SDL_SCANCODE_L: return Keyboard::Scancode::L;
case SDL_SCANCODE_M: return Keyboard::Scancode::M;
case SDL_SCANCODE_N: return Keyboard::Scancode::N;
case SDL_SCANCODE_O: return Keyboard::Scancode::O;
case SDL_SCANCODE_P: return Keyboard::Scancode::P;
case SDL_SCANCODE_Q: return Keyboard::Scancode::Q;
case SDL_SCANCODE_R: return Keyboard::Scancode::R;
case SDL_SCANCODE_S: return Keyboard::Scancode::S;
case SDL_SCANCODE_T: return Keyboard::Scancode::T;
case SDL_SCANCODE_U: return Keyboard::Scancode::U;
case SDL_SCANCODE_V: return Keyboard::Scancode::V;
case SDL_SCANCODE_W: return Keyboard::Scancode::W;
case SDL_SCANCODE_X: return Keyboard::Scancode::X;
case SDL_SCANCODE_Y: return Keyboard::Scancode::Y;
case SDL_SCANCODE_Z: return Keyboard::Scancode::Z;
case SDL_SCANCODE_KP_PLUS: return Keyboard::Scancode::Add;
case SDL_SCANCODE_BACKSPACE: return Keyboard::Scancode::Backspace;
case SDL_SCANCODE_AC_BACK: return Keyboard::Scancode::Browser_Back;
case SDL_SCANCODE_AC_BOOKMARKS: return Keyboard::Scancode::Browser_Favorites;
case SDL_SCANCODE_AC_FORWARD: return Keyboard::Scancode::Browser_Forward;
case SDL_SCANCODE_AC_HOME: return Keyboard::Scancode::Browser_Home;
case SDL_SCANCODE_AC_REFRESH: return Keyboard::Scancode::Browser_Refresh;
case SDL_SCANCODE_AC_SEARCH: return Keyboard::Scancode::Browser_Search;
case SDL_SCANCODE_AC_STOP: return Keyboard::Scancode::Browser_Stop;
case SDL_SCANCODE_CAPSLOCK: return Keyboard::Scancode::CapsLock;
case SDL_SCANCODE_CLEAR: return Keyboard::Scancode::Clear;
case SDL_SCANCODE_KP_PERIOD: return Keyboard::Scancode::Decimal;
case SDL_SCANCODE_DELETE: return Keyboard::Scancode::Delete;
case SDL_SCANCODE_KP_DIVIDE: return Keyboard::Scancode::Divide;
case SDL_SCANCODE_DOWN: return Keyboard::Scancode::Down;
case SDL_SCANCODE_END: return Keyboard::Scancode::End;
case SDL_SCANCODE_ESCAPE: return Keyboard::Scancode::Escape;
case SDL_SCANCODE_F1: return Keyboard::Scancode::F1;
case SDL_SCANCODE_F2: return Keyboard::Scancode::F2;
case SDL_SCANCODE_F3: return Keyboard::Scancode::F3;
case SDL_SCANCODE_F4: return Keyboard::Scancode::F4;
case SDL_SCANCODE_F5: return Keyboard::Scancode::F5;
case SDL_SCANCODE_F6: return Keyboard::Scancode::F6;
case SDL_SCANCODE_F7: return Keyboard::Scancode::F7;
case SDL_SCANCODE_F8: return Keyboard::Scancode::F8;
case SDL_SCANCODE_F9: return Keyboard::Scancode::F9;
case SDL_SCANCODE_F10: return Keyboard::Scancode::F10;
case SDL_SCANCODE_F11: return Keyboard::Scancode::F11;
case SDL_SCANCODE_F12: return Keyboard::Scancode::F12;
case SDL_SCANCODE_F13: return Keyboard::Scancode::F13;
case SDL_SCANCODE_F14: return Keyboard::Scancode::F14;
case SDL_SCANCODE_F15: return Keyboard::Scancode::F15;
case SDL_SCANCODE_HOME: return Keyboard::Scancode::Home;
case SDL_SCANCODE_INSERT: return Keyboard::Scancode::Insert;
case SDL_SCANCODE_LEFT: return Keyboard::Scancode::Left;
case SDL_SCANCODE_LGUI: return Keyboard::Scancode::LSystem;
case SDL_SCANCODE_AUDIONEXT: return Keyboard::Scancode::Media_Next;
case SDL_SCANCODE_AUDIOPLAY: return Keyboard::Scancode::Media_Play;
case SDL_SCANCODE_AUDIOPREV: return Keyboard::Scancode::Media_Previous;
case SDL_SCANCODE_AUDIOSTOP: return Keyboard::Scancode::Media_Stop;
case SDL_SCANCODE_KP_MULTIPLY: return Keyboard::Scancode::Multiply;
case SDL_SCANCODE_PAGEDOWN: return Keyboard::Scancode::PageDown;
case SDL_SCANCODE_KP_0: return Keyboard::Scancode::Numpad0;
case SDL_SCANCODE_KP_1: return Keyboard::Scancode::Numpad1;
case SDL_SCANCODE_KP_2: return Keyboard::Scancode::Numpad2;
case SDL_SCANCODE_KP_3: return Keyboard::Scancode::Numpad3;
case SDL_SCANCODE_KP_4: return Keyboard::Scancode::Numpad4;
case SDL_SCANCODE_KP_5: return Keyboard::Scancode::Numpad5;
case SDL_SCANCODE_KP_6: return Keyboard::Scancode::Numpad6;
case SDL_SCANCODE_KP_7: return Keyboard::Scancode::Numpad7;
case SDL_SCANCODE_KP_8: return Keyboard::Scancode::Numpad8;
case SDL_SCANCODE_KP_9: return Keyboard::Scancode::Numpad9;
case SDL_SCANCODE_NUMLOCKCLEAR: return Keyboard::Scancode::NumLock;
case SDL_SCANCODE_SEMICOLON: return Keyboard::Scancode::Semicolon;
case SDL_SCANCODE_SLASH: return Keyboard::Scancode::Slash;
case SDL_SCANCODE_GRAVE: return Keyboard::Scancode::Tilde;
case SDL_SCANCODE_APPLICATION: return Keyboard::Scancode::Menu;
case SDL_SCANCODE_NONUSBACKSLASH: return Keyboard::Scancode::ISOBackslash102;
case SDL_SCANCODE_LEFTBRACKET: return Keyboard::Scancode::LBracket;
case SDL_SCANCODE_BACKSLASH: return Keyboard::Scancode::Backslash;
case SDL_SCANCODE_RIGHTBRACKET: return Keyboard::Scancode::RBracket;
case SDL_SCANCODE_APOSTROPHE: return Keyboard::Scancode::Quote;
case SDL_SCANCODE_COMMA: return Keyboard::Scancode::Comma;
case SDL_SCANCODE_MINUS: return Keyboard::Scancode::Dash;
case SDL_SCANCODE_PERIOD: return Keyboard::Scancode::Period;
case SDL_SCANCODE_EQUALS: return Keyboard::Scancode::Equal;
case SDL_SCANCODE_RIGHT: return Keyboard::Scancode::Right;
case SDL_SCANCODE_PAGEUP: return Keyboard::Scancode::PageUp;
case SDL_SCANCODE_PAUSE: return Keyboard::Scancode::Pause;
case SDL_SCANCODE_SYSREQ: return Keyboard::Scancode::Print;
case SDL_SCANCODE_SCROLLLOCK: return Keyboard::Scancode::ScrollLock;
case SDL_SCANCODE_PRINTSCREEN: return Keyboard::Scancode::PrintScreen;
case SDL_SCANCODE_KP_MINUS: return Keyboard::Scancode::Subtract;
case SDL_SCANCODE_RETURN: return Keyboard::Scancode::Return;
case SDL_SCANCODE_KP_ENTER: return Keyboard::Scancode::NumpadReturn;
case SDL_SCANCODE_RGUI: return Keyboard::Scancode::RSystem;
case SDL_SCANCODE_SPACE: return Keyboard::Scancode::Space;
case SDL_SCANCODE_TAB: return Keyboard::Scancode::Tab;
case SDL_SCANCODE_UP: return Keyboard::Scancode::Up;
case SDL_SCANCODE_VOLUMEDOWN: return Keyboard::Scancode::Volume_Down;
case SDL_SCANCODE_MUTE: return Keyboard::Scancode::Volume_Mute;
case SDL_SCANCODE_AUDIOMUTE: return Keyboard::Scancode::Volume_Mute;
case SDL_SCANCODE_VOLUMEUP: return Keyboard::Scancode::Volume_Up;
default:
return Keyboard::Scancode::Undefined;
}
}
Keyboard::VKey SDLHelper::FromSDL(SDL_Keycode keycode)
{
switch (keycode)
{
case SDLK_LCTRL: return Keyboard::VKey::LControl;
case SDLK_RCTRL: return Keyboard::VKey::RControl;
case SDLK_LALT: return Keyboard::VKey::LAlt;
case SDLK_RALT: return Keyboard::VKey::RAlt;
case SDLK_LSHIFT: return Keyboard::VKey::LShift;
case SDLK_RSHIFT: return Keyboard::VKey::RShift;
case SDLK_0: return Keyboard::VKey::Num0;
case SDLK_1: return Keyboard::VKey::Num1;
case SDLK_2: return Keyboard::VKey::Num2;
case SDLK_3: return Keyboard::VKey::Num3;
case SDLK_4: return Keyboard::VKey::Num4;
case SDLK_5: return Keyboard::VKey::Num5;
case SDLK_6: return Keyboard::VKey::Num6;
case SDLK_7: return Keyboard::VKey::Num7;
case SDLK_8: return Keyboard::VKey::Num8;
case SDLK_9: return Keyboard::VKey::Num9;
case SDLK_a: return Keyboard::VKey::A;
case SDLK_b: return Keyboard::VKey::B;
case SDLK_c: return Keyboard::VKey::C;
case SDLK_d: return Keyboard::VKey::D;
case SDLK_e: return Keyboard::VKey::E;
case SDLK_f: return Keyboard::VKey::F;
case SDLK_g: return Keyboard::VKey::G;
case SDLK_h: return Keyboard::VKey::H;
case SDLK_i: return Keyboard::VKey::I;
case SDLK_j: return Keyboard::VKey::J;
case SDLK_k: return Keyboard::VKey::K;
case SDLK_l: return Keyboard::VKey::L;
case SDLK_m: return Keyboard::VKey::M;
case SDLK_n: return Keyboard::VKey::N;
case SDLK_o: return Keyboard::VKey::O;
case SDLK_p: return Keyboard::VKey::P;
case SDLK_q: return Keyboard::VKey::Q;
case SDLK_r: return Keyboard::VKey::R;
case SDLK_s: return Keyboard::VKey::S;
case SDLK_t: return Keyboard::VKey::T;
case SDLK_u: return Keyboard::VKey::U;
case SDLK_v: return Keyboard::VKey::V;
case SDLK_w: return Keyboard::VKey::W;
case SDLK_x: return Keyboard::VKey::X;
case SDLK_y: return Keyboard::VKey::Y;
case SDLK_z: return Keyboard::VKey::Z;
case SDLK_KP_PLUS: return Keyboard::VKey::Add;
case SDLK_BACKSPACE: return Keyboard::VKey::Backspace;
case SDLK_AC_BACK: return Keyboard::VKey::Browser_Back;
case SDLK_AC_BOOKMARKS: return Keyboard::VKey::Browser_Favorites;
case SDLK_AC_FORWARD: return Keyboard::VKey::Browser_Forward;
case SDLK_AC_HOME: return Keyboard::VKey::Browser_Home;
case SDLK_AC_REFRESH: return Keyboard::VKey::Browser_Refresh;
case SDLK_AC_SEARCH: return Keyboard::VKey::Browser_Search;
case SDLK_AC_STOP: return Keyboard::VKey::Browser_Stop;
case SDLK_CAPSLOCK: return Keyboard::VKey::CapsLock;
case SDLK_CLEAR: return Keyboard::VKey::Clear;
case SDLK_KP_PERIOD: return Keyboard::VKey::Decimal;
case SDLK_DELETE: return Keyboard::VKey::Delete;
case SDLK_KP_DIVIDE: return Keyboard::VKey::Divide;
case SDLK_DOWN: return Keyboard::VKey::Down;
case SDLK_END: return Keyboard::VKey::End;
case SDLK_ESCAPE: return Keyboard::VKey::Escape;
case SDLK_F1: return Keyboard::VKey::F1;
case SDLK_F2: return Keyboard::VKey::F2;
case SDLK_F3: return Keyboard::VKey::F3;
case SDLK_F4: return Keyboard::VKey::F4;
case SDLK_F5: return Keyboard::VKey::F5;
case SDLK_F6: return Keyboard::VKey::F6;
case SDLK_F7: return Keyboard::VKey::F7;
case SDLK_F8: return Keyboard::VKey::F8;
case SDLK_F9: return Keyboard::VKey::F9;
case SDLK_F10: return Keyboard::VKey::F10;
case SDLK_F11: return Keyboard::VKey::F11;
case SDLK_F12: return Keyboard::VKey::F12;
case SDLK_F13: return Keyboard::VKey::F13;
case SDLK_F14: return Keyboard::VKey::F14;
case SDLK_F15: return Keyboard::VKey::F15;
case SDLK_HOME: return Keyboard::VKey::Home;
case SDLK_INSERT: return Keyboard::VKey::Insert;
case SDLK_LEFT: return Keyboard::VKey::Left;
case SDLK_LGUI: return Keyboard::VKey::LSystem;
case SDLK_AUDIONEXT: return Keyboard::VKey::Media_Next;
case SDLK_AUDIOPLAY: return Keyboard::VKey::Media_Play;
case SDLK_AUDIOPREV: return Keyboard::VKey::Media_Previous;
case SDLK_AUDIOSTOP: return Keyboard::VKey::Media_Stop;
case SDLK_KP_MULTIPLY: return Keyboard::VKey::Multiply;
case SDLK_PAGEDOWN: return Keyboard::VKey::PageDown;
case SDLK_KP_0: return Keyboard::VKey::Numpad0;
case SDLK_KP_1: return Keyboard::VKey::Numpad1;
case SDLK_KP_2: return Keyboard::VKey::Numpad2;
case SDLK_KP_3: return Keyboard::VKey::Numpad3;
case SDLK_KP_4: return Keyboard::VKey::Numpad4;
case SDLK_KP_5: return Keyboard::VKey::Numpad5;
case SDLK_KP_6: return Keyboard::VKey::Numpad6;
case SDLK_KP_7: return Keyboard::VKey::Numpad7;
case SDLK_KP_8: return Keyboard::VKey::Numpad8;
case SDLK_KP_9: return Keyboard::VKey::Numpad9;
case SDLK_NUMLOCKCLEAR: return Keyboard::VKey::NumLock;
case SDLK_SEMICOLON: return Keyboard::VKey::Semicolon;
case SDLK_SLASH: return Keyboard::VKey::Slash;
case SDLK_BACKQUOTE: return Keyboard::VKey::Tilde;
case SDLK_APPLICATION: return Keyboard::VKey::Menu;
case SDLK_LEFTBRACKET: return Keyboard::VKey::LBracket;
case SDLK_BACKSLASH: return Keyboard::VKey::Backslash;
case SDLK_RIGHTBRACKET: return Keyboard::VKey::RBracket;
case SDLK_QUOTE: return Keyboard::VKey::Quote;
case SDLK_COMMA: return Keyboard::VKey::Comma;
case SDLK_MINUS: return Keyboard::VKey::Dash;
case SDLK_PERIOD: return Keyboard::VKey::Period;
case SDLK_EQUALS: return Keyboard::VKey::Equal;
case SDLK_RIGHT: return Keyboard::VKey::Right;
case SDLK_PAGEUP: return Keyboard::VKey::PageUp;
case SDLK_PAUSE: return Keyboard::VKey::Pause;
case SDLK_SYSREQ: return Keyboard::VKey::Print;
case SDLK_SCROLLLOCK: return Keyboard::VKey::ScrollLock;
case SDLK_PRINTSCREEN: return Keyboard::VKey::PrintScreen;
case SDLK_KP_MINUS: return Keyboard::VKey::Subtract;
case SDLK_RETURN: return Keyboard::VKey::Return;
case SDLK_KP_ENTER: return Keyboard::VKey::NumpadReturn;
case SDLK_RGUI: return Keyboard::VKey::RSystem;
case SDLK_SPACE: return Keyboard::VKey::Space;
case SDLK_TAB: return Keyboard::VKey::Tab;
case SDLK_UP: return Keyboard::VKey::Up;
case SDLK_VOLUMEDOWN: return Keyboard::VKey::Volume_Down;
case SDLK_MUTE: return Keyboard::VKey::Volume_Mute;
case SDLK_AUDIOMUTE: return Keyboard::VKey::Volume_Mute;
case SDLK_VOLUMEUP: return Keyboard::VKey::Volume_Up;
default:
return Keyboard::VKey::Undefined;
}
}
SDL_Scancode SDLHelper::ToSDL(Keyboard::Scancode scancode)
{
if (scancode == Keyboard::Scancode::Undefined)
return SDL_SCANCODE_UNKNOWN;
return nzScancodeToSDLScanCode[static_cast<std::size_t>(scancode)];
}
SDL_Keycode SDLHelper::ToSDL(Keyboard::VKey keycode)
{
if (keycode == Keyboard::VKey::Undefined)
return SDLK_UNKNOWN;
return nzVKeyToSDLVKey[static_cast<std::size_t>(keycode)];
}
}

View File

@ -0,0 +1,26 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SDL2_HELPER_HPP
#define NAZARA_SDL2_HELPER_HPP
#include <Nazara/Platform/Keyboard.hpp>
#include <SDL2/SDL_keycode.h>
#include <SDL2/SDL_scancode.h>
namespace Nz
{
class SDLHelper
{
public:
static Keyboard::Scancode FromSDL(SDL_Scancode scancode);
static Keyboard::VKey FromSDL(SDL_Keycode keycode);
static SDL_Scancode ToSDL(Keyboard::Scancode scancode);
static SDL_Keycode ToSDL(Keyboard::VKey keycode);
};
}
#endif // NAZARA_SDL2_HELPER_HPP

View File

@ -0,0 +1,51 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <algorithm>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Platform/Debug.hpp>
#include <Nazara/Platform/SDL2/VideoModeImpl.hpp>
#include <Nazara/Platform/VideoMode.hpp>
#include <SDL2/SDL_video.h>
namespace Nz
{
VideoMode VideoModeImpl::GetDesktopMode()
{
SDL_DisplayMode mode;
if (SDL_GetDesktopDisplayMode(0, &mode) != 0) // handle multi screen ?
{
NazaraError(SDL_GetError());
return VideoMode(800, 600, static_cast<UInt8>(32)); // useless ?
}
return VideoMode(mode.w, mode.h, SDL_BITSPERPIXEL(mode.format));
}
void VideoModeImpl::GetFullscreenModes(std::vector<VideoMode>& modes)
{
SDL_DisplayMode mode;
int numModes = SDL_GetNumDisplayModes(0);
if (numModes < 0)
{
NazaraError(SDL_GetError());
return;
}
for (int i = 0; i < numModes; i++)
{
if (SDL_GetDisplayMode(0, i, &mode) != 0) // handle multi screen ?
NazaraError(SDL_GetError());
VideoMode vMode(mode.w, mode.h, SDL_BITSPERPIXEL(mode.format));
if (std::find(modes.begin(), modes.end(), vMode) == modes.end())
modes.push_back(vMode);
}
}
}

View File

@ -0,0 +1,650 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <cstdio>
#include <memory>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Platform/Config.hpp>
#include <Nazara/Platform/Cursor.hpp>
#include <Nazara/Platform/Icon.hpp>
#include <Nazara/Platform/SDL2/CursorImpl.hpp>
#include <Nazara/Platform/SDL2/IconImpl.hpp>
#include <Nazara/Platform/SDL2/SDLHelper.hpp>
#include <Nazara/Platform/SDL2/WindowImpl.hpp>
#include <Nazara/Utility/Image.hpp>
#include <SDL2/SDL.h>
#include <SDL2/SDL_syswm.h>
namespace Nz
{
namespace
{
WindowImpl* fullscreenWindow = nullptr;
Mouse::Button SDLToNazaraButton(Uint8 sdlButton)
{
switch (sdlButton)
{
case SDL_BUTTON_LEFT:
return Mouse::Left;
case SDL_BUTTON_MIDDLE:
return Mouse::Middle;
case SDL_BUTTON_RIGHT:
return Mouse::Right;
case SDL_BUTTON_X1:
return Mouse::XButton1;
case SDL_BUTTON_X2:
return Mouse::XButton2;
default:
NazaraAssert(false, "Unkown mouse button");
return Mouse::Left;
}
}
}
WindowImpl::WindowImpl(Window* parent) :
m_cursor(nullptr),
m_handle(nullptr),
//m_callback(0),
m_style(0),
m_maxSize(-1),
m_minSize(-1),
m_parent(parent),
m_keyRepeat(true),
m_mouseInside(false),
m_smoothScrolling(false),
m_scrolling(0)
{
m_cursor = SDL_GetDefaultCursor();
}
bool WindowImpl::Create(const VideoMode& mode, const String& title, WindowStyleFlags style)
{
bool async = (style & WindowStyle_Threaded) != 0;
if (async)
{
NazaraError("SDL2 backend doesn't support asyn window for now");
return false;
}
bool fullscreen = (style & WindowStyle_Fullscreen) != 0;
Uint32 winStyle = 0;
unsigned int x, y;
unsigned int width = mode.width;
unsigned int height = mode.height;
if (fullscreen)
winStyle |= SDL_WINDOW_FULLSCREEN;
// Testé une seconde fois car sa valeur peut changer
if (fullscreen)
{
x = 0;
y = 0;
fullscreenWindow = this;
}
else
{
if (!(style & WindowStyle_Titlebar))
winStyle |= SDL_WINDOW_BORDERLESS;
x = SDL_WINDOWPOS_CENTERED;
y = SDL_WINDOWPOS_CENTERED;
}
if (style & WindowStyle_Resizable)
winStyle |= SDL_WINDOW_RESIZABLE;
if (style & WindowStyle_Max)
winStyle |= SDL_WINDOW_MAXIMIZED;
m_eventListener = true;
m_ownsWindow = true;
m_sizemove = false;
m_style = style;
m_handle = SDL_CreateWindow(title.GetConstBuffer(), x, y, width, height, winStyle);
if (!m_handle)
{
NazaraError("Failed to create window: " + Error::GetLastSystemError());
return false;
}
PrepareWindow(fullscreen);
SDL_AddEventWatch(HandleEvent, this);
return true;
}
bool WindowImpl::Create(void* handle)
{
m_handle = SDL_CreateWindowFrom(handle);
if (!m_handle || !SDL_GetWindowID(m_handle))
{
NazaraError("Invalid handle");
return false;
}
m_eventListener = false;
m_ownsWindow = false;
m_sizemove = false;
SDL_GetWindowPosition(m_handle, &m_position.x, &m_position.y);
int width;
int height;
SDL_GetWindowSize(m_handle, &width, &height);
m_size.Set(width, height);
return true;
}
void WindowImpl::Destroy()
{
if (m_ownsWindow && m_handle)
{
SDL_DelEventWatch(HandleEvent, this);
SDL_DestroyWindow(m_handle);
}
else
SetEventListener(false);
}
void WindowImpl::EnableKeyRepeat(bool enable)
{
m_keyRepeat = enable;
}
void WindowImpl::EnableSmoothScrolling(bool enable)
{
m_smoothScrolling = enable;
}
SDL_Window* WindowImpl::GetHandle() const
{
return m_handle;
}
Vector2i WindowImpl::GetPosition() const
{
return m_position;
}
Vector2ui WindowImpl::GetSize() const
{
return m_size;
}
WindowStyleFlags WindowImpl::GetStyle() const
{
return m_style;
}
WindowHandle WindowImpl::GetSystemHandle() const
{
SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version);
if (SDL_GetWindowWMInfo(m_handle, &wmInfo) != SDL_TRUE)
{
ErrorFlags flags(ErrorFlag_ThrowException, true);
NazaraError(std::string("failed to retrieve window manager info: ") + SDL_GetError());
}
WindowHandle handle;
switch (wmInfo.subsystem)
{
#if defined(SDL_VIDEO_DRIVER_X11)
case SDL_SYSWM_X11:
{
handle.type = WindowManager::X11;
handle.x11.display = wmInfo.info.x11.display;
handle.x11.window = wmInfo.info.x11.window;
break;
}
#endif
#if defined(SDL_VIDEO_DRIVER_WAYLAND)
case SDL_SYSWM_WAYLAND:
{
handle.type = WindowManager::Wayland;
handle.wayland.display = wmInfo.info.wl.display;
handle.wayland.surface = wmInfo.info.wl.surface;
handle.wayland.shellSurface = wmInfo.info.wl.shell_surface;
break;
}
#endif
#if defined(SDL_VIDEO_DRIVER_WINDOWS)
case SDL_SYSWM_WINDOWS:
{
handle.type = WindowManager::Windows;
handle.windows.window = wmInfo.info.win.window;
break;
}
#endif
default:
{
ErrorFlags flags(ErrorFlag_ThrowException, true);
NazaraError("unhandled window subsystem");
}
}
return handle;
}
String WindowImpl::GetTitle() const
{
return String::Unicode(SDL_GetWindowTitle(m_handle));
}
bool WindowImpl::HasFocus() const
{
return (SDL_GetWindowFlags(m_handle) & SDL_WINDOW_INPUT_FOCUS) != 0;
}
void WindowImpl::IgnoreNextMouseEvent(int mouseX, int mouseY)
{
m_ignoreNextMouseMove = true;
// Petite astuce ... probablement foireuse dans certains cas :ahde:
m_mousePos.x = mouseX;
m_mousePos.y = mouseY;
}
bool WindowImpl::IsMinimized() const
{
return (SDL_GetWindowFlags(m_handle) & SDL_WINDOW_MINIMIZED) != 0;
}
bool WindowImpl::IsVisible() const
{
return (SDL_GetWindowFlags(m_handle) & SDL_WINDOW_SHOWN) != 0;
}
void WindowImpl::RefreshCursor()
{
if (!m_cursor)
{
if (SDL_ShowCursor(SDL_DISABLE) < 0)
NazaraWarning(SDL_GetError());
}
else
{
if (SDL_ShowCursor(SDL_ENABLE) < 0)
NazaraWarning(SDL_GetError());
SDL_SetCursor(m_cursor);
}
}
void WindowImpl::ProcessEvents(bool block)
{
SDL_PumpEvents();
/*if (m_ownsWindow)
{
if (block)
WaitMessage();
MSG message;
while (PeekMessageW(&message, nullptr, 0, 0, PM_REMOVE))
{
TranslateMessage(&message);
DispatchMessageW(&message);
}
}*/
}
int SDLCALL WindowImpl::HandleEvent(void *userdata, SDL_Event* event)
{
try {
auto window = static_cast<WindowImpl*>(userdata);
WindowEvent evt;
evt.type = WindowEventType::WindowEventType_Max;
switch (event->type)
{
case SDL_WINDOWEVENT:
if (SDL_GetWindowID(window->m_handle) != event->window.windowID)
return 0;
switch (event->window.event)
{
case SDL_WINDOWEVENT_CLOSE:
evt.type = Nz::WindowEventType::WindowEventType_Quit;
break;
case SDL_WINDOWEVENT_RESIZED:
evt.type = Nz::WindowEventType::WindowEventType_Resized;
evt.size.width = static_cast<unsigned int>(std::max(0, event->window.data1));
evt.size.height = static_cast<unsigned int>(std::max(0, event->window.data2));
window->m_size.Set(evt.size.width, evt.size.height);
break;
case SDL_WINDOWEVENT_MOVED:
evt.type = Nz::WindowEventType::WindowEventType_Moved;
evt.position.x = event->window.data1;
evt.position.y = event->window.data2;
window->m_position.Set(event->window.data1, event->window.data2);
break;
case SDL_WINDOWEVENT_FOCUS_GAINED:
evt.type = Nz::WindowEventType::WindowEventType_GainedFocus;
break;
case SDL_WINDOWEVENT_FOCUS_LOST:
evt.type = Nz::WindowEventType::WindowEventType_LostFocus;
break;
case SDL_WINDOWEVENT_ENTER:
evt.type = Nz::WindowEventType::WindowEventType_MouseEntered;
break;
case SDL_WINDOWEVENT_LEAVE:
evt.type = Nz::WindowEventType::WindowEventType_MouseLeft;
break;
}
break;
case SDL_MOUSEMOTION:
if (SDL_GetWindowID(window->m_handle) != event->motion.windowID)
return 0;
if (window->m_ignoreNextMouseMove /*&& event->motion.x == window->m_mousePos.x && event->motion.y == window->m_mousePos.y*/)
{
window->m_ignoreNextMouseMove = false;
return 0;
}
evt.type = Nz::WindowEventType::WindowEventType_MouseMoved;
evt.mouseMove.x = event->motion.x;
evt.mouseMove.y = event->motion.y;
evt.mouseMove.deltaX = event->motion.xrel;
evt.mouseMove.deltaY = event->motion.yrel;
break;
case SDL_MOUSEBUTTONDOWN:
if (SDL_GetWindowID(window->m_handle) != event->button.windowID)
return 0;
evt.mouseButton.button = SDLToNazaraButton(event->button.button);
evt.mouseButton.x = event->button.x;
evt.mouseButton.y = event->button.y;
if (event->button.clicks % 2 == 0)
{
evt.type = Nz::WindowEventType::WindowEventType_MouseButtonDoubleClicked;
window->m_parent->PushEvent(evt);
}
evt.type = Nz::WindowEventType::WindowEventType_MouseButtonPressed;
break;
case SDL_MOUSEBUTTONUP:
if (SDL_GetWindowID(window->m_handle) != event->button.windowID)
return 0;
evt.mouseButton.button = SDLToNazaraButton(event->button.button);
evt.mouseButton.x = event->button.x;
evt.mouseButton.y = event->button.y;
evt.type = Nz::WindowEventType::WindowEventType_MouseButtonReleased;
break;
case SDL_MOUSEWHEEL:
if (SDL_GetWindowID(window->m_handle) != event->wheel.windowID)
return 0;
evt.type = Nz::WindowEventType::WindowEventType_MouseWheelMoved;
evt.mouseWheel.delta = event->wheel.y;
break;
case SDL_KEYDOWN:
if (SDL_GetWindowID(window->m_handle) != event->key.windowID)
return 0;
evt.type = WindowEventType_KeyPressed;
evt.key.scancode = SDLHelper::FromSDL(event->key.keysym.scancode);
evt.key.virtualKey = SDLHelper::FromSDL(event->key.keysym.sym);
evt.key.alt = (event->key.keysym.mod & KMOD_ALT) != 0;
evt.key.control = (event->key.keysym.mod & KMOD_CTRL) != 0;
evt.key.repeated = event->key.repeat != 0;
evt.key.shift = (event->key.keysym.mod & KMOD_SHIFT) != 0;
evt.key.system = (event->key.keysym.mod & KMOD_GUI) != 0;
// implements X11/Win32 APIs behavior for Enter and Backspace
switch (evt.key.virtualKey) {
case Nz::Keyboard::VKey::NumpadReturn:
case Nz::Keyboard::VKey::Return:
if (window->m_lastEditEventLength != 0)
break;
window->m_parent->PushEvent(evt);
evt.type = WindowEventType_TextEntered;
evt.text.character = U'\n';
evt.text.repeated = event->key.repeat != 0;
window->m_parent->PushEvent(evt);
break;
case Nz::Keyboard::VKey::Backspace:
window->m_parent->PushEvent(evt);
evt.type = WindowEventType_TextEntered;
evt.text.character = U'\b';
evt.text.repeated = event->key.repeat != 0;
window->m_parent->PushEvent(evt);
break;
default:
break;
}
break;
case SDL_KEYUP:
if (SDL_GetWindowID(window->m_handle) != event->key.windowID)
return 0;
evt.type = WindowEventType_KeyReleased;
evt.key.scancode = SDLHelper::FromSDL(event->key.keysym.scancode);
evt.key.virtualKey = SDLHelper::FromSDL(event->key.keysym.sym);
evt.key.alt = (event->key.keysym.mod & KMOD_ALT) != 0;
evt.key.control = (event->key.keysym.mod & KMOD_CTRL) != 0;
evt.key.repeated = event->key.repeat != 0;
evt.key.shift = (event->key.keysym.mod & KMOD_SHIFT) != 0;
evt.key.system = (event->key.keysym.mod & KMOD_GUI) != 0;
break;
case SDL_TEXTINPUT:
if (SDL_GetWindowID(window->m_handle) != event->text.windowID)
return 0;
evt.type = WindowEventType_TextEntered;
evt.text.repeated = false;
for (decltype(evt.text.character) codepoint : String::Unicode(event->text.text).Simplify().GetUtf32String())
{
evt.text.character = codepoint;
window->m_parent->PushEvent(evt);
}
// prevent post switch event
evt.type = WindowEventType::WindowEventType_Max;
break;
case SDL_TEXTEDITING:
if (SDL_GetWindowID(window->m_handle) != event->edit.windowID)
return 0;
evt.type = WindowEventType_TextEdited;
evt.edit.length = event->edit.length;
window->m_lastEditEventLength = evt.edit.length;
for (std::size_t i = 0; i < 32; i++)
{
evt.edit.text[i] = event->edit.text[i];
}
break;
}
if (evt.type != WindowEventType::WindowEventType_Max)
window->m_parent->PushEvent(evt);
}
catch (std::exception e)
{
NazaraError(e.what());
}
catch (...) // Don't let any exceptions go thru C calls
{
NazaraError("An unknown error happened");
}
return 0;
}
void WindowImpl::SetCursor(const Cursor& cursor)
{
m_cursor = cursor.m_impl->GetCursor();
if (HasFocus())
RefreshCursor();
}
void WindowImpl::SetEventListener(bool listener)
{
if (m_ownsWindow)
return;
if (listener)
SDL_AddEventWatch(HandleEvent, this);
else
SDL_DelEventWatch(HandleEvent, this);
}
void WindowImpl::SetFocus()
{
SDL_RaiseWindow(m_handle);
}
void WindowImpl::SetIcon(const Icon& icon)
{
SDL_SetWindowIcon(m_handle, icon.m_impl->GetIcon());
}
void WindowImpl::SetMaximumSize(int width, int height)
{
SDL_SetWindowMaximumSize(m_handle, width, height);
}
void WindowImpl::SetMinimumSize(int width, int height)
{
SDL_SetWindowMinimumSize(m_handle, width, height);
}
void WindowImpl::SetPosition(int x, int y)
{
SDL_SetWindowPosition(m_handle, x, y);
}
void WindowImpl::SetSize(unsigned int width, unsigned int height)
{
m_size.Set(width, height);
SDL_SetWindowSize(m_handle, width, height);
}
void WindowImpl::SetStayOnTop(bool stayOnTop)
{
NazaraDebug("Stay on top isn't supported by SDL2 backend for now");
}
void WindowImpl::SetTitle(const String& title)
{
SDL_SetWindowTitle(m_handle, title.GetConstBuffer());
}
void WindowImpl::SetVisible(bool visible)
{
visible ? SDL_ShowWindow(m_handle) : SDL_HideWindow(m_handle);
}
void WindowImpl::PrepareWindow(bool fullscreen)
{
(void)fullscreen; // ignore param warning
SDL_GetWindowPosition(m_handle, &m_position.x, &m_position.y);
int width, height;
SDL_GetWindowSize(m_handle, &width, &height);
m_size.Set(width, height);
}
bool WindowImpl::Initialize()
{
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
NazaraError(SDL_GetError());
return false;
}
return true;
}
void WindowImpl::Uninitialize()
{
SDL_Quit();
}
// not implemented for now, wait for mainloop friendly input
//void WindowImpl::WindowThread(SDL_Window* handle, /*DWORD styleEx,*/ const String& title, /*DWORD style,*/ bool fullscreen, const Rectui& dimensions, WindowImpl* window, Mutex* mutex, ConditionVariable* condition)
//{
// SDL_Window& winHandle = *handle;
/*winHandle = CreateWindowExW(styleEx, className, title.GetWideString().data(), style, dimensions.x, dimensions.y, dimensions.width, dimensions.height, nullptr, nullptr, GetModuleHandle(nullptr), window);
if (winHandle)
window->PrepareWindow(fullscreen);
mutex->Lock();
condition->Signal();
mutex->Unlock(); // mutex and condition may be destroyed after this line
if (!winHandle)
return;
while (window->m_threadActive)
window->ProcessEvents(true);
DestroyWindow(winHandle);*/
//}
}

View File

@ -9,7 +9,6 @@
#ifndef NAZARA_WINDOWIMPL_HPP
#define NAZARA_WINDOWIMPL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Math/Rect.hpp>
#include <Nazara/Math/Vector2.hpp>
@ -18,17 +17,15 @@
#include <Nazara/Platform/Mouse.hpp>
#include <Nazara/Platform/VideoMode.hpp>
#include <Nazara/Platform/Window.hpp>
#include <condition_variable>
#include <mutex>
#include <thread>
#include <windows.h>
#include <Nazara/Prerequisites.hpp>
#include <SDL2/SDL_events.h>
#include <SDL2/SDL_keyboard.h>
#include <SDL2/SDL_video.h>
namespace Nz
{
class Window;
#undef IsMinimized // Conflits with windows.h redefinition
class WindowImpl
{
public:
@ -38,17 +35,18 @@ namespace Nz
~WindowImpl() = default;
bool Create(const VideoMode& mode, const String& title, WindowStyleFlags style);
bool Create(WindowHandle handle);
bool Create(void* handle);
void Destroy();
void EnableKeyRepeat(bool enable);
void EnableSmoothScrolling(bool enable);
WindowHandle GetHandle() const;
SDL_Window* GetHandle() const;
Vector2i GetPosition() const;
Vector2ui GetSize() const;
WindowStyleFlags GetStyle() const;
WindowHandle GetSystemHandle() const;
String GetTitle() const;
bool HasFocus() const;
@ -81,26 +79,22 @@ namespace Nz
static void Uninitialize();
private:
bool HandleMessage(HWND window, UINT message, WPARAM wParam, LPARAM lParam);
int static SDLCALL HandleEvent(void *userdata, SDL_Event * event);
void PrepareWindow(bool fullscreen);
static Keyboard::Key ConvertVirtualKey(WPARAM key, LPARAM flags);
static LRESULT CALLBACK MessageHandler(HWND window, UINT message, WPARAM wParam, LPARAM lParam);
static UInt32 RetrieveStyle(HWND window);
static void WindowThread(HWND& handle, DWORD styleEx, const String& title, DWORD style, bool fullscreen, const Rectui& dimensions, WindowImpl* window, std::mutex& mutex, std::condition_variable& condition);
HCURSOR m_cursor;
HWND m_handle;
LONG_PTR m_callback;
int m_lastEditEventLength = 0;
SDL_Cursor* m_cursor;
SDL_Window* m_handle;
WindowStyleFlags m_style;
Vector2i m_maxSize;
Vector2i m_minSize;
Vector2i m_mousePos;
Vector2i m_position;
Vector2ui m_size;
std::thread m_thread;
Window* m_parent;
bool m_eventListener;
bool m_ignoreNextMouseMove = false;
bool m_keyRepeat;
bool m_mouseInside;
bool m_ownsWindow;

View File

@ -5,15 +5,7 @@
#include <Nazara/Platform/VideoMode.hpp>
#include <algorithm>
#include <functional>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Platform/Win32/VideoModeImpl.hpp>
#elif defined(NAZARA_PLATFORM_X11)
#include <Nazara/Platform/X11/VideoModeImpl.hpp>
#else
#error Lack of implementation: Window
#endif
#include <Nazara/Platform/SDL2/VideoModeImpl.hpp>
#include <Nazara/Platform/Debug.hpp>
namespace Nz

View File

@ -1,106 +0,0 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Platform/Win32/CursorImpl.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Utility/Image.hpp>
#include <Nazara/Utility/PixelFormat.hpp>
#include <Nazara/Platform/Debug.hpp>
namespace Nz
{
bool CursorImpl::Create(const Image& cursor, int hotSpotX, int hotSpotY)
{
Image windowsCursor(cursor);
if (!windowsCursor.Convert(PixelFormat_BGRA8))
{
NazaraError("Failed to convert cursor to BGRA8");
return false;
}
HBITMAP bitmap = CreateBitmap(windowsCursor.GetWidth(), windowsCursor.GetHeight(), 1, 32, windowsCursor.GetConstPixels());
HBITMAP monoBitmap = CreateBitmap(windowsCursor.GetWidth(), windowsCursor.GetHeight(), 1, 1, nullptr);
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms648052(v=vs.85).aspx
ICONINFO iconInfo;
iconInfo.fIcon = FALSE;
iconInfo.xHotspot = hotSpotX;
iconInfo.yHotspot = hotSpotY;
iconInfo.hbmMask = monoBitmap;
iconInfo.hbmColor = bitmap;
m_icon = CreateIconIndirect(&iconInfo);
DeleteObject(bitmap);
DeleteObject(monoBitmap);
if (!m_icon)
{
NazaraError("Failed to create cursor: " + Error::GetLastSystemError());
return false;
}
m_cursor = m_icon;
return true;
}
bool CursorImpl::Create(SystemCursor cursor)
{
if (cursor != SystemCursor_None)
m_cursor = static_cast<HCURSOR>(LoadImage(nullptr, s_systemCursorIds[cursor], IMAGE_CURSOR, 0, 0, LR_SHARED));
else
m_cursor = nullptr;
// No need to free the cursor if shared
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms648045(v=vs.85).aspx
m_icon = nullptr;
return true;
}
void CursorImpl::Destroy()
{
if (m_icon)
DestroyIcon(m_icon);
}
HCURSOR CursorImpl::GetCursor()
{
return m_cursor;
}
bool CursorImpl::Initialize()
{
return true;
}
void CursorImpl::Uninitialize()
{
}
std::array<LPTSTR, SystemCursor_Max + 1> CursorImpl::s_systemCursorIds =
{
IDC_CROSS, // SystemCursor_Crosshair
IDC_ARROW, // SystemCursor_Default
IDC_HAND, // SystemCursor_Hand
IDC_HELP, // SystemCursor_Help
IDC_SIZEALL, // SystemCursor_Move
nullptr, // SystemCursor_None
IDC_HAND, // SystemCursor_Pointer
IDC_APPSTARTING, // SystemCursor_Progress
IDC_SIZEWE, // SystemCursor_ResizeE
IDC_SIZENS, // SystemCursor_ResizeN
IDC_SIZENESW, // SystemCursor_ResizeNE
IDC_SIZENWSE, // SystemCursor_ResizeNW
IDC_SIZENS, // SystemCursor_ResizeS
IDC_SIZENWSE, // SystemCursor_ResizeSE
IDC_SIZENESW, // SystemCursor_ResizeSW
IDC_SIZEWE, // SystemCursor_ResizeW
IDC_IBEAM, // SystemCursor_Text
IDC_WAIT // SystemCursor_Wait
};
static_assert(SystemCursor_Max + 1 == 18, "System cursor array is incomplete");
}

View File

@ -1,53 +0,0 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Platform/Win32/IconImpl.hpp>
#include <Nazara/Utility/Image.hpp>
#include <Nazara/Utility/PixelFormat.hpp>
#include <Nazara/Platform/Debug.hpp>
namespace Nz
{
bool IconImpl::Create(const Image& icon)
{
Image windowsIcon(icon); // Vive le COW
if (!windowsIcon.Convert(PixelFormat_BGRA8))
{
NazaraError("Failed to convert icon to BGRA8");
return false;
}
HBITMAP bitmap = CreateBitmap(windowsIcon.GetWidth(), windowsIcon.GetHeight(), 1, 32, windowsIcon.GetConstPixels());
HBITMAP monoBitmap = CreateBitmap(windowsIcon.GetWidth(), windowsIcon.GetHeight(), 1, 1, nullptr);
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms648052(v=vs.85).aspx
ICONINFO iconInfo;
iconInfo.fIcon = TRUE;
iconInfo.hbmMask = monoBitmap;
iconInfo.hbmColor = bitmap;
m_icon = CreateIconIndirect(&iconInfo);
DeleteObject(bitmap);
DeleteObject(monoBitmap);
if (!m_icon)
{
NazaraError("Failed to create icon: " + Error::GetLastSystemError());
return false;
}
return true;
}
void IconImpl::Destroy()
{
DestroyIcon(m_icon);
}
HICON IconImpl::GetIcon()
{
return m_icon;
}
}

View File

@ -1,296 +0,0 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Platform/Win32/InputImpl.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Platform/Window.hpp>
#include <windows.h>
#include <Nazara/Platform/Debug.hpp>
namespace Nz
{
namespace
{
int vKeys[Keyboard::Count] = {
// Lettres
0x41, // Key::A
0x42, // Key::B
0x43, // Key::C
0x44, // Key::D
0x45, // Key::E
0x46, // Key::F
0x47, // Key::G
0x48, // Key::H
0x49, // Key::I
0x4A, // Key::J
0x4B, // Key::K
0x4C, // Key::L
0x4D, // Key::M
0x4E, // Key::N
0x4F, // Key::O
0x50, // Key::P
0x51, // Key::Q
0x52, // Key::R
0x53, // Key::S
0x54, // Key::T
0x55, // Key::U
0x56, // Key::V
0x57, // Key::W
0x58, // Key::X
0x59, // Key::Y
0x5A, // Key::Z
// Touches de fonction
VK_F1, // Key::F1
VK_F2, // Key::F2
VK_F3, // Key::F3
VK_F4, // Key::F4
VK_F5, // Key::F5
VK_F6, // Key::F6
VK_F7, // Key::F7
VK_F8, // Key::F8
VK_F9, // Key::F9
VK_F10, // Key::F10
VK_F11, // Key::F11
VK_F12, // Key::F12
VK_F13, // Key::F13
VK_F14, // Key::F14
VK_F15, // Key::F15
// Flèches directionnelles
VK_DOWN, // Key::Down
VK_LEFT, // Key::Left
VK_RIGHT, // Key::Right
VK_UP, // Key::Up
// Pavé numérique
VK_ADD, // Key::Add
VK_DECIMAL, // Key::Decimal
VK_DIVIDE, // Key::Divide
VK_MULTIPLY, // Key::Multiply
VK_NUMPAD0, // Key::Numpad0
VK_NUMPAD1, // Key::Numpad1
VK_NUMPAD2, // Key::Numpad2
VK_NUMPAD3, // Key::Numpad3
VK_NUMPAD4, // Key::Numpad4
VK_NUMPAD5, // Key::Numpad5
VK_NUMPAD6, // Key::Numpad6
VK_NUMPAD7, // Key::Numpad7
VK_NUMPAD8, // Key::Numpad8
VK_NUMPAD9, // Key::Numpad9
VK_SUBTRACT, // Key::Subtract
// Diverss
VK_OEM_5, // Key::Backslash
VK_BACK, // Key::Backspace
VK_CLEAR, // Key::Clear
VK_OEM_COMMA, // Key::Comma,
VK_OEM_MINUS, // Key::Dash
VK_DELETE, // Key::Delete
VK_END, // Key::End
VK_OEM_PLUS, // Key::Equal
VK_ESCAPE, // Key::Escape
VK_HOME, // Key::Home
VK_INSERT, // Key::Insert
VK_LMENU, // Key::LAlt
VK_OEM_4, // Key::LBracket
VK_LCONTROL, // Key::LControl
VK_LSHIFT, // Key::LShift
VK_LWIN, // Key::LSystem
0x30, // Key::Num0
0x31, // Key::Num1
0x32, // Key::Num2
0x33, // Key::Num3
0x34, // Key::Num4
0x35, // Key::Num5
0x36, // Key::Num6
0x37, // Key::Num7
0x38, // Key::Num8
0x39, // Key::Num9
VK_NEXT, // Key::PageDown
VK_PRIOR, // Key::PageUp
VK_PAUSE, // Key::Pause
VK_OEM_PERIOD, // Key::Period
VK_PRINT, // Key::Print
VK_SNAPSHOT, // Key::PrintScreen
VK_OEM_7, // Key::Quote
VK_RMENU, // Key::RAlt
VK_OEM_6, // Key::RBracket
VK_RCONTROL, // Key::RControl
VK_RETURN, // Key::Return
VK_RSHIFT, // Key::RShift
VK_RWIN, // Key::RSystem
VK_OEM_1, // Key::Semicolon
VK_OEM_2, // Key::Slash
VK_SPACE, // Key::Space
VK_TAB, // Key::Tab
VK_OEM_3, // Key::Tilde
// Touches navigateur
VK_BROWSER_BACK, // Key::Browser_Back
VK_BROWSER_FAVORITES, // Key::Browser_Favorites
VK_BROWSER_FORWARD, // Key::Browser_Forward
VK_BROWSER_HOME, // Key::Browser_Home
VK_BROWSER_REFRESH, // Key::Browser_Refresh
VK_BROWSER_SEARCH, // Key::Browser_Search
VK_BROWSER_STOP, // Key::Browser_Stop
// Touches de contrôle
VK_MEDIA_NEXT_TRACK, // Key::Media_Next,
VK_MEDIA_PLAY_PAUSE, // Key::Media_PlayPause,
VK_MEDIA_PREV_TRACK, // Key::Media_Previous,
VK_MEDIA_STOP, // Key::Media_Stop,
// Touches de contrôle du volume
VK_VOLUME_DOWN, // Key::Volume_Down
VK_VOLUME_MUTE, // Key::Volume_Mute
VK_VOLUME_UP, // Key::Volume_Up
// Touches à verrouillage
VK_CAPITAL, // Key::CapsLock
VK_NUMLOCK, // Key::NumLock
VK_SCROLL // Key::ScrollLock
};
}
String EventImpl::GetKeyName(Keyboard::Key key)
{
// http://www.ffuts.org/blog/mapvirtualkey-getkeynametext-and-a-story-of-how-to/
int vk = vKeys[key];
unsigned int code = MapVirtualKeyW(vk, 0) << 16;
///FIXME: Liste complète ?
switch (vk)
{
case VK_ATTN:
case VK_DOWN:
case VK_DECIMAL:
case VK_DELETE:
case VK_DIVIDE:
case VK_END:
case VK_HOME:
case VK_INSERT:
case VK_LEFT:
case VK_LWIN:
case VK_OEM_1:
case VK_OEM_2:
case VK_OEM_3:
case VK_OEM_4:
case VK_OEM_5:
case VK_OEM_6:
case VK_OEM_7:
case VK_OEM_CLEAR:
case VK_OEM_COMMA:
case VK_OEM_MINUS:
case VK_OEM_PERIOD:
case VK_OEM_PLUS:
case VK_PAUSE:
case VK_NEXT:
case VK_NUMLOCK:
case VK_PRIOR:
case VK_RIGHT:
case VK_RWIN:
case VK_UP:
code |= 0x1000000; // 24ème bit pour l'extension
break;
}
wchar_t keyName[20]; // Je ne pense pas que ça dépassera 20 caractères
if (!GetKeyNameTextW(code, &keyName[0], 20))
return "Unknown";
return String::Unicode(keyName);
}
Vector2i EventImpl::GetMousePosition()
{
POINT pos;
GetCursorPos(&pos);
return Vector2i(pos.x, pos.y);
}
Vector2i EventImpl::GetMousePosition(const Window& relativeTo)
{
HWND handle = static_cast<HWND>(relativeTo.GetHandle());
if (handle)
{
POINT pos;
GetCursorPos(&pos);
ScreenToClient(handle, &pos);
return Vector2i(pos.x, pos.y);
}
else
{
NazaraError("Invalid window handle");
// Attention que (-1, -1) est une position tout à fait valide et ne doit pas servir de test
return Vector2i(-1, -1);
}
}
bool EventImpl::IsKeyPressed(Keyboard::Key key)
{
switch (key)
{
case Keyboard::CapsLock:
case Keyboard::NumLock:
case Keyboard::ScrollLock:
return GetKeyState(vKeys[key]) != 0;
default:
return (GetAsyncKeyState(vKeys[key]) & 0x8000) != 0;
}
}
bool EventImpl::IsMouseButtonPressed(Mouse::Button button)
{
static int vButtons[Mouse::Max+1] = {
VK_LBUTTON, // Button::Left
VK_MBUTTON, // Button::Middle
VK_RBUTTON, // Button::Right
VK_XBUTTON1, // Button::XButton1
VK_XBUTTON2 // Button::XButton2
};
// Gestion de l'inversement des boutons de la souris
if (GetSystemMetrics(SM_SWAPBUTTON))
{
switch (button)
{
case Mouse::Left:
button = Mouse::Right;
break;
case Mouse::Right:
button = Mouse::Left;
break;
default:
break;
}
}
return (GetAsyncKeyState(vButtons[button]) & 0x8000) != 0;
}
void EventImpl::SetMousePosition(int x, int y)
{
SetCursorPos(x, y);
}
void EventImpl::SetMousePosition(int x, int y, const Window& relativeTo)
{
HWND handle = static_cast<HWND>(relativeTo.GetHandle());
if (handle)
{
POINT pos = {x, y};
ClientToScreen(handle, &pos);
SetCursorPos(pos.x, pos.y);
}
else
NazaraError("Invalid window handle");
}
}

View File

@ -1,35 +0,0 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Platform/Win32/VideoModeImpl.hpp>
#include <Nazara/Platform/VideoMode.hpp>
#include <algorithm>
#include <windows.h>
#include <Nazara/Platform/Debug.hpp>
namespace Nz
{
VideoMode VideoModeImpl::GetDesktopMode()
{
DEVMODE mode;
mode.dmSize = sizeof(DEVMODE);
EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &mode);
return VideoMode(mode.dmPelsWidth, mode.dmPelsHeight, static_cast<UInt8>(mode.dmBitsPerPel));
}
void VideoModeImpl::GetFullscreenModes(std::vector<VideoMode>& modes)
{
DEVMODE win32Mode;
win32Mode.dmSize = sizeof(DEVMODE);
for (unsigned int i = 0; EnumDisplaySettings(nullptr, i, &win32Mode); ++i)
{
VideoMode mode(win32Mode.dmPelsWidth, win32Mode.dmPelsHeight, static_cast<UInt8>(win32Mode.dmBitsPerPel));
// Il existe plusieurs modes avec ces trois caractéristques identiques
if (std::find(modes.begin(), modes.end(), mode) == modes.end())
modes.push_back(mode);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -7,15 +7,7 @@
#include <Nazara/Core/Error.hpp>
#include <Nazara/Platform/Cursor.hpp>
#include <Nazara/Platform/Icon.hpp>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Platform/Win32/WindowImpl.hpp>
#elif defined(NAZARA_PLATFORM_X11)
#include <Nazara/Platform/X11/WindowImpl.hpp>
#else
#error Lack of implementation: Window
#endif
#include <Nazara/Platform/SDL2/WindowImpl.hpp>
#include <Nazara/Platform/Debug.hpp>
namespace Nz
@ -128,7 +120,7 @@ namespace Nz
return true;
}
bool Window::Create(WindowHandle handle)
bool Window::Create(void* handle)
{
Destroy();
@ -201,19 +193,6 @@ namespace Nz
m_impl->EnableSmoothScrolling(enable);
}
WindowHandle Window::GetHandle() const
{
#if NAZARA_PLATFORM_SAFE
if (!m_impl)
{
NazaraError("Window not created");
return static_cast<WindowHandle>(0);
}
#endif
return m_impl->GetHandle();
}
Vector2i Window::GetPosition() const
{
#if NAZARA_PLATFORM_SAFE
@ -253,6 +232,19 @@ namespace Nz
return m_impl->GetStyle();
}
WindowHandle Window::GetSystemHandle() const
{
#if NAZARA_PLATFORM_SAFE
if (!m_impl)
{
NazaraError("Window not created");
return {};
}
#endif
return m_impl->GetSystemHandle();
}
String Window::GetTitle() const
{
#if NAZARA_PLATFORM_SAFE
@ -617,6 +609,11 @@ namespace Nz
return *this;
}
void* Window::GetHandle()
{
return (m_impl) ? m_impl->GetHandle() : nullptr;
}
bool Window::OnWindowCreated()
{
return true;

View File

@ -1,270 +0,0 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Platform/X11/CursorImpl.hpp>
#include <Nazara/Core/CallOnExit.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Utility/Image.hpp>
#include <Nazara/Platform/X11/Display.hpp>
#include <Nazara/Platform/X11/ScopedXCB.hpp>
#include <xcb/xcb_image.h>
// Some older versions of xcb/util-renderutil (notably the one available on Travis CI) use `template` as an argument name
// This is a fixed bug (https://cgit.freedesktop.org/xcb/util-renderutil/commit/?id=8d15acc45a47dc4c922eee5b99885db42bc62c17) but until Travis-CI
// has upgraded their Ubuntu version, I'm forced to use this ugly trick.
#define template ptemplate
extern "C"
{
#include <xcb/xcb_renderutil.h>
}
#undef template
#include <Nazara/Platform/Debug.hpp>
namespace Nz
{
bool CursorImpl::Create(const Image& cursor, int hotSpotX, int hotSpotY)
{
Image cursorImage(cursor); // Vive le COW
if (!cursorImage.Convert(Nz::PixelFormatType_BGRA8))
{
NazaraError("Failed to convert cursor to BGRA8");
return false;
}
auto width = cursorImage.GetWidth();
auto height = cursorImage.GetHeight();
ScopedXCBConnection connection;
xcb_screen_t* screen = X11::XCBDefaultScreen(connection);
ScopedXCB<xcb_generic_error_t> error(nullptr);
ScopedXCB<xcb_render_query_pict_formats_reply_t> formatsReply = xcb_render_query_pict_formats_reply(
connection,
xcb_render_query_pict_formats(connection),
&error);
if (!formatsReply || error)
{
NazaraError("Failed to get pict formats");
return false;
}
xcb_render_pictforminfo_t* fmt = xcb_render_util_find_standard_format(
formatsReply.get(),
XCB_PICT_STANDARD_ARGB_32);
if (!fmt)
{
NazaraError("Failed to find format PICT_STANDARD_ARGB_32");
return false;
}
xcb_image_t* xi = xcb_image_create(
width, height,
XCB_IMAGE_FORMAT_Z_PIXMAP,
32, 32, 32, 32,
XCB_IMAGE_ORDER_LSB_FIRST,
XCB_IMAGE_ORDER_MSB_FIRST,
0, 0, 0);
if (!xi)
{
NazaraError("Failed to create image for cursor");
return false;
}
std::unique_ptr<uint8_t[]> data(new uint8_t[xi->stride * height]);
if (!data)
{
xcb_image_destroy(xi);
NazaraError("Failed to allocate memory for cursor image");
return false;
}
xi->data = data.get();
std::copy(cursorImage.GetConstPixels(), cursorImage.GetConstPixels() + cursorImage.GetBytesPerPixel() * width * height, xi->data);
xcb_render_picture_t pic = XCB_NONE;
CallOnExit onExit([&](){
xcb_image_destroy(xi);
if (pic != XCB_NONE)
xcb_render_free_picture(connection, pic);
});
XCBPixmap pix(connection);
if (!pix.Create(32, screen->root, width, height))
{
NazaraError("Failed to create pixmap for cursor");
return false;
}
pic = xcb_generate_id(connection);
if (!X11::CheckCookie(
connection,
xcb_render_create_picture(
connection,
pic,
pix,
fmt->id,
0,
nullptr
)))
{
NazaraError("Failed to create render picture for cursor");
return false;
}
XCBGContext gc(connection);
if (!gc.Create(pix, 0, nullptr))
{
NazaraError("Failed to create gcontext for cursor");
return false;
}
if (!X11::CheckCookie(
connection,
xcb_image_put(
connection,
pix,
gc,
xi,
0, 0,
0
)))
{
NazaraError("Failed to put image for cursor");
return false;
}
m_cursor = xcb_generate_id(connection);
if (!X11::CheckCookie(
connection,
xcb_render_create_cursor(
connection,
m_cursor,
pic,
hotSpotX, hotSpotY
)))
{
NazaraError("Failed to create cursor");
return false;
}
return true;
}
bool CursorImpl::Create(SystemCursor cursor)
{
ScopedXCBConnection connection;
xcb_screen_t* screen = X11::XCBDefaultScreen(connection);
const char* cursorName = s_systemCursorIds[cursor];
if (cursorName)
{
if (xcb_cursor_context_new(connection, screen, &m_cursorContext) >= 0)
m_cursor = xcb_cursor_load_cursor(m_cursorContext, cursorName);
else
{
NazaraError("Failed to create cursor context");
return false;
}
}
else
m_cursor = s_hiddenCursor;
return true;
}
void CursorImpl::Destroy()
{
ScopedXCBConnection connection;
xcb_free_cursor(connection, m_cursor);
if (m_cursorContext)
xcb_cursor_context_free(m_cursorContext);
}
xcb_cursor_t CursorImpl::GetCursor()
{
return m_cursor;
}
bool CursorImpl::Initialize()
{
ScopedXCBConnection connection;
XCBPixmap cursorPixmap(connection);
xcb_window_t window = X11::XCBDefaultRootWindow(connection);
if (!cursorPixmap.Create(1, window, 1, 1))
{
NazaraError("Failed to create pixmap for hidden cursor");
return false;
}
s_hiddenCursor = xcb_generate_id(connection);
// Create the cursor, using the pixmap as both the shape and the mask of the cursor
if (!X11::CheckCookie(
connection, xcb_create_cursor(connection,
s_hiddenCursor,
cursorPixmap,
cursorPixmap,
0, 0, 0, // Foreground RGB color
0, 0, 0, // Background RGB color
0, // X
0 // Y
)))
{
NazaraError("Failed to create hidden cursor");
return false;
}
return true;
}
void CursorImpl::Uninitialize()
{
if (s_hiddenCursor)
{
ScopedXCBConnection connection;
xcb_free_cursor(connection, s_hiddenCursor);
s_hiddenCursor = 0;
}
}
xcb_cursor_t CursorImpl::s_hiddenCursor = 0;
std::array<const char*, SystemCursor_Max + 1> CursorImpl::s_systemCursorIds =
{
{
// http://gnome-look.org/content/preview.php?preview=1&id=128170&file1=128170-1.png&file2=&file3=&name=Dummy+X11+cursors&PHPSESSID=6
"crosshair", // SystemCursor_Crosshair
"left_ptr", // SystemCursor_Default
"hand", // SystemCursor_Hand
"help", // SystemCursor_Help
"fleur", // SystemCursor_Move
nullptr, // SystemCursor_None
"hand", // SystemCursor_Pointer
"watch", // SystemCursor_Progress
"right_side", // SystemCursor_ResizeE
"top_side", // SystemCursor_ResizeN
"top_right_corner", // SystemCursor_ResizeNE
"top_left_corner", // SystemCursor_ResizeNW
"bottom_side", // SystemCursor_ResizeS
"bottom_right_corner", // SystemCursor_ResizeSE
"bottom_left_corner", // SystemCursor_ResizeSW
"left_side", // SystemCursor_ResizeW
"xterm", // SystemCursor_Text
"watch" // SystemCursor_Wait
}
};
static_assert(SystemCursor_Max + 1 == 18, "System cursor array is incomplete");
}

View File

@ -1,43 +0,0 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_CURSORIMPL_HPP
#define NAZARA_CURSORIMPL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Platform/Enums.hpp>
#include <xcb/xcb_cursor.h>
#include <array>
namespace Nz
{
class Image;
class CursorImpl
{
friend class Cursor;
public:
bool Create(const Image& image, int hotSpotX, int hotSpotY);
bool Create(SystemCursor cursor);
void Destroy();
xcb_cursor_t GetCursor();
private:
static bool Initialize();
static void Uninitialize();
xcb_cursor_t m_cursor = 0;
xcb_cursor_context_t* m_cursorContext = nullptr;
static xcb_cursor_t s_hiddenCursor;
static std::array<const char*, SystemCursor_Max + 1> s_systemCursorIds;
};
}
#endif // NAZARA_CURSORIMPL_HPP

View File

@ -1,247 +0,0 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Platform/X11/Display.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Platform/X11/ScopedXCB.hpp>
#include <xcb/xcb_keysyms.h>
#include <map>
#include <Nazara/Platform/Debug.hpp>
namespace Nz
{
namespace
{
// The shared display and its reference counter
xcb_connection_t* sharedConnection = nullptr;
int screen_nbr = 0;
unsigned int referenceCountConnection = 0;
xcb_key_symbols_t* sharedkeySymbol = nullptr;
unsigned int referenceCountKeySymbol = 0;
xcb_ewmh_connection_t* sharedEwmhConnection = nullptr;
unsigned int referenceCountEwmhConnection = 0;
using AtomMap = std::map<String, xcb_atom_t>;
AtomMap atoms;
}
bool X11::CheckCookie(xcb_connection_t* connection, xcb_void_cookie_t cookie)
{
ScopedXCB<xcb_generic_error_t> error(xcb_request_check(
connection,
cookie
));
if (error)
return false;
else
return true;
}
void X11::CloseConnection(xcb_connection_t* connection)
{
NazaraAssert(connection == sharedConnection, "The model is meant for one connection to X11 server");
--referenceCountConnection;
}
void X11::CloseEWMHConnection(xcb_ewmh_connection_t* ewmh_connection)
{
NazaraAssert(ewmh_connection == sharedEwmhConnection, "The model is meant for one connection to X11 server");
--referenceCountEwmhConnection;
}
xcb_atom_t X11::GetAtom(const String& name, bool onlyIfExists)
{
AtomMap::const_iterator iter = atoms.find(name);
if (iter != atoms.end())
return iter->second;
ScopedXCB<xcb_generic_error_t> error(nullptr);
xcb_connection_t* connection = OpenConnection();
ScopedXCB<xcb_intern_atom_reply_t> reply(xcb_intern_atom_reply(
connection,
xcb_intern_atom(
connection,
onlyIfExists,
name.GetSize(),
name.GetConstBuffer()
),
&error
));
CloseConnection(connection);
if (error || !reply)
{
NazaraError("Failed to get " + name + " atom.");
return XCB_ATOM_NONE;
}
atoms[name] = reply->atom;
return reply->atom;
}
bool X11::Initialize()
{
if (IsInitialized())
{
s_moduleReferenceCounter++;
return true; // Déjà initialisé
}
s_moduleReferenceCounter++;
NazaraAssert(referenceCountConnection == 0, "Initialize should be called before anything");
NazaraAssert(referenceCountKeySymbol == 0, "Initialize should be called before anything");
NazaraAssert(referenceCountEwmhConnection == 0, "Initialize should be called before anything");
{
sharedConnection = xcb_connect(nullptr, &screen_nbr);
// Opening display failed: The best we can do at the moment is to output a meaningful error message
if (!sharedConnection || xcb_connection_has_error(sharedConnection))
{
NazaraError("Failed to open xcb connection");
return false;
}
OpenConnection();
}
{
sharedkeySymbol = xcb_key_symbols_alloc(sharedConnection);
XCBKeySymbolsAlloc(sharedConnection);
}
{
sharedEwmhConnection = new xcb_ewmh_connection_t;
xcb_intern_atom_cookie_t* ewmh_cookie = xcb_ewmh_init_atoms(sharedConnection, sharedEwmhConnection);
if(!xcb_ewmh_init_atoms_replies(sharedEwmhConnection, ewmh_cookie, nullptr))
{
NazaraError("Could not initialize EWMH Connection");
sharedEwmhConnection = nullptr;
}
OpenEWMHConnection(sharedConnection);
}
return true;
}
bool X11::IsInitialized()
{
return s_moduleReferenceCounter != 0;
}
xcb_key_symbols_t* X11::XCBKeySymbolsAlloc(xcb_connection_t* connection)
{
NazaraAssert(connection == sharedConnection, "The model is meant for one connection to X11 server");
++referenceCountKeySymbol;
return sharedkeySymbol;
}
void X11::XCBKeySymbolsFree(xcb_key_symbols_t* keySymbols)
{
NazaraAssert(keySymbols == sharedkeySymbol, "The model is meant for one connection to X11 server");
--referenceCountKeySymbol;
}
xcb_connection_t* X11::OpenConnection()
{
++referenceCountConnection;
return sharedConnection;
}
xcb_ewmh_connection_t* X11::OpenEWMHConnection(xcb_connection_t* connection)
{
NazaraAssert(connection == sharedConnection, "The model is meant for one connection to X11 server");
++referenceCountEwmhConnection;
return sharedEwmhConnection;
}
void X11::Uninitialize()
{
if (s_moduleReferenceCounter != 1)
{
// Le module est soit encore utilisé, soit pas initialisé
if (s_moduleReferenceCounter > 1)
s_moduleReferenceCounter--;
return;
}
s_moduleReferenceCounter = 0;
{
NazaraAssert(referenceCountEwmhConnection == 1, "Uninitialize should be called after anything or a close is missing");
CloseEWMHConnection(sharedEwmhConnection);
xcb_ewmh_connection_wipe(sharedEwmhConnection);
delete sharedEwmhConnection;
}
{
NazaraAssert(referenceCountKeySymbol == 1, "Uninitialize should be called after anything or a free is missing");
XCBKeySymbolsFree(sharedkeySymbol);
xcb_key_symbols_free(sharedkeySymbol);
}
{
NazaraAssert(referenceCountConnection == 1, "Uninitialize should be called after anything or a close is missing");
CloseConnection(sharedConnection);
xcb_disconnect(sharedConnection);
}
}
xcb_window_t X11::XCBDefaultRootWindow(xcb_connection_t* connection)
{
NazaraAssert(connection == sharedConnection, "The model is meant for one connection to X11 server");
xcb_screen_t* screen = XCBDefaultScreen(connection);
if (screen)
return screen->root;
return XCB_NONE;
}
xcb_screen_t* X11::XCBDefaultScreen(xcb_connection_t* connection)
{
NazaraAssert(connection == sharedConnection, "The model is meant for one connection to X11 server");
return XCBScreenOfDisplay(connection, screen_nbr);
}
int X11::XCBScreen(xcb_connection_t* connection)
{
NazaraAssert(connection == sharedConnection, "The model is meant for one connection to X11 server");
return screen_nbr;
}
xcb_screen_t* X11::XCBScreenOfDisplay(xcb_connection_t* connection, int screenIndex)
{
NazaraAssert(connection == sharedConnection, "The model is meant for one connection to X11 server");
xcb_screen_iterator_t iter = xcb_setup_roots_iterator(xcb_get_setup(connection));
for (; iter.rem; --screenIndex, xcb_screen_next (&iter))
{
if (screenIndex == 0)
return iter.data;
}
return nullptr;
}
unsigned int X11::s_moduleReferenceCounter = 0;
}

View File

@ -1,54 +0,0 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_X11DISPLAY_HPP
#define NAZARA_X11DISPLAY_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Platform/Config.hpp>
#include <xcb/xcb.h>
#include <xcb/xcb_ewmh.h>
typedef struct _XCBKeySymbols xcb_key_symbols_t;
namespace Nz
{
class String;
class NAZARA_PLATFORM_API X11
{
public:
X11() = delete;
~X11() = delete;
static bool CheckCookie(xcb_connection_t* connection, xcb_void_cookie_t cookie);
static void CloseConnection(xcb_connection_t* connection);
static void CloseEWMHConnection(xcb_ewmh_connection_t* ewmh_connection);
static xcb_atom_t GetAtom(const String& name, bool onlyIfExists = false);
static bool Initialize();
static bool IsInitialized();
static xcb_key_symbols_t* XCBKeySymbolsAlloc(xcb_connection_t* connection);
static void XCBKeySymbolsFree(xcb_key_symbols_t* keySymbols);
static xcb_connection_t* OpenConnection();
static xcb_ewmh_connection_t* OpenEWMHConnection(xcb_connection_t* connection);
static void Uninitialize();
static xcb_screen_t* XCBDefaultScreen(xcb_connection_t* connection);
static xcb_window_t XCBDefaultRootWindow(xcb_connection_t* connection);
static int XCBScreen(xcb_connection_t* connection);
static xcb_screen_t* XCBScreenOfDisplay(xcb_connection_t* connection, int screen_nbr);
private:
static unsigned int s_moduleReferenceCounter;
};
}
#endif // NAZARA_X11DISPLAY_HPP

View File

@ -1,136 +0,0 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Platform/X11/IconImpl.hpp>
#include <Nazara/Core/CallOnExit.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Utility/Image.hpp>
#include <Nazara/Platform/X11/Display.hpp>
#include <Nazara/Platform/Debug.hpp>
namespace Nz
{
IconImpl::IconImpl()
{
ScopedXCBConnection connection;
m_iconPixmap.Connect(connection);
m_maskPixmap.Connect(connection);
}
bool IconImpl::Create(const Image& icon)
{
Image iconImage(icon); // Vive le COW
if (!iconImage.Convert(Nz::PixelFormatType_BGRA8))
{
NazaraError("Failed to convert icon to BGRA8");
return false;
}
auto width = iconImage.GetWidth();
auto height = iconImage.GetHeight();
ScopedXCBConnection connection;
xcb_screen_t* screen = X11::XCBDefaultScreen(connection);
if (!m_iconPixmap.Create(
screen->root_depth,
screen->root,
width,
height))
{
NazaraError("Failed to create icon pixmap");
return false;
}
CallOnExit onExit([this](){
Destroy();
});
XCBGContext iconGC(connection);
if (!iconGC.Create(
m_iconPixmap,
0,
nullptr))
{
NazaraError("Failed to create icon gc");
return false;
}
if (!X11::CheckCookie(
connection,
xcb_put_image(
connection,
XCB_IMAGE_FORMAT_Z_PIXMAP,
m_iconPixmap,
iconGC,
width,
height,
0,
0,
0,
screen->root_depth,
width * height * 4,
iconImage.GetConstPixels()
)))
{
NazaraError("Failed to put image for icon");
return false;
}
// Create the mask pixmap (must have 1 bit depth)
std::size_t pitch = (width + 7) / 8;
static std::vector<UInt8> maskPixels(pitch * height, 0);
for (std::size_t j = 0; j < height; ++j)
{
for (std::size_t i = 0; i < pitch; ++i)
{
for (std::size_t k = 0; k < 8; ++k)
{
if (i * 8 + k < width)
{
UInt8 opacity = (iconImage.GetConstPixels()[(i * 8 + k + j * width) * 4 + 3] > 0) ? 1 : 0;
maskPixels[i + j * pitch] |= (opacity << k);
}
}
}
}
if (!m_maskPixmap.CreatePixmapFromBitmapData(
X11::XCBDefaultRootWindow(connection),
reinterpret_cast<uint8_t*>(&maskPixels[0]),
width,
height,
1,
0,
1,
nullptr))
{
NazaraError("Failed to create mask pixmap for icon");
return false;
}
onExit.Reset();
return true;
}
void IconImpl::Destroy()
{
m_iconPixmap.Destroy();
m_maskPixmap.Destroy();
}
xcb_pixmap_t IconImpl::GetIcon()
{
return m_iconPixmap;
}
xcb_pixmap_t IconImpl::GetMask()
{
return m_maskPixmap;
}
}

View File

@ -1,34 +0,0 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_ICONIMPL_HPP
#define NAZARA_ICONIMPL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Platform/X11/ScopedXCB.hpp>
namespace Nz
{
class Image;
class IconImpl
{
public:
IconImpl();
bool Create(const Image& image);
void Destroy();
xcb_pixmap_t GetIcon();
xcb_pixmap_t GetMask();
private:
XCBPixmap m_iconPixmap;
XCBPixmap m_maskPixmap;
};
}
#endif // NAZARA_ICONIMPL_HPP

View File

@ -1,390 +0,0 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Platform/X11/InputImpl.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Platform/Window.hpp>
#include <Nazara/Platform/X11/Display.hpp>
#include <Nazara/Platform/X11/ScopedXCB.hpp>
#include <X11/keysym.h>
#include <X11/XF86keysym.h>
#include <X11/Xlib.h>
#include <xcb/xcb_keysyms.h>
#include <Nazara/Platform/Debug.hpp>
namespace Nz
{
namespace
{
KeySym GetKeySym(Keyboard::Key key)
{
// X11 keysym correspondant
KeySym keysym = 0;
switch (key)
{
// Lettres
case Keyboard::A: keysym = XK_a; break;
case Keyboard::B: keysym = XK_b; break;
case Keyboard::C: keysym = XK_c; break;
case Keyboard::D: keysym = XK_d; break;
case Keyboard::E: keysym = XK_e; break;
case Keyboard::F: keysym = XK_f; break;
case Keyboard::G: keysym = XK_g; break;
case Keyboard::H: keysym = XK_h; break;
case Keyboard::I: keysym = XK_i; break;
case Keyboard::J: keysym = XK_j; break;
case Keyboard::K: keysym = XK_k; break;
case Keyboard::L: keysym = XK_l; break;
case Keyboard::M: keysym = XK_m; break;
case Keyboard::N: keysym = XK_n; break;
case Keyboard::O: keysym = XK_o; break;
case Keyboard::P: keysym = XK_p; break;
case Keyboard::Q: keysym = XK_q; break;
case Keyboard::R: keysym = XK_r; break;
case Keyboard::S: keysym = XK_s; break;
case Keyboard::T: keysym = XK_t; break;
case Keyboard::U: keysym = XK_u; break;
case Keyboard::V: keysym = XK_v; break;
case Keyboard::W: keysym = XK_w; break;
case Keyboard::X: keysym = XK_x; break;
case Keyboard::Y: keysym = XK_y; break;
case Keyboard::Z: keysym = XK_z; break;
// Touches de fonction
case Keyboard::F1: keysym = XK_F1; break;
case Keyboard::F2: keysym = XK_F2; break;
case Keyboard::F3: keysym = XK_F3; break;
case Keyboard::F4: keysym = XK_F4; break;
case Keyboard::F5: keysym = XK_F5; break;
case Keyboard::F6: keysym = XK_F6; break;
case Keyboard::F7: keysym = XK_F7; break;
case Keyboard::F8: keysym = XK_F8; break;
case Keyboard::F9: keysym = XK_F9; break;
case Keyboard::F10: keysym = XK_F10; break;
case Keyboard::F11: keysym = XK_F11; break;
case Keyboard::F12: keysym = XK_F12; break;
case Keyboard::F13: keysym = XK_F13; break;
case Keyboard::F14: keysym = XK_F14; break;
case Keyboard::F15: keysym = XK_F15; break;
// Flèches directionnelles
case Keyboard::Down: keysym = XK_Down; break;
case Keyboard::Left: keysym = XK_Left; break;
case Keyboard::Right: keysym = XK_Right; break;
case Keyboard::Up: keysym = XK_Up; break;
// Pavé numérique
case Keyboard::Add: keysym = XK_KP_Add; break;
case Keyboard::Decimal: keysym = XK_KP_Decimal; break;
case Keyboard::Divide: keysym = XK_KP_Divide; break;
case Keyboard::Multiply: keysym = XK_KP_Multiply; break;
case Keyboard::Numpad0: keysym = XK_KP_0; break;
case Keyboard::Numpad1: keysym = XK_KP_1; break;
case Keyboard::Numpad2: keysym = XK_KP_2; break;
case Keyboard::Numpad3: keysym = XK_KP_3; break;
case Keyboard::Numpad4: keysym = XK_KP_4; break;
case Keyboard::Numpad5: keysym = XK_KP_5; break;
case Keyboard::Numpad6: keysym = XK_KP_6; break;
case Keyboard::Numpad7: keysym = XK_KP_7; break;
case Keyboard::Numpad8: keysym = XK_KP_8; break;
case Keyboard::Numpad9: keysym = XK_KP_9; break;
case Keyboard::Subtract: keysym = XK_KP_Subtract; break;
// Divers
case Keyboard::Backslash: keysym = XK_backslash; break;
case Keyboard::Backspace: keysym = XK_BackSpace; break;
case Keyboard::Clear: keysym = XK_Clear; break;
case Keyboard::Comma: keysym = XK_comma; break;
case Keyboard::Dash: keysym = XK_minus; break;
case Keyboard::Delete: keysym = XK_Delete; break;
case Keyboard::End: keysym = XK_End; break;
case Keyboard::Equal: keysym = XK_equal; break;
case Keyboard::Escape: keysym = XK_Escape; break;
case Keyboard::Home: keysym = XK_Home; break;
case Keyboard::Insert: keysym = XK_Insert; break;
case Keyboard::LAlt: keysym = XK_Alt_L; break;
case Keyboard::LBracket: keysym = XK_bracketleft; break;
case Keyboard::LControl: keysym = XK_Control_L; break;
case Keyboard::LShift: keysym = XK_Shift_L; break;
case Keyboard::LSystem: keysym = XK_Super_L; break;
case Keyboard::Num0: keysym = XK_0; break;
case Keyboard::Num1: keysym = XK_1; break;
case Keyboard::Num2: keysym = XK_2; break;
case Keyboard::Num3: keysym = XK_3; break;
case Keyboard::Num4: keysym = XK_4; break;
case Keyboard::Num5: keysym = XK_5; break;
case Keyboard::Num6: keysym = XK_6; break;
case Keyboard::Num7: keysym = XK_7; break;
case Keyboard::Num8: keysym = XK_8; break;
case Keyboard::Num9: keysym = XK_9; break;
case Keyboard::PageDown: keysym = XK_Page_Down; break;
case Keyboard::PageUp: keysym = XK_Page_Up; break;
case Keyboard::Pause: keysym = XK_Pause; break;
case Keyboard::Period: keysym = XK_period; break;
case Keyboard::Print: keysym = XK_Print; break;
case Keyboard::PrintScreen: keysym = XK_Sys_Req; break;
case Keyboard::Quote: keysym = XK_quotedbl; break;
case Keyboard::RAlt: keysym = XK_Alt_R; break;
case Keyboard::RBracket: keysym = XK_bracketright; break;
case Keyboard::RControl: keysym = XK_Control_R; break;
case Keyboard::Return: keysym = XK_Return; break;
case Keyboard::RShift: keysym = XK_Shift_R; break;
case Keyboard::RSystem: keysym = XK_Super_R; break;
case Keyboard::Semicolon: keysym = XK_semicolon; break;
case Keyboard::Slash: keysym = XK_slash; break;
case Keyboard::Space: keysym = XK_space; break;
case Keyboard::Tab: keysym = XK_Tab; break;
case Keyboard::Tilde: keysym = XK_grave; break;
// Touches navigateur
case Keyboard::Browser_Back: keysym = XF86XK_Back; break;
case Keyboard::Browser_Favorites: keysym = XF86XK_Favorites; break;
case Keyboard::Browser_Forward: keysym = XF86XK_Forward; break;
case Keyboard::Browser_Home: keysym = XF86XK_HomePage; break;
case Keyboard::Browser_Refresh: keysym = XF86XK_Refresh; break;
case Keyboard::Browser_Search: keysym = XF86XK_Search; break;
case Keyboard::Browser_Stop: keysym = XF86XK_Stop; break;
// Touches de contrôle
case Keyboard::Media_Next: keysym = XF86XK_AudioNext; break;
case Keyboard::Media_Play: keysym = XF86XK_AudioPlay; break;
case Keyboard::Media_Previous: keysym = XF86XK_AudioPrev; break;
case Keyboard::Media_Stop: keysym = XF86XK_AudioStop; break;
// Touches de contrôle du volume
case Keyboard::Volume_Down: keysym = XF86XK_AudioLowerVolume; break;
case Keyboard::Volume_Mute: keysym = XF86XK_AudioMute; break;
case Keyboard::Volume_Up: keysym = XF86XK_AudioRaiseVolume; break;
// Touches à verrouillage
case Keyboard::CapsLock: keysym = XK_Caps_Lock; break;
case Keyboard::NumLock: keysym = XK_Num_Lock; break;
case Keyboard::ScrollLock: keysym = XK_Scroll_Lock; break;
default: break;
}
// Sanity checks
if (key < 0 || key >= Keyboard::Count || keysym == 0)
NazaraWarning("Key " + String::Number(key) + " is not handled in Keyboard");
return keysym;
}
}
String EventImpl::GetKeyName(Keyboard::Key key)
{
KeySym keySym = GetKeySym(key);
// XKeysymToString returns a static area.
return XKeysymToString(keySym);
}
Vector2i EventImpl::GetMousePosition()
{
ScopedXCBConnection connection;
ScopedXCB<xcb_generic_error_t> error(nullptr);
ScopedXCB<xcb_query_pointer_reply_t> pointer(
xcb_query_pointer_reply(
connection,
xcb_query_pointer(
connection,
X11::XCBDefaultRootWindow(connection)
),
&error
)
);
if (error)
{
NazaraError("Failed to query pointer");
return Vector2i(-1, -1);
}
return Vector2i(pointer->root_x, pointer->root_y);
}
Vector2i EventImpl::GetMousePosition(const Window& relativeTo)
{
WindowHandle handle = relativeTo.GetHandle();
if (handle)
{
// Open a connection with the X server
ScopedXCBConnection connection;
ScopedXCB<xcb_generic_error_t> error(nullptr);
ScopedXCB<xcb_query_pointer_reply_t> pointer(
xcb_query_pointer_reply(
connection,
xcb_query_pointer(
connection,
handle
),
&error
)
);
if (error)
{
NazaraError("Failed to query pointer");
return Vector2i(-1, -1);
}
return Vector2i(pointer->win_x, pointer->win_y);
}
else
{
NazaraError("No window handle");
return Vector2i(-1, -1);
}
}
bool EventImpl::IsKeyPressed(Keyboard::Key key)
{
ScopedXCBConnection connection;
xcb_keysym_t keySym = GetKeySym(key);
xcb_keycode_t realKeyCode = XCB_NO_SYMBOL;
xcb_key_symbols_t* keySymbols = X11::XCBKeySymbolsAlloc(connection);
if (!keySymbols)
{
NazaraError("Failed to alloc key symbols");
return false;
}
ScopedXCB<xcb_keycode_t> keyCode = xcb_key_symbols_get_keycode(keySymbols, keySym);
if (!keyCode)
{
NazaraError("Failed to get key code");
return false;
}
// One keysym is associated with multiple key codes, we have to find the matching one ...
int i = 0;
while (keyCode.get()[i] != XCB_NO_SYMBOL)
{
xcb_keycode_t toTry = keyCode.get()[i];
if (keySym == xcb_key_symbols_get_keysym(keySymbols, toTry, 0))
{
realKeyCode = toTry;
break;
}
++i;
}
X11::XCBKeySymbolsFree(keySymbols);
ScopedXCB<xcb_generic_error_t> error(nullptr);
// Get the whole keyboard state
ScopedXCB<xcb_query_keymap_reply_t> keymap(
xcb_query_keymap_reply(
connection,
xcb_query_keymap(connection),
&error
)
);
if (error)
{
NazaraError("Failed to query keymap");
return false;
}
// Check our keycode
return (keymap->keys[realKeyCode / 8] & (1 << (realKeyCode % 8))) != 0;
}
bool EventImpl::IsMouseButtonPressed(Mouse::Button button)
{
ScopedXCBConnection connection;
ScopedXCB<xcb_generic_error_t> error(nullptr);
// Get pointer mask
ScopedXCB<xcb_query_pointer_reply_t> pointer(
xcb_query_pointer_reply(
connection,
xcb_query_pointer(
connection,
X11::XCBDefaultRootWindow(connection)
),
&error
)
);
if (error)
{
NazaraError("Failed to query pointer");
return false;
}
uint16_t buttons = pointer->mask;
switch (button)
{
case Mouse::Left: return buttons & XCB_BUTTON_MASK_1;
case Mouse::Right: return buttons & XCB_BUTTON_MASK_3;
case Mouse::Middle: return buttons & XCB_BUTTON_MASK_2;
case Mouse::XButton1: return false; // not supported by X
case Mouse::XButton2: return false; // not supported by X
}
NazaraError("Mouse button not supported.");
return false;
}
void EventImpl::SetMousePosition(int x, int y)
{
ScopedXCBConnection connection;
xcb_window_t root = X11::XCBDefaultRootWindow(connection);
if (!X11::CheckCookie(
connection,
xcb_warp_pointer(
connection,
None, // Source window
root, // Destination window
0, 0, // Source position
0, 0, // Source size
x, y // Destination position
))
)
NazaraError("Failed to set mouse position");
xcb_flush(connection);
}
void EventImpl::SetMousePosition(int x, int y, const Window& relativeTo)
{
ScopedXCBConnection connection;
WindowHandle handle = relativeTo.GetHandle();
if (handle)
{
if (!X11::CheckCookie(
connection,
xcb_warp_pointer(
connection,
None, // Source window
handle, // Destination window
0, 0, // Source position
0, 0, // Source size
x, y // Destination position
))
)
NazaraError("Failed to set mouse position relative to window");
xcb_flush(connection);
}
else
NazaraError("No window handle");
}
}

View File

@ -1,31 +0,0 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_INPUTIMPL_HPP
#define NAZARA_INPUTIMPL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Platform/Keyboard.hpp>
#include <Nazara/Platform/Mouse.hpp>
namespace Nz
{
class EventImpl
{
public:
static String GetKeyName(Keyboard::Key key);
static Vector2i GetMousePosition();
static Vector2i GetMousePosition(const Window& relativeTo);
static bool IsKeyPressed(Keyboard::Key key);
static bool IsMouseButtonPressed(Mouse::Button button);
static void SetMousePosition(int x, int y);
static void SetMousePosition(int x, int y, const Window& relativeTo);
};
}
#endif // NAZARA_INPUTIMPL_HPP

View File

@ -1,199 +0,0 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Platform/X11/ScopedXCB.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Platform/X11/Display.hpp>
#include <xcb/xcb_image.h>
#include <Nazara/Platform/Debug.hpp>
namespace Nz
{
/***********************************************
ScopedXCBConnection
***********************************************/
ScopedXCBConnection::ScopedXCBConnection() :
m_connection(nullptr)
{
m_connection = X11::OpenConnection();
}
ScopedXCBConnection::~ScopedXCBConnection()
{
X11::CloseConnection(m_connection);
}
ScopedXCBConnection::operator xcb_connection_t*() const
{
return m_connection;
}
/***********************************************
ScopedXCBEWMHConnection
***********************************************/
ScopedXCBEWMHConnection::ScopedXCBEWMHConnection(xcb_connection_t* connection) :
m_ewmhConnection(nullptr)
{
m_ewmhConnection = X11::OpenEWMHConnection(connection);
}
ScopedXCBEWMHConnection::~ScopedXCBEWMHConnection()
{
X11::CloseEWMHConnection(m_ewmhConnection);
}
xcb_ewmh_connection_t* ScopedXCBEWMHConnection::operator ->() const
{
return m_ewmhConnection;
}
ScopedXCBEWMHConnection::operator xcb_ewmh_connection_t*() const
{
return m_ewmhConnection;
}
/***********************************************
XCBGContext
***********************************************/
XCBGContext::XCBGContext(xcb_connection_t* connection) :
m_connection(connection),
m_gcontext(XCB_NONE)
{
NazaraAssert(connection, "Connection must have been established");
}
XCBGContext::~XCBGContext()
{
Destroy();
}
bool XCBGContext::Create(xcb_drawable_t drawable, uint32_t value_mask, const uint32_t* value_list)
{
NazaraAssert(m_gcontext == XCB_NONE, "Context must have been destroyed before or just created");
m_gcontext = xcb_generate_id(m_connection);
return X11::CheckCookie(
m_connection,
xcb_create_gc(
m_connection,
m_gcontext,
drawable,
value_mask,
value_list
));
}
void XCBGContext::Destroy()
{
if (m_gcontext == XCB_NONE)
return;
if (!X11::CheckCookie(
m_connection,
xcb_free_gc(
m_connection,
m_gcontext
))
)
NazaraError("Failed to free gcontext");
m_gcontext = XCB_NONE;
}
XCBGContext::operator xcb_gcontext_t() const
{
return m_gcontext;
}
/***********************************************
XCBPixmap
***********************************************/
XCBPixmap::XCBPixmap() :
m_connection(nullptr),
m_pixmap(XCB_NONE)
{
}
XCBPixmap::XCBPixmap(xcb_connection_t* connection) :
m_connection(connection),
m_pixmap(XCB_NONE)
{
}
XCBPixmap::~XCBPixmap()
{
Destroy();
}
void XCBPixmap::Connect(xcb_connection_t* connection)
{
NazaraAssert(connection && !m_connection, "Connection must be established");
m_connection = connection;
}
bool XCBPixmap::Create(uint8_t depth, xcb_drawable_t drawable, uint16_t width, uint16_t height)
{
NazaraAssert(m_pixmap == XCB_NONE, "Pixmap must have been destroyed before or just created");
m_pixmap = xcb_generate_id(m_connection);
return X11::CheckCookie(
m_connection,
xcb_create_pixmap(
m_connection,
depth,
m_pixmap,
drawable,
width,
height
));
}
bool XCBPixmap::CreatePixmapFromBitmapData(xcb_drawable_t drawable, uint8_t* data, uint32_t width, uint32_t height, uint32_t depth, uint32_t fg, uint32_t bg, xcb_gcontext_t* gcp)
{
NazaraAssert(m_pixmap == XCB_NONE, "Pixmap must have been destroyed before or just created");
m_pixmap = xcb_create_pixmap_from_bitmap_data(
m_connection,
drawable,
data,
width,
height,
depth,
fg,
bg,
gcp
);
return m_pixmap != XCB_NONE;
}
void XCBPixmap::Destroy()
{
if (m_pixmap == XCB_NONE)
return;
if (!X11::CheckCookie(
m_connection,
xcb_free_pixmap(
m_connection,
m_pixmap
))
)
NazaraError("Failed to free pixmap");
m_pixmap = XCB_NONE;
}
XCBPixmap::operator xcb_pixmap_t() const
{
return m_pixmap;
}
}

View File

@ -1,101 +0,0 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_SCOPEDXCB_HPP
#define NAZARA_SCOPEDXCB_HPP
#include <Nazara/Prerequisites.hpp>
#include <xcb/xcb.h>
#include <xcb/xcb_ewmh.h>
#include <cstdlib>
namespace Nz
{
class ScopedXCBConnection
{
public:
ScopedXCBConnection();
~ScopedXCBConnection();
operator xcb_connection_t*() const;
private:
xcb_connection_t* m_connection;
};
class ScopedXCBEWMHConnection
{
public:
ScopedXCBEWMHConnection(xcb_connection_t* connection);
~ScopedXCBEWMHConnection();
xcb_ewmh_connection_t* operator ->() const;
operator xcb_ewmh_connection_t*() const;
private:
xcb_ewmh_connection_t* m_ewmhConnection;
};
template <typename T>
class ScopedXCB
{
public:
ScopedXCB(T* pointer);
~ScopedXCB();
T* operator ->() const;
T** operator &();
operator bool() const;
T* get() const;
private:
T* m_pointer;
};
class XCBGContext
{
public:
XCBGContext(xcb_connection_t* connection);
~XCBGContext();
bool Create(xcb_drawable_t drawable, uint32_t value_mask, const uint32_t* value_list);
void Destroy();
operator xcb_gcontext_t() const;
private:
xcb_connection_t* m_connection;
xcb_gcontext_t m_gcontext;
};
class XCBPixmap
{
public:
XCBPixmap();
XCBPixmap(xcb_connection_t* connection);
~XCBPixmap();
void Connect(xcb_connection_t* connection);
bool Create(uint8_t depth, xcb_drawable_t drawable, uint16_t width, uint16_t height);
bool CreatePixmapFromBitmapData(xcb_drawable_t drawable, uint8_t* data, uint32_t width, uint32_t height, uint32_t depth, uint32_t fg, uint32_t bg, xcb_gcontext_t* gcp);
void Destroy();
operator xcb_pixmap_t() const;
private:
xcb_connection_t* m_connection;
xcb_pixmap_t m_pixmap;
};
}
#include <Nazara/Platform/X11/ScopedXCB.inl>
#endif // NAZARA_SCOPEDXCB_HPP

View File

@ -1,46 +0,0 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Platform/Debug.hpp>
namespace Nz
{
template <typename T>
ScopedXCB<T>::ScopedXCB(T* pointer) :
m_pointer(pointer)
{
}
template <typename T>
ScopedXCB<T>::~ScopedXCB()
{
std::free(m_pointer);
}
template <typename T>
T* ScopedXCB<T>::operator ->() const
{
return m_pointer;
}
template <typename T>
T** ScopedXCB<T>::operator &()
{
return &m_pointer;
}
template <typename T>
ScopedXCB<T>::operator bool() const
{
return m_pointer != nullptr;
}
template <typename T>
T* ScopedXCB<T>::get() const
{
return m_pointer;
}
}
#include <Nazara/Platform/DebugOff.hpp>

View File

@ -1,170 +0,0 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Platform/X11/VideoModeImpl.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Platform/VideoMode.hpp>
#include <Nazara/Platform/X11/Display.hpp>
#include <Nazara/Platform/X11/ScopedXCB.hpp>
#include <xcb/randr.h>
#include <algorithm>
#include <Nazara/Platform/Debug.hpp>
namespace Nz
{
VideoMode VideoModeImpl::GetDesktopMode()
{
VideoMode desktopMode;
ScopedXCBConnection connection;
// Retrieve the default screen
xcb_screen_t* screen = X11::XCBDefaultScreen(connection);
ScopedXCB<xcb_generic_error_t> error(nullptr);
// Check if the RandR extension is present
const xcb_query_extension_reply_t* randrExt = xcb_get_extension_data(connection, &xcb_randr_id);
if (!randrExt || !randrExt->present)
{
// Randr extension is not supported: we cannot get the video modes
NazaraError("Failed to use the RandR extension while trying to get the desktop video mode");
return desktopMode;
}
// Load RandR and check its version
ScopedXCB<xcb_randr_query_version_reply_t> randrVersion(xcb_randr_query_version_reply(
connection,
xcb_randr_query_version(
connection,
1,
1
),
&error
));
if (error)
{
NazaraError("Failed to load the RandR extension while trying to get the desktop video mode");
return desktopMode;
}
// Get the current configuration
ScopedXCB<xcb_randr_get_screen_info_reply_t> config(xcb_randr_get_screen_info_reply(
connection,
xcb_randr_get_screen_info(
connection,
screen->root
),
&error
));
if (error)
{
// Failed to get the screen configuration
NazaraError("Failed to retrieve the screen configuration while trying to get the desktop video mode");
return desktopMode;
}
// Get the current video mode
xcb_randr_mode_t currentMode = config->sizeID;
// Get the available screen sizes
int nbSizes = xcb_randr_get_screen_info_sizes_length(config.get());
xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(config.get());
if (sizes && (nbSizes > 0))
{
desktopMode = VideoMode(sizes[currentMode].width, sizes[currentMode].height, screen->root_depth);
if (config->rotation == XCB_RANDR_ROTATION_ROTATE_90 ||
config->rotation == XCB_RANDR_ROTATION_ROTATE_270)
std::swap(desktopMode.width, desktopMode.height);
}
else
{
NazaraError("Failed to retrieve any screen sizes while trying to get the desktop video mode");
}
return desktopMode;
}
void VideoModeImpl::GetFullscreenModes(std::vector<VideoMode>& modes)
{
ScopedXCBConnection connection;
// Retrieve the default screen
xcb_screen_t* screen = X11::XCBDefaultScreen(connection);
ScopedXCB<xcb_generic_error_t> error(nullptr);
const xcb_query_extension_reply_t* randrExt = xcb_get_extension_data(connection, &xcb_randr_id);
if (!randrExt || !randrExt->present)
{
// Randr extension is not supported: we cannot get the video modes
NazaraError("Failed to use the RandR extension while trying to get the supported video modes");
return;
}
// Load RandR and check its version
ScopedXCB<xcb_randr_query_version_reply_t> randrVersion(xcb_randr_query_version_reply(
connection,
xcb_randr_query_version(
connection,
1,
1
),
&error
));
if (error)
{
NazaraError("Failed to load the RandR extension while trying to get the supported video modes");
return;
}
// Get the current configuration
ScopedXCB<xcb_randr_get_screen_info_reply_t> config(xcb_randr_get_screen_info_reply(
connection,
xcb_randr_get_screen_info(
connection,
screen->root
),
&error
));
if (error)
{
// Failed to get the screen configuration
NazaraError("Failed to retrieve the screen configuration while trying to get the supported video modes");
return;
}
// Get the available screen sizes
xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(config.get());
if (sizes && (config->nSizes > 0))
{
// Get the list of supported depths
xcb_depth_iterator_t iter = xcb_screen_allowed_depths_iterator(screen);
// Combine depths and sizes to fill the array of supported modes
for (; iter.rem; xcb_depth_next(&iter))
{
for (int j = 0; j < config->nSizes; ++j)
{
// Convert to VideoMode
VideoMode mode(sizes[j].width, sizes[j].height, iter.data->depth);
if (config->rotation == XCB_RANDR_ROTATION_ROTATE_90 ||
config->rotation == XCB_RANDR_ROTATION_ROTATE_270)
std::swap(mode.width, mode.height);
// Add it only if it is not already in the array
if (std::find(modes.begin(), modes.end(), mode) == modes.end())
modes.push_back(mode);
}
}
}
}
}

View File

@ -1,23 +0,0 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_VIDEOMODEIMPL_HPP
#define NAZARA_VIDEOMODEIMPL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Platform/VideoMode.hpp>
namespace Nz
{
class VideoModeImpl
{
public:
static VideoMode GetDesktopMode();
static void GetFullscreenModes(std::vector<VideoMode>& modes);
};
}
#endif // NNAZARA_VIDEOMODEIMPL_HPP

File diff suppressed because it is too large Load Diff

View File

@ -1,127 +0,0 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Platform module"
// For conditions of distribution and use, see copyright notice in Config.hpp
// Interface inspirée de la SFML par Laurent Gomila
#pragma once
#ifndef NAZARA_WINDOWIMPL_HPP
#define NAZARA_WINDOWIMPL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Platform/Enums.hpp>
#include <Nazara/Platform/Keyboard.hpp>
#include <Nazara/Platform/WindowHandle.hpp>
#include <condition_variable>
#include <mutex>
#include <thread>
#include <xcb/randr.h>
#include <xcb/xcb_icccm.h>
namespace Nz
{
class Cursor;
class Icon;
class VideoMode;
class Window;
class WindowImpl
{
public:
WindowImpl(Window* parent);
WindowImpl(const WindowImpl&) = delete;
WindowImpl(WindowImpl&&) = delete; ///TODO?
~WindowImpl();
bool Create(const VideoMode& mode, const String& title, WindowStyleFlags style);
bool Create(WindowHandle handle);
void Destroy();
void EnableKeyRepeat(bool enable);
void EnableSmoothScrolling(bool enable);
WindowHandle GetHandle() const;
unsigned int GetHeight() const;
Vector2i GetPosition() const;
Vector2ui GetSize() const;
WindowStyleFlags GetStyle() const;
String GetTitle() const;
unsigned int GetWidth() const;
bool HasFocus() const;
void IgnoreNextMouseEvent(int mouseX, int mouseY);
bool IsMinimized() const;
bool IsVisible() const;
void RefreshCursor();
void ProcessEvents(bool block);
void SetCursor(const Cursor& cursor);
void SetEventListener(bool listener);
void SetFocus();
void SetIcon(const Icon& icon);
void SetMaximumSize(int width, int height);
void SetMinimumSize(int width, int height);
void SetPosition(int x, int y);
void SetSize(unsigned int width, unsigned int height);
void SetStayOnTop(bool stayOnTop);
void SetTitle(const String& title);
void SetVisible(bool visible);
WindowImpl& operator=(const WindowImpl&) = delete;
WindowImpl& operator=(WindowImpl&&) = delete; ///TODO?
static bool Initialize();
static void Uninitialize();
private:
void CleanUp();
xcb_keysym_t ConvertKeyCodeToKeySym(xcb_keycode_t keycode, uint16_t state);
Keyboard::Key ConvertVirtualKey(xcb_keysym_t symbol);
void CommonInitialize();
char32_t GetRepresentation(xcb_keysym_t keysym) const;
void ProcessEvent(xcb_generic_event_t* windowEvent);
void ResetVideoMode();
void SetMotifHints();
void SetVideoMode(const VideoMode& mode);
void SwitchToFullscreen();
bool UpdateNormalHints();
void UpdateEventQueue(xcb_generic_event_t* event);
static void WindowThread(WindowImpl* window, std::mutex& mutex, std::condition_variable& condition);
xcb_window_t m_window;
xcb_screen_t* m_screen;
xcb_randr_get_screen_info_reply_t m_oldVideoMode;
xcb_size_hints_t m_size_hints;
std::thread m_thread;
WindowStyleFlags m_style;
Window* m_parent;
bool m_eventListener;
bool m_ownsWindow;
bool m_smoothScrolling;
bool m_threadActive;
Vector2i m_mousePos;
bool m_keyRepeat;
struct
{
xcb_generic_event_t* curr = nullptr;
xcb_generic_event_t* next = nullptr;
} m_eventQueue;
};
}
#endif // NAZARA_WINDOWIMPL_HPP

View File

@ -0,0 +1,302 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
// Code inspiré de NeHe (Lesson1) et de la SFML par Laurent Gomila
#include <Nazara/Renderer/GLX/ContextImpl.hpp>
#include <Nazara/Core/CallOnExit.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/Debug.hpp>
using namespace GLX;
namespace Nz
{
namespace
{
Display* m_display;
int m_sharedDisplay = 0;
bool ctxErrorOccurred = false;
int ctxErrorHandler( Display* /*dpy*/, XErrorEvent* /*ev*/ )
{
ctxErrorOccurred = true;
return 0;
}
}
ContextImpl::ContextImpl() :
m_colormap(0),
m_context(0),
m_window(0),
m_ownsWindow(false)
{
if (m_sharedDisplay == 0)
m_display = XOpenDisplay(nullptr);
++m_sharedDisplay;
}
ContextImpl::~ContextImpl()
{
Destroy();
if (--m_sharedDisplay == 0)
{
XCloseDisplay(m_display);
m_display = nullptr;
}
}
bool ContextImpl::Activate() const
{
return glXMakeCurrent(m_display, m_window, m_context) == true;
}
bool ContextImpl::Create(ContextParameters& parameters)
{
// En cas d'exception, la ressource sera quand même libérée
CallOnExit onExit([this] ()
{
Destroy();
});
// Get a matching FB config
static int visual_attribs[] =
{
GLX_X_RENDERABLE, True,
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
GLX_BUFFER_SIZE, parameters.bitsPerPixel,
GLX_ALPHA_SIZE, (parameters.bitsPerPixel == 32) ? 8 : 0,
GLX_DEPTH_SIZE, parameters.depthBits,
GLX_STENCIL_SIZE, parameters.stencilBits,
GLX_DOUBLEBUFFER, True,
GLX_SAMPLE_BUFFERS, (parameters.antialiasingLevel > 0) ? True : False,
GLX_SAMPLES, parameters.antialiasingLevel,
None
};
int glx_major = 0;
int glx_minor = 0;
// FBConfigs were added in GLX version 1.3.
if (!glXQueryVersion(m_display, &glx_major, &glx_minor) || ((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1))
{
NazaraError("Invalid GLX version, version > 1.3 is required.");
return false;
}
int fbcount;
GLXFBConfig* fbc = glXChooseFBConfig(m_display, XDefaultScreen(m_display), visual_attribs, &fbcount);
if (!fbc)
{
NazaraError("Failed to retrieve a framebuffer config");
return false;
}
// Pick the FB config/visual with the most samples per pixel
int best_fbc = -1;
int worst_fbc = -1;
int best_num_samp = -1;
int worst_num_samp = 999;
for (int i = 0; i < fbcount; ++i)
{
XVisualInfo* vi = glXGetVisualFromFBConfig(m_display, fbc[i]);
if (vi)
{
int samp_buf = 0, samples = 0;
glXGetFBConfigAttrib(m_display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf);
glXGetFBConfigAttrib(m_display, fbc[i], GLX_SAMPLES , &samples );
if ((best_fbc < 0) || (samp_buf && (samples > best_num_samp)))
{
best_fbc = i;
best_num_samp = samples;
}
if ((worst_fbc < 0) || !samp_buf || (samples < worst_num_samp))
{
worst_fbc = i;
worst_num_samp = samples;
}
}
XFree(vi);
}
GLXFBConfig bestFbc = fbc[best_fbc];
// Be sure to free the FBConfig list allocated by glXChooseFBConfig()
XFree(fbc);
// Get a visual
XVisualInfo* vi = glXGetVisualFromFBConfig(m_display, bestFbc);
if (!vi)
{
NazaraError("Failed to get best VisualInfo");
return false;
}
// If context is shared by multiple windows
if (parameters.window)
{
NazaraAssert(parameters.window.type == WindowManager::X11, "Cannot create a context for a non-x11 window");
m_window = static_cast<GLX::Window>(parameters.window.x11.window);
m_ownsWindow = false;
}
else
{
XSetWindowAttributes swa;
swa.colormap = m_colormap = XCreateColormap(
m_display,
XRootWindow(
m_display,
vi->screen),
vi->visual,
AllocNone
);
swa.background_pixmap = None;
swa.border_pixel = 0;
swa.event_mask = StructureNotifyMask;
if (!m_colormap)
{
NazaraError("Failed to create colormap for context");
return false;
}
m_window = XCreateWindow(
m_display,
XRootWindow(
m_display,
vi->screen),
0, 0, // X, Y
1, 1, // W H
0,
vi->depth,
InputOutput,
vi->visual,
CWBorderPixel | CWColormap | CWEventMask,
&swa
);
m_ownsWindow = true;
}
if (!m_window)
{
NazaraError("Failed to create window");
return false;
}
// Done with the visual info data
XFree(vi);
// Install an X error handler so the application won't exit if GL 3.0
// context allocation fails.
//
// Note this error handler is global. All display connections in all threads
// of a process use the same error handler, so be sure to guard against other
// threads issuing X commands while this code is running.
ctxErrorOccurred = false;
int (*oldHandler)(Display*, XErrorEvent*) =
XSetErrorHandler(&ctxErrorHandler);
// Check for the GLX_ARB_create_context extension string and the function.
// If either is not present, use GLX 1.3 context creation method.
if (!glXCreateContextAttribs)
{
NazaraWarning("glXCreateContextAttribs() not found. Using old-style GLX context");
m_context = glXCreateNewContext(m_display, bestFbc, GLX_RGBA_TYPE, parameters.shared ? parameters.shareContext->m_impl->m_context : 0, True);
}
// If it does, try to get a GL 3.0 context!
else
{
int profile = parameters.compatibilityProfile ? GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
int debug = parameters.debugMode ? GLX_CONTEXT_DEBUG_BIT_ARB : 0;
int major = 3;//parameters.majorVersion;
int minor = 3;//parameters.minorVersion;
int context_attribs[] =
{
GLX_CONTEXT_MAJOR_VERSION_ARB, major,
GLX_CONTEXT_MINOR_VERSION_ARB, minor,
GLX_CONTEXT_PROFILE_MASK_ARB, profile,
GLX_CONTEXT_FLAGS_ARB, debug,
None, None
};
m_context = glXCreateContextAttribs(
m_display,
bestFbc,
parameters.shared ? parameters.shareContext->m_impl->m_context : 0,
True,
context_attribs
);
}
// Sync to ensure any errors generated are processed.
XSync(m_display, False);
XSetErrorHandler(oldHandler);
if (ctxErrorOccurred || !m_context)
{
NazaraError("Failed to create context, check the version");
return false;
}
onExit.Reset();
return true;
}
void ContextImpl::Destroy()
{
// Destroy the context
if (m_context)
{
if (glXGetCurrentContext() == m_context)
glXMakeCurrent(m_display, None, nullptr);
glXDestroyContext(m_display, m_context);
m_context = nullptr;
}
// Destroy the window if we own it
if (m_ownsWindow && m_window)
{
XFreeColormap(m_display, m_colormap);
XDestroyWindow(m_display, m_window);
m_ownsWindow = false;
m_window = 0;
XFlush(m_display);
}
}
void ContextImpl::EnableVerticalSync(bool enabled)
{
if (glXSwapIntervalEXT)
glXSwapIntervalEXT(m_display, glXGetCurrentDrawable(), enabled ? 1 : 0);
else if (NzglXSwapIntervalMESA)
NzglXSwapIntervalMESA(enabled ? 1 : 0);
else if (glXSwapIntervalSGI)
glXSwapIntervalSGI(enabled ? 1 : 0);
else
NazaraError("Vertical sync not supported");
}
void ContextImpl::SwapBuffers()
{
if (m_window)
glXSwapBuffers(m_display, m_window);
}
bool ContextImpl::Desactivate()
{
return glXMakeCurrent(m_display, None, nullptr) == true;
}
}

View File

@ -15,7 +15,7 @@ namespace Nz
{
if (m_framerateLimit > 0)
{
int remainingTime = 1000/static_cast<int>(m_framerateLimit) - static_cast<int>(m_clock.GetMilliseconds());
int remainingTime = 1000 / static_cast<int>(m_framerateLimit) - static_cast<int>(m_clock.GetMilliseconds());
if (remainingTime > 0)
std::this_thread::sleep_for(std::chrono::milliseconds(remainingTime));
@ -38,9 +38,9 @@ namespace Nz
bool RenderWindow::OnWindowCreated()
{
RendererImpl* rendererImpl = Renderer::GetRendererImpl();
RendererImpl *rendererImpl = Renderer::GetRendererImpl();
auto surface = rendererImpl->CreateRenderSurfaceImpl();
if (!surface->Create(GetHandle()))
if (!surface->Create(GetSystemHandle()))
{
NazaraError("Failed to create render surface: " + Error::GetLastError());
return false;

View File

@ -16,9 +16,9 @@
#include <Nazara/Renderer/Debug.hpp>
#ifdef NAZARA_DEBUG
#define NazaraRendererPattern "Nazara?*Renderer-d" NAZARA_DYNLIB_EXTENSION
#define NazaraRendererDebugSuffix "-d"
#else
#define NazaraRendererPattern "Nazara?*Renderer" NAZARA_DYNLIB_EXTENSION
#define NazaraRendererDebugSuffix ""
#endif
namespace Nz
@ -48,26 +48,45 @@ namespace Nz
CallOnExit onExit(Renderer::Uninitialize);
struct RendererImplementations
{
std::filesystem::path fileName;
int score;
};
std::vector<RendererImplementations> implementations;
auto RegisterImpl = [&](std::filesystem::path fileName, auto ComputeScore)
{
fileName.replace_extension(NAZARA_DYNLIB_EXTENSION);
int score = ComputeScore();
if (score >= 0)
{
auto& impl = implementations.emplace_back();
impl.fileName = std::move(fileName);
impl.score = score;
}
};
RegisterImpl("NazaraOpenGLRenderer" NazaraRendererDebugSuffix, [] { return 50; });
RegisterImpl("NazaraVulkanRenderer" NazaraRendererDebugSuffix, [] { return 100; });
std::sort(implementations.begin(), implementations.end(), [](const auto& lhs, const auto& rhs) { return lhs.score > rhs.score; });
NazaraDebug("Searching for renderer implementation");
DynLib chosenLib;
std::unique_ptr<RendererImpl> chosenImpl;
for (auto&& entry : std::filesystem::directory_iterator("."))
for (auto&& rendererImpl : implementations)
{
if (!entry.is_regular_file())
if (!std::filesystem::exists(rendererImpl.fileName))
continue;
const std::filesystem::path& entryPath = entry.path();
std::filesystem::path fileName = entryPath.filename();
std::string fileNameStr = fileName.generic_u8string();
if (!MatchPattern(fileNameStr, NazaraRendererPattern))
continue;
NazaraDebug("Trying to load " + fileNameStr);
std::string fileNameStr = rendererImpl.fileName.generic_u8string();
DynLib implLib;
if (!implLib.Load(entryPath))
if (!implLib.Load(rendererImpl.fileName))
{
NazaraWarning("Failed to load " + fileNameStr + ": " + implLib.GetLastError());
continue;
@ -87,16 +106,11 @@ namespace Nz
continue;
}
NazaraDebug("Loaded " + impl->QueryAPIString());
NazaraDebug("Loaded " + fileNameStr);
if (!chosenImpl || impl->IsBetterThan(chosenImpl.get()))
{
if (chosenImpl)
NazaraDebug("Choose " + impl->QueryAPIString() + " over " + chosenImpl->QueryAPIString());
chosenImpl = std::move(impl); //< Move (and delete previous) implementation before unloading library
chosenLib = std::move(implLib);
}
chosenImpl = std::move(impl); //< Move (and delete previous) implementation before unloading library
chosenLib = std::move(implLib);
break;
}
if (!chosenImpl)

View File

@ -36,14 +36,6 @@ namespace Nz
return Vulkan::SelectDevice(m_physDevices[deviceIndex]);
}
bool VulkanRenderer::IsBetterThan(const RendererImpl* other) const
{
if (other->QueryAPI() == RenderAPI::Vulkan && QueryAPIVersion() < other->QueryAPIVersion())
return false;
return true; //< Vulkan FTW
}
bool VulkanRenderer::Prepare(const ParameterList& parameters)
{
return Vulkan::Initialize(APIVersion, parameters);

View File

@ -18,7 +18,9 @@ namespace Nz
bool success = false;
#if defined(NAZARA_PLATFORM_WINDOWS)
{
HWND winHandle = reinterpret_cast<HWND>(handle);
NazaraAssert(handle.type == WindowManager::Windows, "expected Windows window");
HWND winHandle = reinterpret_cast<HWND>(handle.windows.window);
HINSTANCE instance = reinterpret_cast<HINSTANCE>(GetWindowLongPtrW(winHandle, GWLP_HINSTANCE));
success = m_surface.Create(instance, winHandle);

View File

@ -167,7 +167,7 @@ namespace Ndk
overlay->keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&consoleRef] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& event)
{
if (event.code == Nz::Keyboard::F9)
if (event.virtualKey == Nz::Keyboard::VKey::F9)
{
// Toggle console visibility and focus
if (consoleRef.IsVisible())

View File

@ -39,16 +39,16 @@ namespace Ndk
}
/*!
* \brief Frees the widget, unregistering it from its canvas
*/
* \brief Frees the widget, unregistering it from its canvas
*/
BaseWidget::~BaseWidget()
{
UnregisterFromCanvas();
}
/*!
* \brief Clears keyboard focus if and only if this widget owns it.
*/
* \brief Clears keyboard focus if and only if this widget owns it.
*/
void BaseWidget::ClearFocus()
{
if (IsRegisteredToCanvas())
@ -56,10 +56,10 @@ namespace Ndk
}
/*!
* \brief Destroy the widget, deleting it in the process.
*
* Calling this function immediately destroys the widget, freeing its memory.
*/
* \brief Destroy the widget, deleting it in the process.
*
* Calling this function immediately destroys the widget, freeing its memory.
*/
void BaseWidget::Destroy()
{
NazaraAssert(this != m_canvas, "Canvas cannot be destroyed by calling Destroy()");
@ -68,8 +68,8 @@ namespace Ndk
}
/*!
* \brief Enable or disables the widget background.
*/
* \brief Enable or disables the widget background.
*/
void BaseWidget::EnableBackground(bool enable)
{
if (m_backgroundEntity.IsValid() == enable)
@ -96,9 +96,9 @@ namespace Ndk
}
/*!
* \brief Checks if this widget has keyboard focus
* \return true if widget has keyboard focus, false otherwise
*/
* \brief Checks if this widget has keyboard focus
* \return true if widget has keyboard focus, false otherwise
*/
bool BaseWidget::HasFocus() const
{
if (!IsRegisteredToCanvas())
@ -188,8 +188,7 @@ namespace Ndk
}
}
for (const auto& widgetPtr : m_children)
widgetPtr->Show(show);
ShowChildren(show);
}
}
@ -313,6 +312,16 @@ namespace Ndk
{
}
void BaseWidget::OnTextEdited(const std::array<char, 32>& /*characters*/, int /*length*/)
{
}
void BaseWidget::ShowChildren(bool show)
{
for (const auto& widgetPtr : m_children)
widgetPtr->Show(show);
}
void BaseWidget::DestroyChild(BaseWidget* widget)
{
auto it = std::find_if(m_children.begin(), m_children.end(), [widget] (const std::unique_ptr<BaseWidget>& widgetPtr) -> bool

View File

@ -157,7 +157,7 @@ namespace Ndk
if (m_widgetEntries[m_keyboardOwner].widget->OnKeyPressed(event))
return;
if (event.code == Nz::Keyboard::Tab)
if (event.virtualKey == Nz::Keyboard::VKey::Tab)
{
if (!event.shift)
{
@ -221,4 +221,10 @@ namespace Ndk
if (m_keyboardOwner != InvalidCanvasIndex)
m_widgetEntries[m_keyboardOwner].widget->OnTextEntered(event.character, event.repeated);
}
void Canvas::OnEventTextEdited(const Nz::EventHandler* /*eventHandler*/, const Nz::WindowEvent::EditEvent& event)
{
if (m_keyboardOwner != InvalidCanvasIndex)
m_widgetEntries[m_keyboardOwner].widget->OnTextEdited(event.text, event.length);
}
}

View File

@ -145,7 +145,7 @@ namespace Ndk
void Console::ClearFocus()
{
m_input->ClearFocus();
}
}
/*!
* \brief Sets the character size

View File

@ -151,9 +151,9 @@ namespace Ndk
{
const Nz::AbstractTextDrawer& textDrawer = GetTextDrawer();
switch (key.code)
switch (key.virtualKey)
{
case Nz::Keyboard::Backspace:
case Nz::Keyboard::VKey::Backspace:
{
bool ignoreDefaultAction = false;
OnTextAreaKeyBackspace(this, &ignoreDefaultAction);
@ -175,7 +175,7 @@ namespace Ndk
return true;
}
case Nz::Keyboard::Delete:
case Nz::Keyboard::VKey::Delete:
{
if (HasSelection())
EraseSelection();
@ -185,7 +185,7 @@ namespace Ndk
return true;
}
case Nz::Keyboard::Down:
case Nz::Keyboard::VKey::Down:
{
bool ignoreDefaultAction = false;
OnTextAreaKeyDown(this, &ignoreDefaultAction);
@ -200,7 +200,7 @@ namespace Ndk
return true;
}
case Nz::Keyboard::End:
case Nz::Keyboard::VKey::End:
{
bool ignoreDefaultAction = false;
OnTextAreaKeyEnd(this, &ignoreDefaultAction);
@ -217,7 +217,7 @@ namespace Ndk
return true;
}
case Nz::Keyboard::Home:
case Nz::Keyboard::VKey::Home:
{
bool ignoreDefaultAction = false;
OnTextAreaKeyHome(this, &ignoreDefaultAction);
@ -229,7 +229,7 @@ namespace Ndk
return true;
}
case Nz::Keyboard::Left:
case Nz::Keyboard::VKey::Left:
{
bool ignoreDefaultAction = false;
OnTextAreaKeyLeft(this, &ignoreDefaultAction);
@ -247,7 +247,7 @@ namespace Ndk
return true;
}
case Nz::Keyboard::Return:
case Nz::Keyboard::VKey::Return:
{
bool ignoreDefaultAction = false;
OnTextAreaKeyReturn(this, &ignoreDefaultAction);
@ -265,7 +265,7 @@ namespace Ndk
return true;;
}
case Nz::Keyboard::Right:
case Nz::Keyboard::VKey::Right:
{
bool ignoreDefaultAction = false;
OnTextAreaKeyRight(this, &ignoreDefaultAction);
@ -283,7 +283,7 @@ namespace Ndk
return true;
}
case Nz::Keyboard::Up:
case Nz::Keyboard::VKey::Up:
{
bool ignoreDefaultAction = false;
OnTextAreaKeyUp(this, &ignoreDefaultAction);
@ -298,7 +298,7 @@ namespace Ndk
return true;
}
case Nz::Keyboard::Tab:
case Nz::Keyboard::VKey::Tab:
{
if (!m_tabEnabled)
return false;
@ -331,7 +331,7 @@ namespace Ndk
Nz::Vector2ui hoveredGlyph = GetHoveredGlyph(float(x), float(y));
// Shift extends selection
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::LShift) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::RShift))
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::LShift) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::RShift))
SetSelection(hoveredGlyph, m_selectionCursor);
else
{

View File

@ -19,7 +19,7 @@ void EventState::Enter(Ndk::StateMachine& fsm)
Nz::EventHandler& eventHandler = m_context.window.GetEventHandler();
m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key)
{
if (key.code == Nz::Keyboard::Key::M && key.shift)
if (key.virtualKey == Nz::Keyboard::VKey::M && key.shift)
{
fsm.ChangeState(StateFactory::Get(EventStatus::Menu));
}
@ -90,4 +90,4 @@ Nz::String EventState::ToString(const Nz::WindowEvent& event) const
default:
return "Not handled";
}
}
}

View File

@ -18,7 +18,7 @@ void FocusState::Enter(Ndk::StateMachine& fsm)
Nz::EventHandler& eventHandler = m_context.window.GetEventHandler();
m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key)
{
if (key.code == Nz::Keyboard::Key::M && key.shift)
if (key.virtualKey == Nz::Keyboard::VKey::M && key.shift)
{
fsm.ChangeState(StateFactory::Get(EventStatus::Menu));
}
@ -38,4 +38,4 @@ void FocusState::Enter(Ndk::StateMachine& fsm)
void FocusState::DrawMenu()
{
m_text.SetContent("Click outside the windows, this text should change !\nM for Menu");
}
}

View File

@ -35,16 +35,16 @@ void KeyState::DrawMenu()
void KeyState::ManageInput(KeyStatus /*isKeyPressed*/, const Nz::WindowEvent::KeyEvent& key, Ndk::StateMachine& fsm)
{
if (key.code == Nz::Keyboard::Key::M && key.shift)
if (key.virtualKey == Nz::Keyboard::VKey::M && key.shift)
fsm.ChangeState(StateFactory::Get(EventStatus::Menu));
else if (key.code == Nz::Keyboard::Key::N && key.shift)
else if (key.virtualKey == Nz::Keyboard::VKey::N && key.shift)
{
if (m_keyStatus == KeyStatus::Pressed)
m_keyStatus = KeyStatus::Released;
else
m_keyStatus = KeyStatus::Pressed;
}
else
else
{
Nz::String content;
if (m_keyStatus == KeyStatus::Pressed)
@ -52,7 +52,7 @@ void KeyState::ManageInput(KeyStatus /*isKeyPressed*/, const Nz::WindowEvent::Ke
else
content = "Released: ";
Nz::String keyName = Nz::Keyboard::GetKeyName(key.code);
Nz::String keyName = Nz::Keyboard::GetKeyName(key.virtualKey) + " (" + Nz::Keyboard::GetKeyName(key.scancode) + ")";
if (keyName.IsEmpty())
{
m_text.SetContent("Unknown\nM for Menu");
@ -74,4 +74,4 @@ void KeyState::ManageInput(KeyStatus /*isKeyPressed*/, const Nz::WindowEvent::Ke
m_text.SetContent(content + "\nM for Menu");
}
}
}
}

View File

@ -19,9 +19,9 @@ void MenuState::Enter(Ndk::StateMachine& fsm)
Nz::EventHandler& eventHandler = m_context.window.GetEventHandler();
m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [this] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key)
{
if (key.code >= Nz::Keyboard::Key::A && key.code < (Nz::Keyboard::Key::A + static_cast<int>(EventStatus::Max) - 1))
if (key.virtualKey >= Nz::Keyboard::VKey::A && key.virtualKey < static_cast<Nz::Keyboard::VKey>(static_cast<int>(Nz::Keyboard::VKey::A) + static_cast<int>(EventStatus::Max) - 1))
{
m_selectedNextState = key.code - static_cast<int>(Nz::Keyboard::Key::A);
m_selectedNextState = static_cast<int>(key.virtualKey) - static_cast<int>(Nz::Keyboard::VKey::A);
}
});
}
@ -44,4 +44,4 @@ bool MenuState::Update(Ndk::StateMachine& fsm, float /*elapsedTime*/)
void MenuState::DrawMenu()
{
m_text.SetContent("a. Event\nb. Focus\nc. Key\nd. Mouse click\ne. Mouse enter\nf. Mouse move\ng. Text enter\nh. Window modification");
}
}

View File

@ -18,7 +18,7 @@ void MouseClickState::Enter(Ndk::StateMachine& fsm)
Nz::EventHandler& eventHandler = m_context.window.GetEventHandler();
m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key)
{
if (key.code == Nz::Keyboard::Key::M && key.shift)
if (key.virtualKey == Nz::Keyboard::VKey::M && key.shift)
{
fsm.ChangeState(StateFactory::Get(EventStatus::Menu));
}
@ -78,4 +78,4 @@ void MouseClickState::ManageInput(MouseStatus mouseStatus, const Nz::WindowEvent
}
m_text.SetContent(content + "\nM for Menu");
}
}

View File

@ -18,7 +18,7 @@ void MouseEnterState::Enter(Ndk::StateMachine& fsm)
Nz::EventHandler& eventHandler = m_context.window.GetEventHandler();
m_keyPressedSlot.Connect(eventHandler.OnKeyPressed, [&] (const Nz::EventHandler*, const Nz::WindowEvent::KeyEvent& key)
{
if (key.code == Nz::Keyboard::Key::M && key.shift)
if (key.virtualKey == Nz::Keyboard::VKey::M && key.shift)
{
fsm.ChangeState(StateFactory::Get(EventStatus::Menu));
}
@ -38,4 +38,4 @@ void MouseEnterState::Enter(Ndk::StateMachine& fsm)
void MouseEnterState::DrawMenu()
{
m_text.SetContent("Move your mouse outside the windows, this text should change !\nM for Menu");
}
}

Some files were not shown because too many files have changed in this diff Show More