]> git.lizzy.rs Git - irrlicht.git/blob - source/Irrlicht/CIrrDeviceLinux.h
344149e1a9357f63c3f0046036d691b1d296b714
[irrlicht.git] / source / Irrlicht / CIrrDeviceLinux.h
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 \r
5 #ifndef __C_IRR_DEVICE_LINUX_H_INCLUDED__\r
6 #define __C_IRR_DEVICE_LINUX_H_INCLUDED__\r
7 \r
8 #include "IrrCompileConfig.h"\r
9 \r
10 #ifdef _IRR_COMPILE_WITH_X11_DEVICE_\r
11 \r
12 #include "CIrrDeviceStub.h"\r
13 #include "IrrlichtDevice.h"\r
14 #include "IImagePresenter.h"\r
15 #include "ICursorControl.h"\r
16 #include "os.h"\r
17 \r
18 #ifdef _IRR_COMPILE_WITH_X11_\r
19 \r
20 #include <X11/Xlib.h>\r
21 #include <X11/Xutil.h>\r
22 #include <X11/cursorfont.h>\r
23 #ifdef _IRR_LINUX_X11_VIDMODE_\r
24 #include <X11/extensions/xf86vmode.h>\r
25 #endif\r
26 #ifdef _IRR_LINUX_X11_RANDR_\r
27 #include <X11/extensions/Xrandr.h>\r
28 #endif\r
29 #include <X11/keysym.h>\r
30 \r
31 #else\r
32 #define KeySym s32\r
33 #endif\r
34 \r
35 namespace irr\r
36 {\r
37 \r
38         class CIrrDeviceLinux : public CIrrDeviceStub, public video::IImagePresenter\r
39         {\r
40         public:\r
41 \r
42                 //! constructor\r
43                 CIrrDeviceLinux(const SIrrlichtCreationParameters& param);\r
44 \r
45                 //! destructor\r
46                 virtual ~CIrrDeviceLinux();\r
47 \r
48                 //! runs the device. Returns false if device wants to be deleted\r
49                 virtual bool run() _IRR_OVERRIDE_;\r
50 \r
51                 //! Cause the device to temporarily pause execution and let other processes to run\r
52                 // This should bring down processor usage without major performance loss for Irrlicht\r
53                 virtual void yield() _IRR_OVERRIDE_;\r
54 \r
55                 //! Pause execution and let other processes to run for a specified amount of time.\r
56                 virtual void sleep(u32 timeMs, bool pauseTimer) _IRR_OVERRIDE_;\r
57 \r
58                 //! sets the caption of the window\r
59                 virtual void setWindowCaption(const wchar_t* text) _IRR_OVERRIDE_;\r
60 \r
61                 //! returns if window is active. if not, nothing need to be drawn\r
62                 virtual bool isWindowActive() const _IRR_OVERRIDE_;\r
63 \r
64                 //! returns if window has focus.\r
65                 virtual bool isWindowFocused() const _IRR_OVERRIDE_;\r
66 \r
67                 //! returns if window is minimized.\r
68                 virtual bool isWindowMinimized() const _IRR_OVERRIDE_;\r
69 \r
70                 //! returns color format of the window.\r
71                 virtual video::ECOLOR_FORMAT getColorFormat() const _IRR_OVERRIDE_;\r
72 \r
73                 //! presents a surface in the client area\r
74                 virtual bool present(video::IImage* surface, void* windowId=0, core::rect<s32>* src=0 ) _IRR_OVERRIDE_;\r
75 \r
76                 //! notifies the device that it should close itself\r
77                 virtual void closeDevice() _IRR_OVERRIDE_;\r
78 \r
79                 //! \return Returns a pointer to a list with all video modes\r
80                 //! supported by the gfx adapter.\r
81                 virtual video::IVideoModeList* getVideoModeList() _IRR_OVERRIDE_;\r
82 \r
83                 //! Sets if the window should be resizable in windowed mode.\r
84                 virtual void setResizable(bool resize=false) _IRR_OVERRIDE_;\r
85 \r
86                 //! Resize the render window.\r
87                 virtual void setWindowSize(const irr::core::dimension2d<u32>& size) _IRR_OVERRIDE_;\r
88 \r
89                 //! Minimizes the window.\r
90                 virtual void minimizeWindow() _IRR_OVERRIDE_;\r
91 \r
92                 //! Maximizes the window.\r
93                 virtual void maximizeWindow() _IRR_OVERRIDE_;\r
94 \r
95                 //! Restores the window size.\r
96                 virtual void restoreWindow() _IRR_OVERRIDE_;\r
97 \r
98                 //! Get the position of this window on screen\r
99                 virtual core::position2di getWindowPosition() _IRR_OVERRIDE_;\r
100 \r
101                 //! Activate any joysticks, and generate events for them.\r
102                 virtual bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo) _IRR_OVERRIDE_;\r
103 \r
104                 //! Set the current Gamma Value for the Display\r
105                 virtual bool setGammaRamp( f32 red, f32 green, f32 blue, f32 brightness, f32 contrast ) _IRR_OVERRIDE_;\r
106 \r
107                 //! Get the current Gamma Value for the Display\r
108                 virtual bool getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast ) _IRR_OVERRIDE_;\r
109 \r
110                 //! gets text from the clipboard\r
111                 //! \return Returns 0 if no string is in there.\r
112                 virtual const c8* getTextFromClipboard() const;\r
113 \r
114                 //! copies text to the clipboard\r
115                 //! This sets the clipboard selection and _not_ the primary selection which you have on X on the middle mouse button.\r
116                 virtual void copyToClipboard(const c8* text) const;\r
117 \r
118                 //! Remove all messages pending in the system message loop\r
119                 virtual void clearSystemMessages() _IRR_OVERRIDE_;\r
120 \r
121                 //! Get the device type\r
122                 virtual E_DEVICE_TYPE getType() const _IRR_OVERRIDE_\r
123                 {\r
124                                 return EIDT_X11;\r
125                 }\r
126 \r
127 #ifdef _IRR_COMPILE_WITH_X11_\r
128                 // convert an Irrlicht texture to a X11 cursor\r
129                 Cursor TextureToCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot);\r
130                 Cursor TextureToMonochromeCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot);\r
131 #ifdef _IRR_LINUX_XCURSOR_\r
132                 Cursor TextureToARGBCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot);\r
133 #endif\r
134 #endif\r
135 \r
136         private:\r
137 \r
138                 //! create the driver\r
139                 void createDriver();\r
140 \r
141                 bool createWindow();\r
142 \r
143                 void createKeyMap();\r
144 \r
145                 void pollJoysticks();\r
146 \r
147                 void initXAtoms();\r
148 \r
149                 bool switchToFullscreen(bool reset=false);\r
150 \r
151 #ifdef _IRR_COMPILE_WITH_X11_\r
152                 bool createInputContext();\r
153                 void destroyInputContext();\r
154                 EKEY_CODE getKeyCode(XEvent &event);\r
155 #endif\r
156 \r
157                 //! Implementation of the linux cursor control\r
158                 class CCursorControl : public gui::ICursorControl\r
159                 {\r
160                 public:\r
161 \r
162                         CCursorControl(CIrrDeviceLinux* dev, bool null);\r
163 \r
164                         ~CCursorControl();\r
165 \r
166                         //! Changes the visible state of the mouse cursor.\r
167                         virtual void setVisible(bool visible) _IRR_OVERRIDE_\r
168                         {\r
169                                 if (visible==IsVisible)\r
170                                         return;\r
171                                 IsVisible = visible;\r
172 #ifdef _IRR_COMPILE_WITH_X11_\r
173                                 if (!Null)\r
174                                 {\r
175                                         if ( !IsVisible )\r
176                                                 XDefineCursor( Device->XDisplay, Device->XWindow, InvisCursor );\r
177                                         else\r
178                                                 XUndefineCursor( Device->XDisplay, Device->XWindow );\r
179                                 }\r
180 #endif\r
181                         }\r
182 \r
183                         //! Returns if the cursor is currently visible.\r
184                         virtual bool isVisible() const _IRR_OVERRIDE_\r
185                         {\r
186                                 return IsVisible;\r
187                         }\r
188 \r
189                         //! Sets the new position of the cursor.\r
190                         virtual void setPosition(const core::position2d<f32> &pos) _IRR_OVERRIDE_\r
191                         {\r
192                                 setPosition(pos.X, pos.Y);\r
193                         }\r
194 \r
195                         //! Sets the new position of the cursor.\r
196                         virtual void setPosition(f32 x, f32 y) _IRR_OVERRIDE_\r
197                         {\r
198                                 setPosition((s32)(x*Device->Width), (s32)(y*Device->Height));\r
199                         }\r
200 \r
201                         //! Sets the new position of the cursor.\r
202                         virtual void setPosition(const core::position2d<s32> &pos) _IRR_OVERRIDE_\r
203                         {\r
204                                 setPosition(pos.X, pos.Y);\r
205                         }\r
206 \r
207                         //! Sets the new position of the cursor.\r
208                         virtual void setPosition(s32 x, s32 y) _IRR_OVERRIDE_\r
209                         {\r
210 #ifdef _IRR_COMPILE_WITH_X11_\r
211 \r
212                                 if (!Null)\r
213                                 {\r
214                                         if (UseReferenceRect)\r
215                                         {\r
216                                                 XWarpPointer(Device->XDisplay,\r
217                                                         None,\r
218                                                         Device->XWindow, 0, 0,\r
219                                                         Device->Width,\r
220                                                         Device->Height,\r
221                                                         ReferenceRect.UpperLeftCorner.X + x,\r
222                                                         ReferenceRect.UpperLeftCorner.Y + y);\r
223 \r
224                                         }\r
225                                         else\r
226                                         {\r
227                                                 XWarpPointer(Device->XDisplay,\r
228                                                         None,\r
229                                                         Device->XWindow, 0, 0,\r
230                                                         Device->Width,\r
231                                                         Device->Height, x, y);\r
232                                         }\r
233                                         XFlush(Device->XDisplay);\r
234                                 }\r
235 #endif\r
236                                 CursorPos.X = x;\r
237                                 CursorPos.Y = y;\r
238                         }\r
239 \r
240                         //! Returns the current position of the mouse cursor.\r
241                         virtual const core::position2d<s32>& getPosition(bool updateCursor) _IRR_OVERRIDE_\r
242                         {\r
243                                 if ( updateCursor )\r
244                                         updateCursorPos();\r
245                                 return CursorPos;\r
246                         }\r
247 \r
248                         //! Returns the current position of the mouse cursor.\r
249                         virtual core::position2d<f32> getRelativePosition(bool updateCursor) _IRR_OVERRIDE_\r
250                         {\r
251                                 if ( updateCursor )\r
252                                         updateCursorPos();\r
253 \r
254                                 if (!UseReferenceRect)\r
255                                 {\r
256                                         return core::position2d<f32>(CursorPos.X / (f32)Device->Width,\r
257                                                 CursorPos.Y / (f32)Device->Height);\r
258                                 }\r
259 \r
260                                 return core::position2d<f32>(CursorPos.X / (f32)ReferenceRect.getWidth(),\r
261                                                 CursorPos.Y / (f32)ReferenceRect.getHeight());\r
262                         }\r
263 \r
264                         virtual void setReferenceRect(core::rect<s32>* rect=0) _IRR_OVERRIDE_\r
265                         {\r
266                                 if (rect)\r
267                                 {\r
268                                         ReferenceRect = *rect;\r
269                                         UseReferenceRect = true;\r
270 \r
271                                         // prevent division through zero and uneven sizes\r
272 \r
273                                         if (!ReferenceRect.getHeight() || ReferenceRect.getHeight()%2)\r
274                                                 ReferenceRect.LowerRightCorner.Y += 1;\r
275 \r
276                                         if (!ReferenceRect.getWidth() || ReferenceRect.getWidth()%2)\r
277                                                 ReferenceRect.LowerRightCorner.X += 1;\r
278                                 }\r
279                                 else\r
280                                         UseReferenceRect = false;\r
281                         }\r
282 \r
283                         //! Sets the active cursor icon\r
284                         virtual void setActiveIcon(gui::ECURSOR_ICON iconId) _IRR_OVERRIDE_;\r
285 \r
286                         //! Gets the currently active icon\r
287                         virtual gui::ECURSOR_ICON getActiveIcon() const _IRR_OVERRIDE_\r
288                         {\r
289                                 return ActiveIcon;\r
290                         }\r
291 \r
292                         //! Add a custom sprite as cursor icon.\r
293                         virtual gui::ECURSOR_ICON addIcon(const gui::SCursorSprite& icon) _IRR_OVERRIDE_;\r
294 \r
295                         //! replace the given cursor icon.\r
296                         virtual void changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite& icon) _IRR_OVERRIDE_;\r
297 \r
298                         //! Return a system-specific size which is supported for cursors. Larger icons will fail, smaller icons might work.\r
299                         virtual core::dimension2di getSupportedIconSize() const _IRR_OVERRIDE_;\r
300 \r
301 #ifdef _IRR_COMPILE_WITH_X11_\r
302                         //! Set platform specific behavior flags.\r
303                         virtual void setPlatformBehavior(gui::ECURSOR_PLATFORM_BEHAVIOR behavior) _IRR_OVERRIDE_ {PlatformBehavior = behavior; }\r
304 \r
305                         //! Return platform specific behavior.\r
306                         virtual gui::ECURSOR_PLATFORM_BEHAVIOR getPlatformBehavior() const _IRR_OVERRIDE_ { return PlatformBehavior; }\r
307 \r
308                         void update();\r
309                         void clearCursors();\r
310 #endif\r
311                 private:\r
312 \r
313                         void updateCursorPos()\r
314                         {\r
315 #ifdef _IRR_COMPILE_WITH_X11_\r
316                                 if (Null)\r
317                                         return;\r
318 \r
319                                 if ( PlatformBehavior&gui::ECPB_X11_CACHE_UPDATES && !os::Timer::isStopped() )\r
320                                 {\r
321                                         u32 now = os::Timer::getTime();\r
322                                         if (now <= LastQuery)\r
323                                                 return;\r
324                                         LastQuery = now;\r
325                                 }\r
326 \r
327                                 Window tmp;\r
328                                 int itmp1, itmp2;\r
329                                 unsigned  int maskreturn;\r
330                                 XQueryPointer(Device->XDisplay, Device->XWindow,\r
331                                         &tmp, &tmp,\r
332                                         &itmp1, &itmp2,\r
333                                         &CursorPos.X, &CursorPos.Y, &maskreturn);\r
334 #endif\r
335                         }\r
336 \r
337                         CIrrDeviceLinux* Device;\r
338                         core::position2d<s32> CursorPos;\r
339                         core::rect<s32> ReferenceRect;\r
340 #ifdef _IRR_COMPILE_WITH_X11_\r
341                         gui::ECURSOR_PLATFORM_BEHAVIOR PlatformBehavior;\r
342                         u32 LastQuery;\r
343                         Cursor InvisCursor;\r
344 \r
345                         struct CursorFrameX11\r
346                         {\r
347                                 CursorFrameX11() : IconHW(0) {}\r
348                                 CursorFrameX11(Cursor icon) : IconHW(icon) {}\r
349 \r
350                                 Cursor IconHW;  // hardware cursor\r
351                         };\r
352 \r
353                         struct CursorX11\r
354                         {\r
355                                 CursorX11() {}\r
356                                 explicit CursorX11(Cursor iconHw, u32 frameTime=0) : FrameTime(frameTime)\r
357                                 {\r
358                                         Frames.push_back( CursorFrameX11(iconHw) );\r
359                                 }\r
360                                 core::array<CursorFrameX11> Frames;\r
361                                 u32 FrameTime;\r
362                         };\r
363 \r
364                         core::array<CursorX11> Cursors;\r
365 \r
366                         void initCursors();\r
367 #endif\r
368                         bool IsVisible;\r
369                         bool Null;\r
370                         bool UseReferenceRect;\r
371                         gui::ECURSOR_ICON ActiveIcon;\r
372                         u32 ActiveIconStartTime;\r
373                 };\r
374 \r
375                 friend class CCursorControl;\r
376 \r
377 #ifdef _IRR_COMPILE_WITH_X11_\r
378                 friend class COpenGLDriver;\r
379 \r
380                 Display *XDisplay;\r
381                 XVisualInfo* VisualInfo;\r
382                 int Screennr;\r
383                 Window XWindow;\r
384                 XSetWindowAttributes WndAttributes;\r
385                 XSizeHints* StdHints;\r
386                 XImage* SoftwareImage;\r
387                 XIM XInputMethod;\r
388                 XIC XInputContext;\r
389                 bool HasNetWM;\r
390                 mutable core::stringc Clipboard;\r
391                 #ifdef _IRR_LINUX_X11_VIDMODE_\r
392                 XF86VidModeModeInfo OldVideoMode;\r
393                 #endif\r
394                 #ifdef _IRR_LINUX_X11_RANDR_\r
395                 SizeID OldRandrMode;\r
396                 Rotation OldRandrRotation;\r
397                 #endif\r
398 #endif\r
399                 u32 Width, Height;\r
400                 bool WindowHasFocus;\r
401                 bool WindowMinimized;\r
402                 bool UseXVidMode;\r
403                 bool UseXRandR;\r
404                 bool ExternalWindow;\r
405                 int AutorepeatSupport;\r
406 \r
407                 struct SKeyMap\r
408                 {\r
409                         SKeyMap() {}\r
410                         SKeyMap(s32 x11, s32 win32)\r
411                                 : X11Key(x11), Win32Key(win32)\r
412                         {\r
413                         }\r
414 \r
415                         KeySym X11Key;\r
416                         s32 Win32Key;\r
417 \r
418                         bool operator<(const SKeyMap& o) const\r
419                         {\r
420                                 return X11Key<o.X11Key;\r
421                         }\r
422                 };\r
423 \r
424                 core::array<SKeyMap> KeyMap;\r
425 \r
426 #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)\r
427                 struct JoystickInfo\r
428                 {\r
429                         int     fd;\r
430                         int     axes;\r
431                         int     buttons;\r
432 \r
433                         SEvent persistentData;\r
434 \r
435                         JoystickInfo() : fd(-1), axes(0), buttons(0) { }\r
436                 };\r
437                 core::array<JoystickInfo> ActiveJoysticks;\r
438 #endif\r
439         };\r
440 \r
441 \r
442 } // end namespace irr\r
443 \r
444 #endif // _IRR_COMPILE_WITH_X11_DEVICE_\r
445 #endif // __C_IRR_DEVICE_LINUX_H_INCLUDED__\r
446 \r