1 // Copyright (C) 2002-2012 Nikolaus Gebhardt
\r
2 // This file is part of the "Irrlicht Engine".
\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
\r
4 // This device code is based on the original SDL device implementation
\r
5 // contributed by Shane Parker (sirshane).
\r
7 #ifndef __C_IRR_DEVICE_SDL_H_INCLUDED__
\r
8 #define __C_IRR_DEVICE_SDL_H_INCLUDED__
\r
11 #ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
\r
13 #include "IrrlichtDevice.h"
\r
14 #include "CIrrDeviceStub.h"
\r
15 #include "ICursorControl.h"
\r
17 #ifdef _IRR_EMSCRIPTEN_PLATFORM_
\r
18 #include <emscripten/html5.h>
\r
22 #include <SDL_syswm.h>
\r
29 class CIrrDeviceSDL : public CIrrDeviceStub
\r
34 CIrrDeviceSDL(const SIrrlichtCreationParameters& param);
\r
37 virtual ~CIrrDeviceSDL();
\r
39 //! runs the device. Returns false if device wants to be deleted
\r
40 bool run() override;
\r
42 //! pause execution temporarily
\r
43 void yield() override;
\r
45 //! pause execution for a specified time
\r
46 void sleep(u32 timeMs, bool pauseTimer) override;
\r
48 //! sets the caption of the window
\r
49 void setWindowCaption(const wchar_t* text) override;
\r
51 //! returns if window is active. if not, nothing need to be drawn
\r
52 bool isWindowActive() const override;
\r
54 //! returns if window has focus.
\r
55 bool isWindowFocused() const override;
\r
57 //! returns if window is minimized.
\r
58 bool isWindowMinimized() const override;
\r
60 //! returns color format of the window.
\r
61 video::ECOLOR_FORMAT getColorFormat() const override;
\r
63 //! notifies the device that it should close itself
\r
64 void closeDevice() override;
\r
66 //! Sets if the window should be resizable in windowed mode.
\r
67 void setResizable(bool resize=false) override;
\r
69 //! Minimizes the window.
\r
70 void minimizeWindow() override;
\r
72 //! Maximizes the window.
\r
73 void maximizeWindow() override;
\r
75 //! Restores the window size.
\r
76 void restoreWindow() override;
\r
78 //! Checks if the window is maximized.
\r
79 bool isWindowMaximized() const override;
\r
81 //! Checks if the Irrlicht window is running in fullscreen mode
\r
82 /** \return True if window is fullscreen. */
\r
83 bool isFullscreen() const override;
\r
85 //! Get the position of this window on screen
\r
86 core::position2di getWindowPosition() override;
\r
88 //! Activate any joysticks, and generate events for them.
\r
89 bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo) override;
\r
91 //! Get the device type
\r
92 E_DEVICE_TYPE getType() const override
\r
99 //! Implementation of the linux cursor control
\r
100 class CCursorControl : public gui::ICursorControl
\r
104 CCursorControl(CIrrDeviceSDL* dev)
\r
105 : Device(dev), IsVisible(true)
\r
110 //! Changes the visible state of the mouse cursor.
\r
111 void setVisible(bool visible) override
\r
113 IsVisible = visible;
\r
115 SDL_ShowCursor( SDL_ENABLE );
\r
118 SDL_ShowCursor( SDL_DISABLE );
\r
122 //! Returns if the cursor is currently visible.
\r
123 bool isVisible() const override
\r
128 //! Sets the new position of the cursor.
\r
129 void setPosition(const core::position2d<f32> &pos) override
\r
131 setPosition(pos.X, pos.Y);
\r
134 //! Sets the new position of the cursor.
\r
135 void setPosition(f32 x, f32 y) override
\r
137 setPosition((s32)(x*Device->Width), (s32)(y*Device->Height));
\r
140 //! Sets the new position of the cursor.
\r
141 void setPosition(const core::position2d<s32> &pos) override
\r
143 setPosition(pos.X, pos.Y);
\r
146 //! Sets the new position of the cursor.
\r
147 void setPosition(s32 x, s32 y) override
\r
149 SDL_WarpMouseInWindow(Device->Window, x, y);
\r
151 if (SDL_GetRelativeMouseMode()) {
\r
152 // There won't be an event for this warp (details on libsdl-org/SDL/issues/6034)
\r
153 Device->MouseX = x;
\r
154 Device->MouseY = y;
\r
158 //! Returns the current position of the mouse cursor.
\r
159 const core::position2d<s32>& getPosition(bool updateCursor) override
\r
161 if ( updateCursor )
\r
166 //! Returns the current position of the mouse cursor.
\r
167 core::position2d<f32> getRelativePosition(bool updateCursor) override
\r
169 if ( updateCursor )
\r
171 return core::position2d<f32>(CursorPos.X / (f32)Device->Width,
\r
172 CursorPos.Y / (f32)Device->Height);
\r
175 void setReferenceRect(core::rect<s32>* rect=0) override
\r
179 virtual void setRelativeMode(bool relative) _IRR_OVERRIDE_
\r
181 // Only change it when necessary, as it flushes mouse motion when enabled
\r
182 if ( relative != SDL_GetRelativeMouseMode()) {
\r
184 SDL_SetRelativeMouseMode( SDL_TRUE );
\r
186 SDL_SetRelativeMouseMode( SDL_FALSE );
\r
190 void setActiveIcon(gui::ECURSOR_ICON iconId) override
\r
192 ActiveIcon = iconId;
\r
193 if (iconId > Cursors.size() || !Cursors[iconId]) {
\r
194 iconId = gui::ECI_NORMAL;
\r
195 if (iconId > Cursors.size() || !Cursors[iconId])
\r
198 SDL_SetCursor(Cursors[iconId].get());
\r
201 gui::ECURSOR_ICON getActiveIcon() const override
\r
208 void updateCursorPos()
\r
210 #ifdef _IRR_EMSCRIPTEN_PLATFORM_
\r
211 EmscriptenPointerlockChangeEvent pointerlockStatus; // let's hope that test is not expensive ...
\r
212 if ( emscripten_get_pointerlock_status(&pointerlockStatus) == EMSCRIPTEN_RESULT_SUCCESS )
\r
214 if ( pointerlockStatus.isActive )
\r
216 CursorPos.X += Device->MouseXRel;
\r
217 CursorPos.Y += Device->MouseYRel;
\r
218 Device->MouseXRel = 0;
\r
219 Device->MouseYRel = 0;
\r
223 CursorPos.X = Device->MouseX;
\r
224 CursorPos.Y = Device->MouseY;
\r
228 CursorPos.X = Device->MouseX;
\r
229 CursorPos.Y = Device->MouseY;
\r
231 if (CursorPos.X < 0)
\r
233 if (CursorPos.X > (s32)Device->Width)
\r
234 CursorPos.X = Device->Width;
\r
235 if (CursorPos.Y < 0)
\r
237 if (CursorPos.Y > (s32)Device->Height)
\r
238 CursorPos.Y = Device->Height;
\r
242 void initCursors();
\r
244 CIrrDeviceSDL* Device;
\r
245 core::position2d<s32> CursorPos;
\r
248 struct CursorDeleter {
\r
249 void operator()(SDL_Cursor *ptr) {
\r
251 SDL_FreeCursor(ptr);
\r
254 std::vector<std::unique_ptr<SDL_Cursor, CursorDeleter>> Cursors;
\r
255 gui::ECURSOR_ICON ActiveIcon;
\r
260 #ifdef _IRR_EMSCRIPTEN_PLATFORM_
\r
261 static EM_BOOL MouseUpDownCallback(int eventType, const EmscriptenMouseEvent * event, void* userData);
\r
262 static EM_BOOL MouseEnterCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
\r
263 static EM_BOOL MouseLeaveCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
\r
266 // Check if a key is a known special character with no side effects on text boxes.
\r
267 static bool keyIsKnownSpecial(EKEY_CODE key);
\r
269 // Return the Char that should be sent to Irrlicht for the given key (either the one passed in or 0).
\r
270 static int findCharToPassToIrrlicht(int assumedChar, EKEY_CODE key);
\r
272 // Check if a text box is in focus. Enable or disable SDL_TEXTINPUT events only if in focus.
\r
273 void resetReceiveTextInputEvents();
\r
275 //! create the driver
\r
276 void createDriver();
\r
278 bool createWindow();
\r
280 void createKeyMap();
\r
282 void logAttributes();
\r
283 SDL_GLContext Context;
\r
284 SDL_Window *Window;
\r
286 #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
\r
287 core::array<SDL_Joystick*> Joysticks;
\r
290 s32 MouseX, MouseY;
\r
291 s32 MouseXRel, MouseYRel;
\r
292 u32 MouseButtonStates;
\r
301 SKeyMap(s32 x11, s32 win32)
\r
302 : SDLKey(x11), Win32Key(win32)
\r
309 bool operator<(const SKeyMap& o) const
\r
311 return SDLKey<o.SDLKey;
\r
315 core::array<SKeyMap> KeyMap;
\r
316 SDL_SysWMinfo Info;
\r
319 } // end namespace irr
\r
321 #endif // _IRR_COMPILE_WITH_SDL_DEVICE_
\r
322 #endif // __C_IRR_DEVICE_SDL_H_INCLUDED__
\r