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
5 #ifndef __C_IRR_DEVICE_LINUX_H_INCLUDED__
\r
6 #define __C_IRR_DEVICE_LINUX_H_INCLUDED__
\r
9 #ifdef _IRR_COMPILE_WITH_X11_DEVICE_
\r
11 #include "CIrrDeviceStub.h"
\r
12 #include "IrrlichtDevice.h"
\r
13 #include "ICursorControl.h"
\r
16 #ifdef _IRR_COMPILE_WITH_X11_
\r
18 #include <X11/Xlib.h>
\r
19 #include <X11/Xutil.h>
\r
20 #include <X11/cursorfont.h>
\r
21 #include <X11/keysym.h>
\r
23 #ifdef _IRR_LINUX_X11_XINPUT2_
\r
24 #include <X11/extensions/XInput2.h>
\r
34 class CIrrDeviceLinux : public CIrrDeviceStub
\r
39 CIrrDeviceLinux(const SIrrlichtCreationParameters& param);
\r
42 virtual ~CIrrDeviceLinux();
\r
44 //! runs the device. Returns false if device wants to be deleted
\r
45 bool run() override;
\r
47 //! Cause the device to temporarily pause execution and let other processes to run
\r
48 // This should bring down processor usage without major performance loss for Irrlicht
\r
49 void yield() override;
\r
51 //! Pause execution and let other processes to run for a specified amount of time.
\r
52 void sleep(u32 timeMs, bool pauseTimer) override;
\r
54 //! sets the caption of the window
\r
55 void setWindowCaption(const wchar_t* text) override;
\r
57 //! returns if window is active. if not, nothing need to be drawn
\r
58 bool isWindowActive() const override;
\r
60 //! returns if window has focus.
\r
61 bool isWindowFocused() const override;
\r
63 //! returns if window is minimized.
\r
64 bool isWindowMinimized() const override;
\r
66 //! returns last state from maximizeWindow() and restoreWindow()
\r
67 bool isWindowMaximized() const override;
\r
69 //! returns color format of the window.
\r
70 video::ECOLOR_FORMAT getColorFormat() const override;
\r
72 //! notifies the device that it should close itself
\r
73 void closeDevice() override;
\r
75 //! Sets if the window should be resizable in windowed mode.
\r
76 void setResizable(bool resize=false) override;
\r
78 //! Resize the render window.
\r
79 void setWindowSize(const irr::core::dimension2d<u32>& size) override;
\r
81 //! Minimizes the window.
\r
82 void minimizeWindow() override;
\r
84 //! Maximizes the window.
\r
85 void maximizeWindow() override;
\r
87 //! Restores the window size.
\r
88 void restoreWindow() override;
\r
90 //! Get the position of this window on screen
\r
91 core::position2di getWindowPosition() override;
\r
93 //! Activate any joysticks, and generate events for them.
\r
94 bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo) override;
\r
96 //! gets text from the clipboard
\r
97 //! \return Returns 0 if no string is in there, otherwise utf-8 text.
\r
98 virtual const c8 *getTextFromClipboard() const;
\r
100 //! copies text to the clipboard
\r
101 //! This sets the clipboard selection and _not_ the primary selection which you have on X on the middle mouse button.
\r
102 //! @param text The text in utf-8
\r
103 virtual void copyToClipboard(const c8 *text) const;
\r
105 //! Remove all messages pending in the system message loop
\r
106 void clearSystemMessages() override;
\r
108 //! Get the device type
\r
109 E_DEVICE_TYPE getType() const override
\r
114 #ifdef _IRR_COMPILE_WITH_X11_
\r
115 // convert an Irrlicht texture to a X11 cursor
\r
116 Cursor TextureToCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot);
\r
117 Cursor TextureToMonochromeCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot);
\r
118 #ifdef _IRR_LINUX_XCURSOR_
\r
119 Cursor TextureToARGBCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot);
\r
125 //! create the driver
\r
126 void createDriver();
\r
128 bool createWindow();
\r
130 void createKeyMap();
\r
132 void pollJoysticks();
\r
136 void initXInput2();
\r
138 bool switchToFullscreen();
\r
140 #ifdef _IRR_COMPILE_WITH_X11_
\r
141 bool createInputContext();
\r
142 void destroyInputContext();
\r
143 EKEY_CODE getKeyCode(XEvent &event);
\r
146 //! Implementation of the linux cursor control
\r
147 class CCursorControl : public gui::ICursorControl
\r
151 CCursorControl(CIrrDeviceLinux* dev, bool null);
\r
155 //! Changes the visible state of the mouse cursor.
\r
156 void setVisible(bool visible) override
\r
158 if (visible==IsVisible)
\r
160 IsVisible = visible;
\r
161 #ifdef _IRR_COMPILE_WITH_X11_
\r
165 XDefineCursor( Device->XDisplay, Device->XWindow, InvisCursor );
\r
167 XUndefineCursor( Device->XDisplay, Device->XWindow );
\r
172 //! Returns if the cursor is currently visible.
\r
173 bool isVisible() const override
\r
178 //! Sets the new position of the cursor.
\r
179 void setPosition(const core::position2d<f32> &pos) override
\r
181 setPosition(pos.X, pos.Y);
\r
184 //! Sets the new position of the cursor.
\r
185 void setPosition(f32 x, f32 y) override
\r
187 setPosition((s32)(x*Device->Width), (s32)(y*Device->Height));
\r
190 //! Sets the new position of the cursor.
\r
191 void setPosition(const core::position2d<s32> &pos) override
\r
193 setPosition(pos.X, pos.Y);
\r
196 //! Sets the new position of the cursor.
\r
197 void setPosition(s32 x, s32 y) override
\r
199 #ifdef _IRR_COMPILE_WITH_X11_
\r
203 if (UseReferenceRect)
\r
205 // NOTE: XIWarpPointer works when X11 has set a coordinate transformation matrix for the mouse unlike XWarpPointer
\r
206 // which runs into a bug mentioned here: https://gitlab.freedesktop.org/xorg/xserver/-/issues/600
\r
207 // So also workaround for Irrlicht bug #450
\r
208 #ifdef _IRR_LINUX_X11_XINPUT2_
\r
209 if ( DeviceId != 0)
\r
211 XIWarpPointer(Device->XDisplay,
\r
214 Device->XWindow, 0, 0,
\r
217 ReferenceRect.UpperLeftCorner.X + x,
\r
218 ReferenceRect.UpperLeftCorner.Y + y);
\r
223 XWarpPointer(Device->XDisplay,
\r
225 Device->XWindow, 0, 0,
\r
228 ReferenceRect.UpperLeftCorner.X + x,
\r
229 ReferenceRect.UpperLeftCorner.Y + y);
\r
234 #ifdef _IRR_LINUX_X11_XINPUT2_
\r
235 if ( DeviceId != 0)
\r
237 XIWarpPointer(Device->XDisplay,
\r
240 Device->XWindow, 0, 0,
\r
242 Device->Height, x, y);
\r
247 XWarpPointer(Device->XDisplay,
\r
249 Device->XWindow, 0, 0,
\r
251 Device->Height, x, y);
\r
254 XFlush(Device->XDisplay);
\r
261 //! Returns the current position of the mouse cursor.
\r
262 const core::position2d<s32>& getPosition(bool updateCursor) override
\r
264 if ( updateCursor )
\r
269 //! Returns the current position of the mouse cursor.
\r
270 core::position2d<f32> getRelativePosition(bool updateCursor) override
\r
272 if ( updateCursor )
\r
275 if (!UseReferenceRect)
\r
277 return core::position2d<f32>(CursorPos.X / (f32)Device->Width,
\r
278 CursorPos.Y / (f32)Device->Height);
\r
281 return core::position2d<f32>(CursorPos.X / (f32)ReferenceRect.getWidth(),
\r
282 CursorPos.Y / (f32)ReferenceRect.getHeight());
\r
285 void setReferenceRect(core::rect<s32>* rect=0) override
\r
289 ReferenceRect = *rect;
\r
290 UseReferenceRect = true;
\r
292 // prevent division through zero and uneven sizes
\r
294 if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2)
\r
295 ReferenceRect.LowerRightCorner.Y += 1;
\r
297 if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2)
\r
298 ReferenceRect.LowerRightCorner.X += 1;
\r
301 UseReferenceRect = false;
\r
304 //! Sets the active cursor icon
\r
305 void setActiveIcon(gui::ECURSOR_ICON iconId) override;
\r
307 //! Gets the currently active icon
\r
308 gui::ECURSOR_ICON getActiveIcon() const override
\r
313 //! Add a custom sprite as cursor icon.
\r
314 gui::ECURSOR_ICON addIcon(const gui::SCursorSprite& icon) override;
\r
316 //! replace the given cursor icon.
\r
317 void changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite& icon) override;
\r
319 //! Return a system-specific size which is supported for cursors. Larger icons will fail, smaller icons might work.
\r
320 core::dimension2di getSupportedIconSize() const override;
\r
322 #ifdef _IRR_COMPILE_WITH_X11_
\r
323 //! Set platform specific behavior flags.
\r
324 void setPlatformBehavior(gui::ECURSOR_PLATFORM_BEHAVIOR behavior) override {PlatformBehavior = behavior; }
\r
326 //! Return platform specific behavior.
\r
327 gui::ECURSOR_PLATFORM_BEHAVIOR getPlatformBehavior() const override { return PlatformBehavior; }
\r
330 void clearCursors();
\r
334 void updateCursorPos()
\r
336 #ifdef _IRR_COMPILE_WITH_X11_
\r
340 if ( PlatformBehavior&gui::ECPB_X11_CACHE_UPDATES && !os::Timer::isStopped() )
\r
342 u32 now = os::Timer::getTime();
\r
343 if (now <= LastQuery)
\r
350 unsigned int maskreturn;
\r
351 XQueryPointer(Device->XDisplay, Device->XWindow,
\r
354 &CursorPos.X, &CursorPos.Y, &maskreturn);
\r
358 CIrrDeviceLinux* Device;
\r
359 core::position2d<s32> CursorPos;
\r
360 core::rect<s32> ReferenceRect;
\r
361 #ifdef _IRR_COMPILE_WITH_X11_
\r
362 gui::ECURSOR_PLATFORM_BEHAVIOR PlatformBehavior;
\r
364 Cursor InvisCursor;
\r
366 #ifdef _IRR_LINUX_X11_XINPUT2_
\r
370 struct CursorFrameX11
\r
372 CursorFrameX11() : IconHW(0) {}
\r
373 CursorFrameX11(Cursor icon) : IconHW(icon) {}
\r
375 Cursor IconHW; // hardware cursor
\r
381 explicit CursorX11(Cursor iconHw, u32 frameTime=0) : FrameTime(frameTime)
\r
383 Frames.push_back( CursorFrameX11(iconHw) );
\r
385 core::array<CursorFrameX11> Frames;
\r
389 core::array<CursorX11> Cursors;
\r
391 void initCursors();
\r
395 bool UseReferenceRect;
\r
396 gui::ECURSOR_ICON ActiveIcon;
\r
397 u32 ActiveIconStartTime;
\r
400 friend class CCursorControl;
\r
402 #ifdef _IRR_COMPILE_WITH_X11_
\r
403 friend class COpenGLDriver;
\r
406 XVisualInfo* VisualInfo;
\r
409 XSetWindowAttributes WndAttributes;
\r
410 XSizeHints* StdHints;
\r
415 mutable core::stringc Clipboard;
\r
417 #if defined(_IRR_LINUX_X11_XINPUT2_)
\r
418 int currentTouchedCount;
\r
421 bool WindowHasFocus;
\r
422 bool WindowMinimized;
\r
423 bool WindowMaximized;
\r
424 bool ExternalWindow;
\r
425 int AutorepeatSupport;
\r
430 SKeyMap(s32 x11, s32 win32)
\r
431 : X11Key(x11), Win32Key(win32)
\r
438 bool operator<(const SKeyMap& o) const
\r
440 return X11Key<o.X11Key;
\r
444 core::array<SKeyMap> KeyMap;
\r
446 #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
\r
447 struct JoystickInfo
\r
453 SEvent persistentData;
\r
455 JoystickInfo() : fd(-1), axes(0), buttons(0) { }
\r
457 core::array<JoystickInfo> ActiveJoysticks;
\r
462 } // end namespace irr
\r
464 #endif // _IRR_COMPILE_WITH_X11_DEVICE_
\r
465 #endif // __C_IRR_DEVICE_LINUX_H_INCLUDED__
\r