Merge branch 'vulkan' into shader-nodes
This commit is contained in:
commit
e4348349da
|
|
@ -0,0 +1,2 @@
|
|||
github: [SirLynix]
|
||||
custom: ['https://paypal.me/sirlynixvanfrietjes']
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,3 +32,4 @@ MODULE.OsLibraries.Posix = {
|
|||
"GL",
|
||||
"X11"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -9,3 +9,7 @@ EXAMPLE.Files = {
|
|||
EXAMPLE.Libraries = {
|
||||
"NazaraSDK"
|
||||
}
|
||||
|
||||
if Config.PlatformSDL2 then
|
||||
table.insert(EXAMPLE.Defines, "NAZARA_PLATFORM_SDL2")
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,3 +12,6 @@ EXAMPLE.Libraries = {
|
|||
"NazaraUtility"
|
||||
}
|
||||
|
||||
if Config.PlatformSDL2 then
|
||||
table.insert(EXAMPLE.Defines, "NAZARA_PLATFORM_SDL2")
|
||||
end
|
||||
|
|
|
|||
|
|
@ -680,6 +680,7 @@ void SpacebattleExample::Leave(Ndk::StateMachine& fsm)
|
|||
{
|
||||
m_ambientMusic.Stop();
|
||||
m_onMouseMoved.Disconnect();
|
||||
if (m_shared.target)
|
||||
m_shared.target->SetCursor(Nz::SystemCursor_Default);
|
||||
m_shared.world3D->RemoveSystem<LaserBeamSystem>();
|
||||
m_shared.world3D->RemoveSystem<SpaceshipSystem>();
|
||||
|
|
|
|||
|
|
@ -11,3 +11,7 @@ EXAMPLE.Files = {
|
|||
EXAMPLE.Libraries = {
|
||||
"NazaraSDK"
|
||||
}
|
||||
|
||||
if Config.PlatformSDL2 then
|
||||
table.insert(EXAMPLE.Defines, "NAZARA_PLATFORM_SDL2")
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,3 +18,7 @@ EXAMPLE.Libraries = {
|
|||
"NazaraUtility",
|
||||
"NazaraSDK"
|
||||
}
|
||||
|
||||
if Config.PlatformSDL2 then
|
||||
table.insert(EXAMPLE.Defines, "NAZARA_PLATFORM_SDL2")
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,3 +9,7 @@ EXAMPLE.Files = {
|
|||
EXAMPLE.Libraries = {
|
||||
"NazaraSDK"
|
||||
}
|
||||
|
||||
if Config.PlatformSDL2 then
|
||||
table.insert(EXAMPLE.Defines, "NAZARA_PLATFORM_SDL2")
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,3 +9,7 @@ EXAMPLE.Files = {
|
|||
EXAMPLE.Libraries = {
|
||||
"NazaraSDK"
|
||||
}
|
||||
|
||||
if Config.PlatformSDL2 then
|
||||
table.insert(EXAMPLE.Defines, "NAZARA_PLATFORM_SDL2")
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ namespace Nz
|
|||
WindowEventType_Moved,
|
||||
WindowEventType_Quit,
|
||||
WindowEventType_Resized,
|
||||
WindowEventType_TextEdited,
|
||||
WindowEventType_TextEntered,
|
||||
|
||||
WindowEventType_Max = WindowEventType_TextEntered
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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*/);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,6 +78,10 @@ namespace Nz
|
|||
case WindowEventType_TextEntered:
|
||||
OnTextEntered(this, event.text);
|
||||
break;
|
||||
|
||||
case WindowEventType_TextEdited:
|
||||
OnTextEdited(this, event.edit);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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*/
|
||||
#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
|
||||
|
|
|
|||
|
|
@ -26,11 +26,11 @@ namespace Nz
|
|||
public:
|
||||
inline RenderWindow();
|
||||
inline RenderWindow(VideoMode mode, const String &title, WindowStyleFlags style = WindowStyle_Default, const RenderWindowParameters ¶meters = RenderWindowParameters());
|
||||
inline explicit RenderWindow(WindowHandle handle, const RenderWindowParameters& parameters = RenderWindowParameters());
|
||||
inline explicit RenderWindow(void* handle, const RenderWindowParameters ¶meters = RenderWindowParameters());
|
||||
inline ~RenderWindow();
|
||||
|
||||
inline bool Create(VideoMode mode, const String &title, WindowStyleFlags style = WindowStyle_Default, const RenderWindowParameters ¶meters = RenderWindowParameters());
|
||||
inline bool Create(WindowHandle handle, const RenderWindowParameters& parameters = RenderWindowParameters());
|
||||
inline bool Create(void* handle, const RenderWindowParameters ¶meters = RenderWindowParameters());
|
||||
|
||||
void Display();
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ namespace Nz
|
|||
RenderWindowParameters m_parameters;
|
||||
unsigned int m_framerateLimit;
|
||||
};
|
||||
}
|
||||
} // namespace Nz
|
||||
|
||||
#include <Nazara/Renderer/RenderWindow.inl>
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,6 @@ namespace Nz
|
|||
|
||||
void DummySurface::Destroy()
|
||||
{
|
||||
m_handle = nullptr;
|
||||
m_handle = WindowHandle{};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -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)];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);*/
|
||||
//}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -40,7 +40,7 @@ namespace Nz
|
|||
{
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
||||
if (!chosenImpl || impl->IsBetterThan(chosenImpl.get()))
|
||||
{
|
||||
if (chosenImpl)
|
||||
NazaraDebug("Choose " + impl->QueryAPIString() + " over " + chosenImpl->QueryAPIString());
|
||||
NazaraDebug("Loaded " + fileNameStr);
|
||||
|
||||
chosenImpl = std::move(impl); //< Move (and delete previous) implementation before unloading library
|
||||
chosenLib = std::move(implLib);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!chosenImpl)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ 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;
|
||||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ void MouseMoveState::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));
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue