aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CIrrDeviceLinux.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CIrrDeviceLinux.cpp')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CIrrDeviceLinux.cpp4592
1 files changed, 2296 insertions, 2296 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CIrrDeviceLinux.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CIrrDeviceLinux.cpp
index 6339b6a..a97c9d3 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/CIrrDeviceLinux.cpp
+++ b/libraries/irrlicht-1.8/source/Irrlicht/CIrrDeviceLinux.cpp
@@ -1,2298 +1,2298 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt 1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine". 2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h 3// For conditions of distribution and use, see copyright notice in irrlicht.h
4 4
5#include "CIrrDeviceLinux.h" 5#include "CIrrDeviceLinux.h"
6 6
7#ifdef _IRR_COMPILE_WITH_X11_DEVICE_ 7#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
8 8
9#include <stdio.h> 9#include <stdio.h>
10#include <stdlib.h> 10#include <stdlib.h>
11#include <sys/utsname.h> 11#include <sys/utsname.h>
12#include <time.h> 12#include <time.h>
13#include "IEventReceiver.h" 13#include "IEventReceiver.h"
14#include "ISceneManager.h" 14#include "ISceneManager.h"
15#include "IGUIEnvironment.h" 15#include "IGUIEnvironment.h"
16#include "os.h" 16#include "os.h"
17#include "CTimer.h" 17#include "CTimer.h"
18#include "irrString.h" 18#include "irrString.h"
19#include "Keycodes.h" 19#include "Keycodes.h"
20#include "COSOperator.h" 20#include "COSOperator.h"
21#include "CColorConverter.h" 21#include "CColorConverter.h"
22#include "SIrrCreationParameters.h" 22#include "SIrrCreationParameters.h"
23#include "IGUISpriteBank.h" 23#include "IGUISpriteBank.h"
24#include <X11/XKBlib.h> 24#include <X11/XKBlib.h>
25#include <X11/Xatom.h> 25#include <X11/Xatom.h>
26 26
27#ifdef _IRR_LINUX_XCURSOR_ 27#ifdef _IRR_LINUX_XCURSOR_
28#include <X11/Xcursor/Xcursor.h> 28#include <X11/Xcursor/Xcursor.h>
29#endif 29#endif
30 30
31#if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ 31#if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
32#include <fcntl.h> 32#include <fcntl.h>
33#include <unistd.h> 33#include <unistd.h>
34 34
35#ifdef __FREE_BSD_ 35#ifdef __FREE_BSD_
36#include <sys/joystick.h> 36#include <sys/joystick.h>
37#else 37#else
38 38
39// linux/joystick.h includes linux/input.h, which #defines values for various KEY_FOO keys. 39// linux/joystick.h includes linux/input.h, which #defines values for various KEY_FOO keys.
40// These override the irr::KEY_FOO equivalents, which stops key handling from working. 40// These override the irr::KEY_FOO equivalents, which stops key handling from working.
41// As a workaround, defining _INPUT_H stops linux/input.h from being included; it 41// As a workaround, defining _INPUT_H stops linux/input.h from being included; it
42// doesn't actually seem to be necessary except to pull in sys/ioctl.h. 42// doesn't actually seem to be necessary except to pull in sys/ioctl.h.
43#define _INPUT_H 43#define _INPUT_H
44#include <sys/ioctl.h> // Would normally be included in linux/input.h 44#include <sys/ioctl.h> // Would normally be included in linux/input.h
45#include <linux/joystick.h> 45#include <linux/joystick.h>
46#undef _INPUT_H 46#undef _INPUT_H
47#endif 47#endif
48 48
49#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ 49#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
50 50
51namespace irr 51namespace irr
52{ 52{
53 namespace video 53 namespace video
54 { 54 {
55 IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params, 55 IVideoDriver* createOpenGLDriver(const SIrrlichtCreationParameters& params,
56 io::IFileSystem* io, CIrrDeviceLinux* device); 56 io::IFileSystem* io, CIrrDeviceLinux* device);
57 } 57 }
58} // end namespace irr 58} // end namespace irr
59 59
60namespace 60namespace
61{ 61{
62 Atom X_ATOM_CLIPBOARD; 62 Atom X_ATOM_CLIPBOARD;
63 Atom X_ATOM_TARGETS; 63 Atom X_ATOM_TARGETS;
64 Atom X_ATOM_UTF8_STRING; 64 Atom X_ATOM_UTF8_STRING;
65 Atom X_ATOM_TEXT; 65 Atom X_ATOM_TEXT;
66}; 66};
67 67
68namespace irr 68namespace irr
69{ 69{
70 70
71const char* wmDeleteWindow = "WM_DELETE_WINDOW"; 71const char* wmDeleteWindow = "WM_DELETE_WINDOW";
72 72
73//! constructor 73//! constructor
74CIrrDeviceLinux::CIrrDeviceLinux(const SIrrlichtCreationParameters& param) 74CIrrDeviceLinux::CIrrDeviceLinux(const SIrrlichtCreationParameters& param)
75 : CIrrDeviceStub(param), 75 : CIrrDeviceStub(param),
76#ifdef _IRR_COMPILE_WITH_X11_ 76#ifdef _IRR_COMPILE_WITH_X11_
77 display(0), visual(0), screennr(0), window(0), StdHints(0), SoftwareImage(0), 77 display(0), visual(0), screennr(0), window(0), StdHints(0), SoftwareImage(0),
78#ifdef _IRR_COMPILE_WITH_OPENGL_ 78#ifdef _IRR_COMPILE_WITH_OPENGL_
79 glxWin(0), 79 glxWin(0),
80 Context(0), 80 Context(0),
81#endif 81#endif
82#endif 82#endif
83 Width(param.WindowSize.Width), Height(param.WindowSize.Height), 83 Width(param.WindowSize.Width), Height(param.WindowSize.Height),
84 WindowHasFocus(false), WindowMinimized(false), 84 WindowHasFocus(false), WindowMinimized(false),
85 UseXVidMode(false), UseXRandR(false), UseGLXWindow(false), 85 UseXVidMode(false), UseXRandR(false), UseGLXWindow(false),
86 ExternalWindow(false), AutorepeatSupport(0) 86 ExternalWindow(false), AutorepeatSupport(0)
87{ 87{
88 #ifdef _DEBUG 88 #ifdef _DEBUG
89 setDebugName("CIrrDeviceLinux"); 89 setDebugName("CIrrDeviceLinux");
90 #endif 90 #endif
91 91
92 // print version, distribution etc. 92 // print version, distribution etc.
93 // thx to LynxLuna for pointing me to the uname function 93 // thx to LynxLuna for pointing me to the uname function
94 core::stringc linuxversion; 94 core::stringc linuxversion;
95 struct utsname LinuxInfo; 95 struct utsname LinuxInfo;
96 uname(&LinuxInfo); 96 uname(&LinuxInfo);
97 97
98 linuxversion += LinuxInfo.sysname; 98 linuxversion += LinuxInfo.sysname;
99 linuxversion += " "; 99 linuxversion += " ";
100 linuxversion += LinuxInfo.release; 100 linuxversion += LinuxInfo.release;
101 linuxversion += " "; 101 linuxversion += " ";
102 linuxversion += LinuxInfo.version; 102 linuxversion += LinuxInfo.version;
103 linuxversion += " "; 103 linuxversion += " ";
104 linuxversion += LinuxInfo.machine; 104 linuxversion += LinuxInfo.machine;
105 105
106 Operator = new COSOperator(linuxversion, this); 106 Operator = new COSOperator(linuxversion, this);
107 os::Printer::log(linuxversion.c_str(), ELL_INFORMATION); 107 os::Printer::log(linuxversion.c_str(), ELL_INFORMATION);
108 108
109 // create keymap 109 // create keymap
110 createKeyMap(); 110 createKeyMap();
111 111
112 // create window 112 // create window
113 if (CreationParams.DriverType != video::EDT_NULL) 113 if (CreationParams.DriverType != video::EDT_NULL)
114 { 114 {
115 // create the window, only if we do not use the null device 115 // create the window, only if we do not use the null device
116 if (!createWindow()) 116 if (!createWindow())
117 return; 117 return;
118 } 118 }
119 119
120 // create cursor control 120 // create cursor control
121 CursorControl = new CCursorControl(this, CreationParams.DriverType == video::EDT_NULL); 121 CursorControl = new CCursorControl(this, CreationParams.DriverType == video::EDT_NULL);
122 122
123 // create driver 123 // create driver
124 createDriver(); 124 createDriver();
125 125
126 if (!VideoDriver) 126 if (!VideoDriver)
127 return; 127 return;
128 128
129 createGUIAndScene(); 129 createGUIAndScene();
130} 130}
131 131
132 132
133//! destructor 133//! destructor
134CIrrDeviceLinux::~CIrrDeviceLinux() 134CIrrDeviceLinux::~CIrrDeviceLinux()
135{ 135{
136#ifdef _IRR_COMPILE_WITH_X11_ 136#ifdef _IRR_COMPILE_WITH_X11_
137 if (StdHints) 137 if (StdHints)
138 XFree(StdHints); 138 XFree(StdHints);
139 // Disable cursor (it is drop'ed in stub) 139 // Disable cursor (it is drop'ed in stub)
140 if (CursorControl) 140 if (CursorControl)
141 { 141 {
142 CursorControl->setVisible(false); 142 CursorControl->setVisible(false);
143 static_cast<CCursorControl*>(CursorControl)->clearCursors(); 143 static_cast<CCursorControl*>(CursorControl)->clearCursors();
144 } 144 }
145 145
146 // Must free OpenGL textures etc before destroying context, so can't wait for stub destructor 146 // Must free OpenGL textures etc before destroying context, so can't wait for stub destructor
147 if ( GUIEnvironment ) 147 if ( GUIEnvironment )
148 { 148 {
149 GUIEnvironment->drop(); 149 GUIEnvironment->drop();
150 GUIEnvironment = NULL; 150 GUIEnvironment = NULL;
151 } 151 }
152 if ( SceneManager ) 152 if ( SceneManager )
153 { 153 {
154 SceneManager->drop(); 154 SceneManager->drop();
155 SceneManager = NULL; 155 SceneManager = NULL;
156 } 156 }
157 if ( VideoDriver ) 157 if ( VideoDriver )
158 { 158 {
159 VideoDriver->drop(); 159 VideoDriver->drop();
160 VideoDriver = NULL; 160 VideoDriver = NULL;
161 } 161 }
162 162
163 if (display) 163 if (display)
164 { 164 {
165 #ifdef _IRR_COMPILE_WITH_OPENGL_ 165 #ifdef _IRR_COMPILE_WITH_OPENGL_
166 if (Context) 166 if (Context)
167 { 167 {
168 if (glxWin) 168 if (glxWin)
169 { 169 {
170 if (!glXMakeContextCurrent(display, None, None, NULL)) 170 if (!glXMakeContextCurrent(display, None, None, NULL))
171 os::Printer::log("Could not release glx context.", ELL_WARNING); 171 os::Printer::log("Could not release glx context.", ELL_WARNING);
172 } 172 }
173 else 173 else
174 { 174 {
175 if (!glXMakeCurrent(display, None, NULL)) 175 if (!glXMakeCurrent(display, None, NULL))
176 os::Printer::log("Could not release glx context.", ELL_WARNING); 176 os::Printer::log("Could not release glx context.", ELL_WARNING);
177 } 177 }
178 glXDestroyContext(display, Context); 178 glXDestroyContext(display, Context);
179 if (glxWin) 179 if (glxWin)
180 glXDestroyWindow(display, glxWin); 180 glXDestroyWindow(display, glxWin);
181 } 181 }
182 #endif // #ifdef _IRR_COMPILE_WITH_OPENGL_ 182 #endif // #ifdef _IRR_COMPILE_WITH_OPENGL_
183 183
184 // Reset fullscreen resolution change 184 // Reset fullscreen resolution change
185 switchToFullscreen(true); 185 switchToFullscreen(true);
186 186
187 if (SoftwareImage) 187 if (SoftwareImage)
188 XDestroyImage(SoftwareImage); 188 XDestroyImage(SoftwareImage);
189 189
190 if (!ExternalWindow) 190 if (!ExternalWindow)
191 { 191 {
192 XDestroyWindow(display,window); 192 XDestroyWindow(display,window);
193 XCloseDisplay(display); 193 XCloseDisplay(display);
194 } 194 }
195 } 195 }
196 if (visual) 196 if (visual)
197 XFree(visual); 197 XFree(visual);
198 198
199#endif // #ifdef _IRR_COMPILE_WITH_X11_ 199#endif // #ifdef _IRR_COMPILE_WITH_X11_
200 200
201#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) 201#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
202 for (u32 joystick = 0; joystick < ActiveJoysticks.size(); ++joystick) 202 for (u32 joystick = 0; joystick < ActiveJoysticks.size(); ++joystick)
203 { 203 {
204 if (ActiveJoysticks[joystick].fd >= 0) 204 if (ActiveJoysticks[joystick].fd >= 0)
205 { 205 {
206 close(ActiveJoysticks[joystick].fd); 206 close(ActiveJoysticks[joystick].fd);
207 } 207 }
208 } 208 }
209#endif 209#endif
210} 210}
211 211
212 212
213#if defined(_IRR_COMPILE_WITH_X11_) && defined(_DEBUG) 213#if defined(_IRR_COMPILE_WITH_X11_) && defined(_DEBUG)
214int IrrPrintXError(Display *display, XErrorEvent *event) 214int IrrPrintXError(Display *display, XErrorEvent *event)
215{ 215{
216 char msg[256]; 216 char msg[256];
217 char msg2[256]; 217 char msg2[256];
218 218
219 snprintf(msg, 256, "%d", event->request_code); 219 snprintf(msg, 256, "%d", event->request_code);
220 XGetErrorDatabaseText(display, "XRequest", msg, "unknown", msg2, 256); 220 XGetErrorDatabaseText(display, "XRequest", msg, "unknown", msg2, 256);
221 XGetErrorText(display, event->error_code, msg, 256); 221 XGetErrorText(display, event->error_code, msg, 256);
222 os::Printer::log("X Error", msg, ELL_WARNING); 222 os::Printer::log("X Error", msg, ELL_WARNING);
223 os::Printer::log("From call ", msg2, ELL_WARNING); 223 os::Printer::log("From call ", msg2, ELL_WARNING);
224 return 0; 224 return 0;
225} 225}
226#endif 226#endif
227 227
228 228
229bool CIrrDeviceLinux::switchToFullscreen(bool reset) 229bool CIrrDeviceLinux::switchToFullscreen(bool reset)
230{ 230{
231 if (!CreationParams.Fullscreen) 231 if (!CreationParams.Fullscreen)
232 return true; 232 return true;
233 if (reset) 233 if (reset)
234 { 234 {
235#ifdef _IRR_LINUX_X11_VIDMODE_ 235#ifdef _IRR_LINUX_X11_VIDMODE_
236 if (UseXVidMode && CreationParams.Fullscreen) 236 if (UseXVidMode && CreationParams.Fullscreen)
237 { 237 {
238 XF86VidModeSwitchToMode(display, screennr, &oldVideoMode); 238 XF86VidModeSwitchToMode(display, screennr, &oldVideoMode);
239 XF86VidModeSetViewPort(display, screennr, 0, 0); 239 XF86VidModeSetViewPort(display, screennr, 0, 0);
240 } 240 }
241 #endif 241 #endif
242 #ifdef _IRR_LINUX_X11_RANDR_ 242 #ifdef _IRR_LINUX_X11_RANDR_
243 if (UseXRandR && CreationParams.Fullscreen) 243 if (UseXRandR && CreationParams.Fullscreen)
244 { 244 {
245 XRRScreenConfiguration *config=XRRGetScreenInfo(display,DefaultRootWindow(display)); 245 XRRScreenConfiguration *config=XRRGetScreenInfo(display,DefaultRootWindow(display));
246 XRRSetScreenConfig(display,config,DefaultRootWindow(display),oldRandrMode,oldRandrRotation,CurrentTime); 246 XRRSetScreenConfig(display,config,DefaultRootWindow(display),oldRandrMode,oldRandrRotation,CurrentTime);
247 XRRFreeScreenConfigInfo(config); 247 XRRFreeScreenConfigInfo(config);
248 } 248 }
249 #endif 249 #endif
250 return true; 250 return true;
251 } 251 }
252 252
253 getVideoModeList(); 253 getVideoModeList();
254 #if defined(_IRR_LINUX_X11_VIDMODE_) || defined(_IRR_LINUX_X11_RANDR_) 254 #if defined(_IRR_LINUX_X11_VIDMODE_) || defined(_IRR_LINUX_X11_RANDR_)
255 s32 eventbase, errorbase; 255 s32 eventbase, errorbase;
256 s32 bestMode = -1; 256 s32 bestMode = -1;
257 #endif 257 #endif
258 258
259 #ifdef _IRR_LINUX_X11_VIDMODE_ 259 #ifdef _IRR_LINUX_X11_VIDMODE_
260 if (XF86VidModeQueryExtension(display, &eventbase, &errorbase)) 260 if (XF86VidModeQueryExtension(display, &eventbase, &errorbase))
261 { 261 {
262 // enumerate video modes 262 // enumerate video modes
263 s32 modeCount; 263 s32 modeCount;
264 XF86VidModeModeInfo** modes; 264 XF86VidModeModeInfo** modes;
265 265
266 XF86VidModeGetAllModeLines(display, screennr, &modeCount, &modes); 266 XF86VidModeGetAllModeLines(display, screennr, &modeCount, &modes);
267 267
268 // find fitting mode 268 // find fitting mode
269 for (s32 i = 0; i<modeCount; ++i) 269 for (s32 i = 0; i<modeCount; ++i)
270 { 270 {
271 if (bestMode==-1 && modes[i]->hdisplay >= Width && modes[i]->vdisplay >= Height) 271 if (bestMode==-1 && modes[i]->hdisplay >= Width && modes[i]->vdisplay >= Height)
272 bestMode = i; 272 bestMode = i;
273 else if (bestMode!=-1 && 273 else if (bestMode!=-1 &&
274 modes[i]->hdisplay >= Width && 274 modes[i]->hdisplay >= Width &&
275 modes[i]->vdisplay >= Height && 275 modes[i]->vdisplay >= Height &&
276 modes[i]->hdisplay <= modes[bestMode]->hdisplay && 276 modes[i]->hdisplay <= modes[bestMode]->hdisplay &&
277 modes[i]->vdisplay <= modes[bestMode]->vdisplay) 277 modes[i]->vdisplay <= modes[bestMode]->vdisplay)
278 bestMode = i; 278 bestMode = i;
279 } 279 }
280 if (bestMode != -1) 280 if (bestMode != -1)
281 { 281 {
282 os::Printer::log("Starting vidmode fullscreen mode...", ELL_INFORMATION); 282 os::Printer::log("Starting vidmode fullscreen mode...", ELL_INFORMATION);
283 os::Printer::log("hdisplay: ", core::stringc(modes[bestMode]->hdisplay).c_str(), ELL_INFORMATION); 283 os::Printer::log("hdisplay: ", core::stringc(modes[bestMode]->hdisplay).c_str(), ELL_INFORMATION);
284 os::Printer::log("vdisplay: ", core::stringc(modes[bestMode]->vdisplay).c_str(), ELL_INFORMATION); 284 os::Printer::log("vdisplay: ", core::stringc(modes[bestMode]->vdisplay).c_str(), ELL_INFORMATION);
285 285
286 XF86VidModeSwitchToMode(display, screennr, modes[bestMode]); 286 XF86VidModeSwitchToMode(display, screennr, modes[bestMode]);
287 XF86VidModeSetViewPort(display, screennr, 0, 0); 287 XF86VidModeSetViewPort(display, screennr, 0, 0);
288 UseXVidMode=true; 288 UseXVidMode=true;
289 } 289 }
290 else 290 else
291 { 291 {
292 os::Printer::log("Could not find specified video mode, running windowed.", ELL_WARNING); 292 os::Printer::log("Could not find specified video mode, running windowed.", ELL_WARNING);
293 CreationParams.Fullscreen = false; 293 CreationParams.Fullscreen = false;
294 } 294 }
295 295
296 XFree(modes); 296 XFree(modes);
297 } 297 }
298 else 298 else
299 #endif 299 #endif
300 #ifdef _IRR_LINUX_X11_RANDR_ 300 #ifdef _IRR_LINUX_X11_RANDR_
301 if (XRRQueryExtension(display, &eventbase, &errorbase)) 301 if (XRRQueryExtension(display, &eventbase, &errorbase))
302 { 302 {
303 s32 modeCount; 303 s32 modeCount;
304 XRRScreenConfiguration *config=XRRGetScreenInfo(display,DefaultRootWindow(display)); 304 XRRScreenConfiguration *config=XRRGetScreenInfo(display,DefaultRootWindow(display));
305 XRRScreenSize *modes=XRRConfigSizes(config,&modeCount); 305 XRRScreenSize *modes=XRRConfigSizes(config,&modeCount);
306 for (s32 i = 0; i<modeCount; ++i) 306 for (s32 i = 0; i<modeCount; ++i)
307 { 307 {
308 if (bestMode==-1 && (u32)modes[i].width >= Width && (u32)modes[i].height >= Height) 308 if (bestMode==-1 && (u32)modes[i].width >= Width && (u32)modes[i].height >= Height)
309 bestMode = i; 309 bestMode = i;
310 else if (bestMode!=-1 && 310 else if (bestMode!=-1 &&
311 (u32)modes[i].width >= Width && 311 (u32)modes[i].width >= Width &&
312 (u32)modes[i].height >= Height && 312 (u32)modes[i].height >= Height &&
313 modes[i].width <= modes[bestMode].width && 313 modes[i].width <= modes[bestMode].width &&
314 modes[i].height <= modes[bestMode].height) 314 modes[i].height <= modes[bestMode].height)
315 bestMode = i; 315 bestMode = i;
316 } 316 }
317 if (bestMode != -1) 317 if (bestMode != -1)
318 { 318 {
319 os::Printer::log("Starting randr fullscreen mode...", ELL_INFORMATION); 319 os::Printer::log("Starting randr fullscreen mode...", ELL_INFORMATION);
320 os::Printer::log("width: ", core::stringc(modes[bestMode].width).c_str(), ELL_INFORMATION); 320 os::Printer::log("width: ", core::stringc(modes[bestMode].width).c_str(), ELL_INFORMATION);
321 os::Printer::log("height: ", core::stringc(modes[bestMode].height).c_str(), ELL_INFORMATION); 321 os::Printer::log("height: ", core::stringc(modes[bestMode].height).c_str(), ELL_INFORMATION);
322 322
323 XRRSetScreenConfig(display,config,DefaultRootWindow(display),bestMode,oldRandrRotation,CurrentTime); 323 XRRSetScreenConfig(display,config,DefaultRootWindow(display),bestMode,oldRandrRotation,CurrentTime);
324 UseXRandR=true; 324 UseXRandR=true;
325 } 325 }
326 XRRFreeScreenConfigInfo(config); 326 XRRFreeScreenConfigInfo(config);
327 } 327 }
328 else 328 else
329 #endif 329 #endif
330 { 330 {
331 os::Printer::log("VidMode or RandR extension must be installed to allow Irrlicht " 331 os::Printer::log("VidMode or RandR extension must be installed to allow Irrlicht "
332 "to switch to fullscreen mode. Running in windowed mode instead.", ELL_WARNING); 332 "to switch to fullscreen mode. Running in windowed mode instead.", ELL_WARNING);
333 CreationParams.Fullscreen = false; 333 CreationParams.Fullscreen = false;
334 } 334 }
335 return CreationParams.Fullscreen; 335 return CreationParams.Fullscreen;
336} 336}
337 337
338 338
339#if defined(_IRR_COMPILE_WITH_X11_) 339#if defined(_IRR_COMPILE_WITH_X11_)
340void IrrPrintXGrabError(int grabResult, const c8 * grabCommand ) 340void IrrPrintXGrabError(int grabResult, const c8 * grabCommand )
341{ 341{
342 if ( grabResult == GrabSuccess ) 342 if ( grabResult == GrabSuccess )
343 { 343 {
344// os::Printer::log(grabCommand, ": GrabSuccess", ELL_INFORMATION); 344// os::Printer::log(grabCommand, ": GrabSuccess", ELL_INFORMATION);
345 return; 345 return;
346 } 346 }
347 347
348 switch ( grabResult ) 348 switch ( grabResult )
349 { 349 {
350 case AlreadyGrabbed: 350 case AlreadyGrabbed:
351 os::Printer::log(grabCommand, ": AlreadyGrabbed", ELL_WARNING); 351 os::Printer::log(grabCommand, ": AlreadyGrabbed", ELL_WARNING);
352 break; 352 break;
353 case GrabNotViewable: 353 case GrabNotViewable:
354 os::Printer::log(grabCommand, ": GrabNotViewable", ELL_WARNING); 354 os::Printer::log(grabCommand, ": GrabNotViewable", ELL_WARNING);
355 break; 355 break;
356 case GrabFrozen: 356 case GrabFrozen:
357 os::Printer::log(grabCommand, ": GrabFrozen", ELL_WARNING); 357 os::Printer::log(grabCommand, ": GrabFrozen", ELL_WARNING);
358 break; 358 break;
359 case GrabInvalidTime: 359 case GrabInvalidTime:
360 os::Printer::log(grabCommand, ": GrabInvalidTime", ELL_WARNING); 360 os::Printer::log(grabCommand, ": GrabInvalidTime", ELL_WARNING);
361 break; 361 break;
362 default: 362 default:
363 os::Printer::log(grabCommand, ": grab failed with unknown problem", ELL_WARNING); 363 os::Printer::log(grabCommand, ": grab failed with unknown problem", ELL_WARNING);
364 break; 364 break;
365 } 365 }
366} 366}
367#endif 367#endif
368 368
369 369
370bool CIrrDeviceLinux::createWindow() 370bool CIrrDeviceLinux::createWindow()
371{ 371{
372#ifdef _IRR_COMPILE_WITH_X11_ 372#ifdef _IRR_COMPILE_WITH_X11_
373#ifdef _DEBUG 373#ifdef _DEBUG
374 os::Printer::log("Creating X window...", ELL_INFORMATION); 374 os::Printer::log("Creating X window...", ELL_INFORMATION);
375 XSetErrorHandler(IrrPrintXError); 375 XSetErrorHandler(IrrPrintXError);
376#endif 376#endif
377 377
378 if (CreationParams.VideoData) 378 if (CreationParams.VideoData)
379 display = (Display *) CreationParams.VideoData->OpenGLLinux.X11Display; 379 display = (Display *) CreationParams.VideoData->OpenGLLinux.X11Display;
380 if (!display) 380 if (!display)
381 display = XOpenDisplay(0); 381 display = XOpenDisplay(0);
382 if (!display) 382 if (!display)
383 { 383 {
384 os::Printer::log("Error: Need running XServer to start Irrlicht Engine.", ELL_ERROR); 384 os::Printer::log("Error: Need running XServer to start Irrlicht Engine.", ELL_ERROR);
385 if (XDisplayName(0)[0]) 385 if (XDisplayName(0)[0])
386 os::Printer::log("Could not open display", XDisplayName(0), ELL_ERROR); 386 os::Printer::log("Could not open display", XDisplayName(0), ELL_ERROR);
387 else 387 else
388 os::Printer::log("Could not open display, set DISPLAY variable", ELL_ERROR); 388 os::Printer::log("Could not open display, set DISPLAY variable", ELL_ERROR);
389 return false; 389 return false;
390 } 390 }
391 391
392 screennr = DefaultScreen(display); 392 screennr = DefaultScreen(display);
393 393
394 switchToFullscreen(); 394 switchToFullscreen();
395 395
396#ifdef _IRR_COMPILE_WITH_OPENGL_ 396#ifdef _IRR_COMPILE_WITH_OPENGL_
397 397
398 GLXFBConfig glxFBConfig; 398 GLXFBConfig glxFBConfig;
399 int major, minor; 399 int major, minor;
400 bool isAvailableGLX=false; 400 bool isAvailableGLX=false;
401 if (CreationParams.DriverType==video::EDT_OPENGL) 401 if (CreationParams.DriverType==video::EDT_OPENGL)
402 { 402 {
403 isAvailableGLX=glXQueryExtension(display,&major,&minor); 403 isAvailableGLX=glXQueryExtension(display,&major,&minor);
404 if (isAvailableGLX && glXQueryVersion(display, &major, &minor)) 404 if (isAvailableGLX && glXQueryVersion(display, &major, &minor))
405 { 405 {
406#ifdef GLX_VERSION_1_3 406#ifdef GLX_VERSION_1_3
407 typedef GLXFBConfig * ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements); 407 typedef GLXFBConfig * ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements);
408 408
409#ifdef _IRR_OPENGL_USE_EXTPOINTER_ 409#ifdef _IRR_OPENGL_USE_EXTPOINTER_
410 PFNGLXCHOOSEFBCONFIGPROC glxChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddress(reinterpret_cast<const GLubyte*>("glXChooseFBConfig")); 410 PFNGLXCHOOSEFBCONFIGPROC glxChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddress(reinterpret_cast<const GLubyte*>("glXChooseFBConfig"));
411#else 411#else
412 PFNGLXCHOOSEFBCONFIGPROC glxChooseFBConfig=glXChooseFBConfig; 412 PFNGLXCHOOSEFBCONFIGPROC glxChooseFBConfig=glXChooseFBConfig;
413#endif 413#endif
414 if (major==1 && minor>2 && glxChooseFBConfig) 414 if (major==1 && minor>2 && glxChooseFBConfig)
415 { 415 {
416 // attribute array for the draw buffer 416 // attribute array for the draw buffer
417 int visualAttrBuffer[] = 417 int visualAttrBuffer[] =
418 { 418 {
419 GLX_RENDER_TYPE, GLX_RGBA_BIT, 419 GLX_RENDER_TYPE, GLX_RGBA_BIT,
420 GLX_RED_SIZE, 4, 420 GLX_RED_SIZE, 4,
421 GLX_GREEN_SIZE, 4, 421 GLX_GREEN_SIZE, 4,
422 GLX_BLUE_SIZE, 4, 422 GLX_BLUE_SIZE, 4,
423 GLX_ALPHA_SIZE, CreationParams.WithAlphaChannel?1:0, 423 GLX_ALPHA_SIZE, CreationParams.WithAlphaChannel?1:0,
424 GLX_DEPTH_SIZE, CreationParams.ZBufferBits, //10,11 424 GLX_DEPTH_SIZE, CreationParams.ZBufferBits, //10,11
425 GLX_DOUBLEBUFFER, CreationParams.Doublebuffer?True:False, 425 GLX_DOUBLEBUFFER, CreationParams.Doublebuffer?True:False,
426 GLX_STENCIL_SIZE, CreationParams.Stencilbuffer?1:0, 426 GLX_STENCIL_SIZE, CreationParams.Stencilbuffer?1:0,
427#if defined(GLX_VERSION_1_4) && defined(GLX_SAMPLE_BUFFERS) // we need to check the extension string! 427#if defined(GLX_VERSION_1_4) && defined(GLX_SAMPLE_BUFFERS) // we need to check the extension string!
428 GLX_SAMPLE_BUFFERS, 1, 428 GLX_SAMPLE_BUFFERS, 1,
429 GLX_SAMPLES, CreationParams.AntiAlias, // 18,19 429 GLX_SAMPLES, CreationParams.AntiAlias, // 18,19
430#elif defined(GLX_ARB_multisample) 430#elif defined(GLX_ARB_multisample)
431 GLX_SAMPLE_BUFFERS_ARB, 1, 431 GLX_SAMPLE_BUFFERS_ARB, 1,
432 GLX_SAMPLES_ARB, CreationParams.AntiAlias, // 18,19 432 GLX_SAMPLES_ARB, CreationParams.AntiAlias, // 18,19
433#elif defined(GLX_SGIS_multisample) 433#elif defined(GLX_SGIS_multisample)
434 GLX_SAMPLE_BUFFERS_SGIS, 1, 434 GLX_SAMPLE_BUFFERS_SGIS, 1,
435 GLX_SAMPLES_SGIS, CreationParams.AntiAlias, // 18,19 435 GLX_SAMPLES_SGIS, CreationParams.AntiAlias, // 18,19
436#endif 436#endif
437//#ifdef GL_ARB_framebuffer_sRGB 437//#ifdef GL_ARB_framebuffer_sRGB
438// GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, CreationParams.HandleSRGB, 438// GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, CreationParams.HandleSRGB,
439//#elif defined(GL_EXT_framebuffer_sRGB) 439//#elif defined(GL_EXT_framebuffer_sRGB)
440// GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, CreationParams.HandleSRGB, 440// GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, CreationParams.HandleSRGB,
441//#endif 441//#endif
442 GLX_STEREO, CreationParams.Stereobuffer?True:False, 442 GLX_STEREO, CreationParams.Stereobuffer?True:False,
443 None 443 None
444 }; 444 };
445 445
446 GLXFBConfig *configList=0; 446 GLXFBConfig *configList=0;
447 int nitems=0; 447 int nitems=0;
448 if (CreationParams.AntiAlias<2) 448 if (CreationParams.AntiAlias<2)
449 { 449 {
450 visualAttrBuffer[17] = 0; 450 visualAttrBuffer[17] = 0;
451 visualAttrBuffer[19] = 0; 451 visualAttrBuffer[19] = 0;
452 } 452 }
453 // first round with unchanged values 453 // first round with unchanged values
454 { 454 {
455 configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); 455 configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
456 if (!configList && CreationParams.AntiAlias) 456 if (!configList && CreationParams.AntiAlias)
457 { 457 {
458 while (!configList && (visualAttrBuffer[19]>1)) 458 while (!configList && (visualAttrBuffer[19]>1))
459 { 459 {
460 visualAttrBuffer[19] -= 1; 460 visualAttrBuffer[19] -= 1;
461 configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); 461 configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
462 } 462 }
463 if (!configList) 463 if (!configList)
464 { 464 {
465 visualAttrBuffer[17] = 0; 465 visualAttrBuffer[17] = 0;
466 visualAttrBuffer[19] = 0; 466 visualAttrBuffer[19] = 0;
467 configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); 467 configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
468 if (configList) 468 if (configList)
469 { 469 {
470 os::Printer::log("No FSAA available.", ELL_WARNING); 470 os::Printer::log("No FSAA available.", ELL_WARNING);
471 CreationParams.AntiAlias=0; 471 CreationParams.AntiAlias=0;
472 } 472 }
473 else 473 else
474 { 474 {
475 //reenable multisampling 475 //reenable multisampling
476 visualAttrBuffer[17] = 1; 476 visualAttrBuffer[17] = 1;
477 visualAttrBuffer[19] = CreationParams.AntiAlias; 477 visualAttrBuffer[19] = CreationParams.AntiAlias;
478 } 478 }
479 } 479 }
480 } 480 }
481 } 481 }
482 // Next try with flipped stencil buffer value 482 // Next try with flipped stencil buffer value
483 // If the first round was with stencil flag it's now without 483 // If the first round was with stencil flag it's now without
484 // Other way round also makes sense because some configs 484 // Other way round also makes sense because some configs
485 // only have depth buffer combined with stencil buffer 485 // only have depth buffer combined with stencil buffer
486 if (!configList) 486 if (!configList)
487 { 487 {
488 if (CreationParams.Stencilbuffer) 488 if (CreationParams.Stencilbuffer)
489 os::Printer::log("No stencilbuffer available, disabling stencil shadows.", ELL_WARNING); 489 os::Printer::log("No stencilbuffer available, disabling stencil shadows.", ELL_WARNING);
490 CreationParams.Stencilbuffer = !CreationParams.Stencilbuffer; 490 CreationParams.Stencilbuffer = !CreationParams.Stencilbuffer;
491 visualAttrBuffer[15]=CreationParams.Stencilbuffer?1:0; 491 visualAttrBuffer[15]=CreationParams.Stencilbuffer?1:0;
492 492
493 configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); 493 configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
494 if (!configList && CreationParams.AntiAlias) 494 if (!configList && CreationParams.AntiAlias)
495 { 495 {
496 while (!configList && (visualAttrBuffer[19]>1)) 496 while (!configList && (visualAttrBuffer[19]>1))
497 { 497 {
498 visualAttrBuffer[19] -= 1; 498 visualAttrBuffer[19] -= 1;
499 configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); 499 configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
500 } 500 }
501 if (!configList) 501 if (!configList)
502 { 502 {
503 visualAttrBuffer[17] = 0; 503 visualAttrBuffer[17] = 0;
504 visualAttrBuffer[19] = 0; 504 visualAttrBuffer[19] = 0;
505 configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); 505 configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
506 if (configList) 506 if (configList)
507 { 507 {
508 os::Printer::log("No FSAA available.", ELL_WARNING); 508 os::Printer::log("No FSAA available.", ELL_WARNING);
509 CreationParams.AntiAlias=0; 509 CreationParams.AntiAlias=0;
510 } 510 }
511 else 511 else
512 { 512 {
513 //reenable multisampling 513 //reenable multisampling
514 visualAttrBuffer[17] = 1; 514 visualAttrBuffer[17] = 1;
515 visualAttrBuffer[19] = CreationParams.AntiAlias; 515 visualAttrBuffer[19] = CreationParams.AntiAlias;
516 } 516 }
517 } 517 }
518 } 518 }
519 } 519 }
520 // Next try without double buffer 520 // Next try without double buffer
521 if (!configList && CreationParams.Doublebuffer) 521 if (!configList && CreationParams.Doublebuffer)
522 { 522 {
523 os::Printer::log("No doublebuffering available.", ELL_WARNING); 523 os::Printer::log("No doublebuffering available.", ELL_WARNING);
524 CreationParams.Doublebuffer=false; 524 CreationParams.Doublebuffer=false;
525 visualAttrBuffer[13] = GLX_DONT_CARE; 525 visualAttrBuffer[13] = GLX_DONT_CARE;
526 CreationParams.Stencilbuffer = false; 526 CreationParams.Stencilbuffer = false;
527 visualAttrBuffer[15]=0; 527 visualAttrBuffer[15]=0;
528 configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); 528 configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
529 if (!configList && CreationParams.AntiAlias) 529 if (!configList && CreationParams.AntiAlias)
530 { 530 {
531 while (!configList && (visualAttrBuffer[19]>1)) 531 while (!configList && (visualAttrBuffer[19]>1))
532 { 532 {
533 visualAttrBuffer[19] -= 1; 533 visualAttrBuffer[19] -= 1;
534 configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); 534 configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
535 } 535 }
536 if (!configList) 536 if (!configList)
537 { 537 {
538 visualAttrBuffer[17] = 0; 538 visualAttrBuffer[17] = 0;
539 visualAttrBuffer[19] = 0; 539 visualAttrBuffer[19] = 0;
540 configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems); 540 configList=glxChooseFBConfig(display, screennr, visualAttrBuffer,&nitems);
541 if (configList) 541 if (configList)
542 { 542 {
543 os::Printer::log("No FSAA available.", ELL_WARNING); 543 os::Printer::log("No FSAA available.", ELL_WARNING);
544 CreationParams.AntiAlias=0; 544 CreationParams.AntiAlias=0;
545 } 545 }
546 else 546 else
547 { 547 {
548 //reenable multisampling 548 //reenable multisampling
549 visualAttrBuffer[17] = 1; 549 visualAttrBuffer[17] = 1;
550 visualAttrBuffer[19] = CreationParams.AntiAlias; 550 visualAttrBuffer[19] = CreationParams.AntiAlias;
551 } 551 }
552 } 552 }
553 } 553 }
554 } 554 }
555 if (configList) 555 if (configList)
556 { 556 {
557 glxFBConfig=configList[0]; 557 glxFBConfig=configList[0];
558 XFree(configList); 558 XFree(configList);
559 UseGLXWindow=true; 559 UseGLXWindow=true;
560#ifdef _IRR_OPENGL_USE_EXTPOINTER_ 560#ifdef _IRR_OPENGL_USE_EXTPOINTER_
561 typedef XVisualInfo * ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config); 561 typedef XVisualInfo * ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config);
562 PFNGLXGETVISUALFROMFBCONFIGPROC glxGetVisualFromFBConfig= (PFNGLXGETVISUALFROMFBCONFIGPROC)glXGetProcAddress(reinterpret_cast<const GLubyte*>("glXGetVisualFromFBConfig")); 562 PFNGLXGETVISUALFROMFBCONFIGPROC glxGetVisualFromFBConfig= (PFNGLXGETVISUALFROMFBCONFIGPROC)glXGetProcAddress(reinterpret_cast<const GLubyte*>("glXGetVisualFromFBConfig"));
563 if (glxGetVisualFromFBConfig) 563 if (glxGetVisualFromFBConfig)
564 visual = glxGetVisualFromFBConfig(display,glxFBConfig); 564 visual = glxGetVisualFromFBConfig(display,glxFBConfig);
565#else 565#else
566 visual = glXGetVisualFromFBConfig(display,glxFBConfig); 566 visual = glXGetVisualFromFBConfig(display,glxFBConfig);
567#endif 567#endif
568 } 568 }
569 } 569 }
570 else 570 else
571#endif 571#endif
572 { 572 {
573 // attribute array for the draw buffer 573 // attribute array for the draw buffer
574 int visualAttrBuffer[] = 574 int visualAttrBuffer[] =
575 { 575 {
576 GLX_RGBA, GLX_USE_GL, 576 GLX_RGBA, GLX_USE_GL,
577 GLX_RED_SIZE, 4, 577 GLX_RED_SIZE, 4,
578 GLX_GREEN_SIZE, 4, 578 GLX_GREEN_SIZE, 4,
579 GLX_BLUE_SIZE, 4, 579 GLX_BLUE_SIZE, 4,
580 GLX_ALPHA_SIZE, CreationParams.WithAlphaChannel?1:0, 580 GLX_ALPHA_SIZE, CreationParams.WithAlphaChannel?1:0,
581 GLX_DEPTH_SIZE, CreationParams.ZBufferBits, 581 GLX_DEPTH_SIZE, CreationParams.ZBufferBits,
582 GLX_STENCIL_SIZE, CreationParams.Stencilbuffer?1:0, // 12,13 582 GLX_STENCIL_SIZE, CreationParams.Stencilbuffer?1:0, // 12,13
583 // The following attributes have no flags, but are 583 // The following attributes have no flags, but are
584 // either present or not. As a no-op we use 584 // either present or not. As a no-op we use
585 // GLX_USE_GL, which is silently ignored by glXChooseVisual 585 // GLX_USE_GL, which is silently ignored by glXChooseVisual
586 CreationParams.Doublebuffer?GLX_DOUBLEBUFFER:GLX_USE_GL, // 14 586 CreationParams.Doublebuffer?GLX_DOUBLEBUFFER:GLX_USE_GL, // 14
587 CreationParams.Stereobuffer?GLX_STEREO:GLX_USE_GL, // 15 587 CreationParams.Stereobuffer?GLX_STEREO:GLX_USE_GL, // 15
588//#ifdef GL_ARB_framebuffer_sRGB 588//#ifdef GL_ARB_framebuffer_sRGB
589// CreationParams.HandleSRGB?GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB:GLX_USE_GL, 589// CreationParams.HandleSRGB?GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB:GLX_USE_GL,
590//#elif defined(GL_EXT_framebuffer_sRGB) 590//#elif defined(GL_EXT_framebuffer_sRGB)
591// CreationParams.HandleSRGB?GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT:GLX_USE_GL, 591// CreationParams.HandleSRGB?GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT:GLX_USE_GL,
592//#endif 592//#endif
593 None 593 None
594 }; 594 };
595 595
596 visual=glXChooseVisual(display, screennr, visualAttrBuffer); 596 visual=glXChooseVisual(display, screennr, visualAttrBuffer);
597 if (!visual) 597 if (!visual)
598 { 598 {
599 if (CreationParams.Stencilbuffer) 599 if (CreationParams.Stencilbuffer)
600 os::Printer::log("No stencilbuffer available, disabling.", ELL_WARNING); 600 os::Printer::log("No stencilbuffer available, disabling.", ELL_WARNING);
601 CreationParams.Stencilbuffer = !CreationParams.Stencilbuffer; 601 CreationParams.Stencilbuffer = !CreationParams.Stencilbuffer;
602 visualAttrBuffer[13]=CreationParams.Stencilbuffer?1:0; 602 visualAttrBuffer[13]=CreationParams.Stencilbuffer?1:0;
603 603
604 visual=glXChooseVisual(display, screennr, visualAttrBuffer); 604 visual=glXChooseVisual(display, screennr, visualAttrBuffer);
605 if (!visual && CreationParams.Doublebuffer) 605 if (!visual && CreationParams.Doublebuffer)
606 { 606 {
607 os::Printer::log("No doublebuffering available.", ELL_WARNING); 607 os::Printer::log("No doublebuffering available.", ELL_WARNING);
608 CreationParams.Doublebuffer=false; 608 CreationParams.Doublebuffer=false;
609 visualAttrBuffer[14] = GLX_USE_GL; 609 visualAttrBuffer[14] = GLX_USE_GL;
610 visual=glXChooseVisual(display, screennr, visualAttrBuffer); 610 visual=glXChooseVisual(display, screennr, visualAttrBuffer);
611 } 611 }
612 } 612 }
613 } 613 }
614 } 614 }
615 else 615 else
616 os::Printer::log("No GLX support available. OpenGL driver will not work.", ELL_WARNING); 616 os::Printer::log("No GLX support available. OpenGL driver will not work.", ELL_WARNING);
617 } 617 }
618 // don't use the XVisual with OpenGL, because it ignores all requested 618 // don't use the XVisual with OpenGL, because it ignores all requested
619 // properties of the CreationParams 619 // properties of the CreationParams
620 else if (!visual) 620 else if (!visual)
621#endif // _IRR_COMPILE_WITH_OPENGL_ 621#endif // _IRR_COMPILE_WITH_OPENGL_
622 622
623 // create visual with standard X methods 623 // create visual with standard X methods
624 { 624 {
625 os::Printer::log("Using plain X visual"); 625 os::Printer::log("Using plain X visual");
626 XVisualInfo visTempl; //Template to hold requested values 626 XVisualInfo visTempl; //Template to hold requested values
627 int visNumber; // Return value of available visuals 627 int visNumber; // Return value of available visuals
628 628
629 visTempl.screen = screennr; 629 visTempl.screen = screennr;
630 // ARGB visuals should be avoided for usual applications 630 // ARGB visuals should be avoided for usual applications
631 visTempl.depth = CreationParams.WithAlphaChannel?32:24; 631 visTempl.depth = CreationParams.WithAlphaChannel?32:24;
632 while ((!visual) && (visTempl.depth>=16)) 632 while ((!visual) && (visTempl.depth>=16))
633 { 633 {
634 visual = XGetVisualInfo(display, VisualScreenMask|VisualDepthMask, 634 visual = XGetVisualInfo(display, VisualScreenMask|VisualDepthMask,
635 &visTempl, &visNumber); 635 &visTempl, &visNumber);
636 visTempl.depth -= 8; 636 visTempl.depth -= 8;
637 } 637 }
638 } 638 }
639 639
640 if (!visual) 640 if (!visual)
641 { 641 {
642 os::Printer::log("Fatal error, could not get visual.", ELL_ERROR); 642 os::Printer::log("Fatal error, could not get visual.", ELL_ERROR);
643 XCloseDisplay(display); 643 XCloseDisplay(display);
644 display=0; 644 display=0;
645 return false; 645 return false;
646 } 646 }
647#ifdef _DEBUG 647#ifdef _DEBUG
648 else 648 else
649 os::Printer::log("Visual chosen: ", core::stringc(static_cast<u32>(visual->visualid)).c_str(), ELL_DEBUG); 649 os::Printer::log("Visual chosen: ", core::stringc(static_cast<u32>(visual->visualid)).c_str(), ELL_DEBUG);
650#endif 650#endif
651 651
652 // create color map 652 // create color map
653 Colormap colormap; 653 Colormap colormap;
654 colormap = XCreateColormap(display, 654 colormap = XCreateColormap(display,
655 RootWindow(display, visual->screen), 655 RootWindow(display, visual->screen),
656 visual->visual, AllocNone); 656 visual->visual, AllocNone);
657 657
658 attributes.colormap = colormap; 658 attributes.colormap = colormap;
659 attributes.border_pixel = 0; 659 attributes.border_pixel = 0;
660 attributes.event_mask = StructureNotifyMask | FocusChangeMask | ExposureMask; 660 attributes.event_mask = StructureNotifyMask | FocusChangeMask | ExposureMask;
661 if (!CreationParams.IgnoreInput) 661 if (!CreationParams.IgnoreInput)
662 attributes.event_mask |= PointerMotionMask | 662 attributes.event_mask |= PointerMotionMask |
663 ButtonPressMask | KeyPressMask | 663 ButtonPressMask | KeyPressMask |
664 ButtonReleaseMask | KeyReleaseMask; 664 ButtonReleaseMask | KeyReleaseMask;
665 665
666 if (!CreationParams.WindowId) 666 if (!CreationParams.WindowId)
667 { 667 {
668 // create new Window 668 // create new Window
669 // Remove window manager decoration in fullscreen 669 // Remove window manager decoration in fullscreen
670 attributes.override_redirect = CreationParams.Fullscreen; 670 attributes.override_redirect = CreationParams.Fullscreen;
671 window = XCreateWindow(display, 671 window = XCreateWindow(display,
672 RootWindow(display, visual->screen), 672 RootWindow(display, visual->screen),
673 0, 0, Width, Height, 0, visual->depth, 673 0, 0, Width, Height, 0, visual->depth,
674 InputOutput, visual->visual, 674 InputOutput, visual->visual,
675 CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, 675 CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect,
676 &attributes); 676 &attributes);
677 XMapRaised(display, window); 677 XMapRaised(display, window);
678 CreationParams.WindowId = (void*)window; 678 CreationParams.WindowId = (void*)window;
679 Atom wmDelete; 679 Atom wmDelete;
680 wmDelete = XInternAtom(display, wmDeleteWindow, True); 680 wmDelete = XInternAtom(display, wmDeleteWindow, True);
681 XSetWMProtocols(display, window, &wmDelete, 1); 681 XSetWMProtocols(display, window, &wmDelete, 1);
682 if (CreationParams.Fullscreen) 682 if (CreationParams.Fullscreen)
683 { 683 {
684 XSetInputFocus(display, window, RevertToParent, CurrentTime); 684 XSetInputFocus(display, window, RevertToParent, CurrentTime);
685 int grabKb = XGrabKeyboard(display, window, True, GrabModeAsync, 685 int grabKb = XGrabKeyboard(display, window, True, GrabModeAsync,
686 GrabModeAsync, CurrentTime); 686 GrabModeAsync, CurrentTime);
687 IrrPrintXGrabError(grabKb, "XGrabKeyboard"); 687 IrrPrintXGrabError(grabKb, "XGrabKeyboard");
688 int grabPointer = XGrabPointer(display, window, True, ButtonPressMask, 688 int grabPointer = XGrabPointer(display, window, True, ButtonPressMask,
689 GrabModeAsync, GrabModeAsync, window, None, CurrentTime); 689 GrabModeAsync, GrabModeAsync, window, None, CurrentTime);
690 IrrPrintXGrabError(grabPointer, "XGrabPointer"); 690 IrrPrintXGrabError(grabPointer, "XGrabPointer");
691 XWarpPointer(display, None, window, 0, 0, 0, 0, 0, 0); 691 XWarpPointer(display, None, window, 0, 0, 0, 0, 0, 0);
692 } 692 }
693 } 693 }
694 else 694 else
695 { 695 {
696 // attach external window 696 // attach external window
697 window = (Window)CreationParams.WindowId; 697 window = (Window)CreationParams.WindowId;
698 if (!CreationParams.IgnoreInput) 698 if (!CreationParams.IgnoreInput)
699 { 699 {
700 XCreateWindow(display, 700 XCreateWindow(display,
701 window, 701 window,
702 0, 0, Width, Height, 0, visual->depth, 702 0, 0, Width, Height, 0, visual->depth,
703 InputOutput, visual->visual, 703 InputOutput, visual->visual,
704 CWBorderPixel | CWColormap | CWEventMask, 704 CWBorderPixel | CWColormap | CWEventMask,
705 &attributes); 705 &attributes);
706 } 706 }
707 XWindowAttributes wa; 707 XWindowAttributes wa;
708 XGetWindowAttributes(display, window, &wa); 708 XGetWindowAttributes(display, window, &wa);
709 CreationParams.WindowSize.Width = wa.width; 709 CreationParams.WindowSize.Width = wa.width;
710 CreationParams.WindowSize.Height = wa.height; 710 CreationParams.WindowSize.Height = wa.height;
711 CreationParams.Fullscreen = false; 711 CreationParams.Fullscreen = false;
712 ExternalWindow = true; 712 ExternalWindow = true;
713 } 713 }
714 714
715 WindowMinimized=false; 715 WindowMinimized=false;
716 // Currently broken in X, see Bug ID 2795321 716 // Currently broken in X, see Bug ID 2795321
717 // XkbSetDetectableAutoRepeat(display, True, &AutorepeatSupport); 717 // XkbSetDetectableAutoRepeat(display, True, &AutorepeatSupport);
718 718
719#ifdef _IRR_COMPILE_WITH_OPENGL_ 719#ifdef _IRR_COMPILE_WITH_OPENGL_
720 720
721 // connect glx context to window 721 // connect glx context to window
722 Context=0; 722 Context=0;
723 if (isAvailableGLX && CreationParams.DriverType==video::EDT_OPENGL) 723 if (isAvailableGLX && CreationParams.DriverType==video::EDT_OPENGL)
724 { 724 {
725 if (CreationParams.VideoData) 725 if (CreationParams.VideoData)
726 Context = (GLXContext) CreationParams.VideoData->OpenGLLinux.X11Context; 726 Context = (GLXContext) CreationParams.VideoData->OpenGLLinux.X11Context;
727 if (Context) 727 if (Context)
728 { 728 {
729 if (!glXMakeCurrent(display, window, Context)) 729 if (!glXMakeCurrent(display, window, Context))
730 { 730 {
731 os::Printer::log("Could not make context current.", ELL_WARNING); 731 os::Printer::log("Could not make context current.", ELL_WARNING);
732 glXDestroyContext(display, Context); 732 glXDestroyContext(display, Context);
733 } 733 }
734 } 734 }
735 else if (UseGLXWindow) 735 else if (UseGLXWindow)
736 { 736 {
737 glxWin=glXCreateWindow(display,glxFBConfig,window,NULL); 737 glxWin=glXCreateWindow(display,glxFBConfig,window,NULL);
738 if (glxWin) 738 if (glxWin)
739 { 739 {
740 // create glx context 740 // create glx context
741 Context = glXCreateNewContext(display, glxFBConfig, GLX_RGBA_TYPE, NULL, True); 741 Context = glXCreateNewContext(display, glxFBConfig, GLX_RGBA_TYPE, NULL, True);
742 if (Context) 742 if (Context)
743 { 743 {
744 if (!glXMakeContextCurrent(display, glxWin, glxWin, Context)) 744 if (!glXMakeContextCurrent(display, glxWin, glxWin, Context))
745 { 745 {
746 os::Printer::log("Could not make context current.", ELL_WARNING); 746 os::Printer::log("Could not make context current.", ELL_WARNING);
747 glXDestroyContext(display, Context); 747 glXDestroyContext(display, Context);
748 } 748 }
749 } 749 }
750 else 750 else
751 { 751 {
752 os::Printer::log("Could not create GLX rendering context.", ELL_WARNING); 752 os::Printer::log("Could not create GLX rendering context.", ELL_WARNING);
753 } 753 }
754 } 754 }
755 else 755 else
756 { 756 {
757 os::Printer::log("Could not create GLX window.", ELL_WARNING); 757 os::Printer::log("Could not create GLX window.", ELL_WARNING);
758 } 758 }
759 } 759 }
760 else 760 else
761 { 761 {
762 Context = glXCreateContext(display, visual, NULL, True); 762 Context = glXCreateContext(display, visual, NULL, True);
763 if (Context) 763 if (Context)
764 { 764 {
765 if (!glXMakeCurrent(display, window, Context)) 765 if (!glXMakeCurrent(display, window, Context))
766 { 766 {
767 os::Printer::log("Could not make context current.", ELL_WARNING); 767 os::Printer::log("Could not make context current.", ELL_WARNING);
768 glXDestroyContext(display, Context); 768 glXDestroyContext(display, Context);
769 } 769 }
770 } 770 }
771 else 771 else
772 { 772 {
773 os::Printer::log("Could not create GLX rendering context.", ELL_WARNING); 773 os::Printer::log("Could not create GLX rendering context.", ELL_WARNING);
774 } 774 }
775 } 775 }
776 } 776 }
777#endif // _IRR_COMPILE_WITH_OPENGL_ 777#endif // _IRR_COMPILE_WITH_OPENGL_
778 778
779 Window tmp; 779 Window tmp;
780 u32 borderWidth; 780 u32 borderWidth;
781 int x,y; 781 int x,y;
782 unsigned int bits; 782 unsigned int bits;
783 783
784 XGetGeometry(display, window, &tmp, &x, &y, &Width, &Height, &borderWidth, &bits); 784 XGetGeometry(display, window, &tmp, &x, &y, &Width, &Height, &borderWidth, &bits);
785 CreationParams.Bits = bits; 785 CreationParams.Bits = bits;
786 CreationParams.WindowSize.Width = Width; 786 CreationParams.WindowSize.Width = Width;
787 CreationParams.WindowSize.Height = Height; 787 CreationParams.WindowSize.Height = Height;
788 788
789 StdHints = XAllocSizeHints(); 789 StdHints = XAllocSizeHints();
790 long num; 790 long num;
791 XGetWMNormalHints(display, window, StdHints, &num); 791 XGetWMNormalHints(display, window, StdHints, &num);
792 792
793 // create an XImage for the software renderer 793 // create an XImage for the software renderer
794 //(thx to Nadav for some clues on how to do that!) 794 //(thx to Nadav for some clues on how to do that!)
795 795
796 if (CreationParams.DriverType == video::EDT_SOFTWARE || CreationParams.DriverType == video::EDT_BURNINGSVIDEO) 796 if (CreationParams.DriverType == video::EDT_SOFTWARE || CreationParams.DriverType == video::EDT_BURNINGSVIDEO)
797 { 797 {
798 SoftwareImage = XCreateImage(display, 798 SoftwareImage = XCreateImage(display,
799 visual->visual, visual->depth, 799 visual->visual, visual->depth,
800 ZPixmap, 0, 0, Width, Height, 800 ZPixmap, 0, 0, Width, Height,
801 BitmapPad(display), 0); 801 BitmapPad(display), 0);
802 802
803 // use malloc because X will free it later on 803 // use malloc because X will free it later on
804 if (SoftwareImage) 804 if (SoftwareImage)
805 SoftwareImage->data = (char*) malloc(SoftwareImage->bytes_per_line * SoftwareImage->height * sizeof(char)); 805 SoftwareImage->data = (char*) malloc(SoftwareImage->bytes_per_line * SoftwareImage->height * sizeof(char));
806 } 806 }
807 807
808 initXAtoms(); 808 initXAtoms();
809 809
810#endif // #ifdef _IRR_COMPILE_WITH_X11_ 810#endif // #ifdef _IRR_COMPILE_WITH_X11_
811 return true; 811 return true;
812} 812}
813 813
814 814
815//! create the driver 815//! create the driver
816void CIrrDeviceLinux::createDriver() 816void CIrrDeviceLinux::createDriver()
817{ 817{
818 switch(CreationParams.DriverType) 818 switch(CreationParams.DriverType)
819 { 819 {
820#ifdef _IRR_COMPILE_WITH_X11_ 820#ifdef _IRR_COMPILE_WITH_X11_
821 821
822 case video::EDT_SOFTWARE: 822 case video::EDT_SOFTWARE:
823 #ifdef _IRR_COMPILE_WITH_SOFTWARE_ 823 #ifdef _IRR_COMPILE_WITH_SOFTWARE_
824 VideoDriver = video::createSoftwareDriver(CreationParams.WindowSize, CreationParams.Fullscreen, FileSystem, this); 824 VideoDriver = video::createSoftwareDriver(CreationParams.WindowSize, CreationParams.Fullscreen, FileSystem, this);
825 #else 825 #else
826 os::Printer::log("No Software driver support compiled in.", ELL_ERROR); 826 os::Printer::log("No Software driver support compiled in.", ELL_ERROR);
827 #endif 827 #endif
828 break; 828 break;
829 829
830 case video::EDT_BURNINGSVIDEO: 830 case video::EDT_BURNINGSVIDEO:
831 #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ 831 #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
832 VideoDriver = video::createBurningVideoDriver(CreationParams, FileSystem, this); 832 VideoDriver = video::createBurningVideoDriver(CreationParams, FileSystem, this);
833 #else 833 #else
834 os::Printer::log("Burning's video driver was not compiled in.", ELL_ERROR); 834 os::Printer::log("Burning's video driver was not compiled in.", ELL_ERROR);
835 #endif 835 #endif
836 break; 836 break;
837 837
838 case video::EDT_OPENGL: 838 case video::EDT_OPENGL:
839 #ifdef _IRR_COMPILE_WITH_OPENGL_ 839 #ifdef _IRR_COMPILE_WITH_OPENGL_
840 if (Context) 840 if (Context)
841 VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, this); 841 VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, this);
842 #else 842 #else
843 os::Printer::log("No OpenGL support compiled in.", ELL_ERROR); 843 os::Printer::log("No OpenGL support compiled in.", ELL_ERROR);
844 #endif 844 #endif
845 break; 845 break;
846 846
847 case video::EDT_DIRECT3D8: 847 case video::EDT_DIRECT3D8:
848 case video::EDT_DIRECT3D9: 848 case video::EDT_DIRECT3D9:
849 os::Printer::log("This driver is not available in Linux. Try OpenGL or Software renderer.", 849 os::Printer::log("This driver is not available in Linux. Try OpenGL or Software renderer.",
850 ELL_ERROR); 850 ELL_ERROR);
851 break; 851 break;
852 852
853 case video::EDT_NULL: 853 case video::EDT_NULL:
854 VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize); 854 VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize);
855 break; 855 break;
856 856
857 default: 857 default:
858 os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR); 858 os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR);
859 break; 859 break;
860#else 860#else
861 case video::EDT_NULL: 861 case video::EDT_NULL:
862 VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize); 862 VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize);
863 break; 863 break;
864 default: 864 default:
865 os::Printer::log("No X11 support compiled in. Only Null driver available.", ELL_ERROR); 865 os::Printer::log("No X11 support compiled in. Only Null driver available.", ELL_ERROR);
866 break; 866 break;
867#endif 867#endif
868 } 868 }
869} 869}
870 870
871 871
872//! runs the device. Returns false if device wants to be deleted 872//! runs the device. Returns false if device wants to be deleted
873bool CIrrDeviceLinux::run() 873bool CIrrDeviceLinux::run()
874{ 874{
875 os::Timer::tick(); 875 os::Timer::tick();
876 876
877#ifdef _IRR_COMPILE_WITH_X11_ 877#ifdef _IRR_COMPILE_WITH_X11_
878 878
879 if ( CursorControl ) 879 if ( CursorControl )
880 static_cast<CCursorControl*>(CursorControl)->update(); 880 static_cast<CCursorControl*>(CursorControl)->update();
881 881
882 if ((CreationParams.DriverType != video::EDT_NULL) && display) 882 if ((CreationParams.DriverType != video::EDT_NULL) && display)
883 { 883 {
884 SEvent irrevent; 884 SEvent irrevent;
885 irrevent.MouseInput.ButtonStates = 0xffffffff; 885 irrevent.MouseInput.ButtonStates = 0xffffffff;
886 886
887 while (XPending(display) > 0 && !Close) 887 while (XPending(display) > 0 && !Close)
888 { 888 {
889 XEvent event; 889 XEvent event;
890 XNextEvent(display, &event); 890 XNextEvent(display, &event);
891 891
892 switch (event.type) 892 switch (event.type)
893 { 893 {
894 case ConfigureNotify: 894 case ConfigureNotify:
895 // check for changed window size 895 // check for changed window size
896 if ((event.xconfigure.width != (int) Width) || 896 if ((event.xconfigure.width != (int) Width) ||
897 (event.xconfigure.height != (int) Height)) 897 (event.xconfigure.height != (int) Height))
898 { 898 {
899 Width = event.xconfigure.width; 899 Width = event.xconfigure.width;
900 Height = event.xconfigure.height; 900 Height = event.xconfigure.height;
901 901
902 // resize image data 902 // resize image data
903 if (SoftwareImage) 903 if (SoftwareImage)
904 { 904 {
905 XDestroyImage(SoftwareImage); 905 XDestroyImage(SoftwareImage);
906 906
907 SoftwareImage = XCreateImage(display, 907 SoftwareImage = XCreateImage(display,
908 visual->visual, visual->depth, 908 visual->visual, visual->depth,
909 ZPixmap, 0, 0, Width, Height, 909 ZPixmap, 0, 0, Width, Height,
910 BitmapPad(display), 0); 910 BitmapPad(display), 0);
911 911
912 // use malloc because X will free it later on 912 // use malloc because X will free it later on
913 if (SoftwareImage) 913 if (SoftwareImage)
914 SoftwareImage->data = (char*) malloc(SoftwareImage->bytes_per_line * SoftwareImage->height * sizeof(char)); 914 SoftwareImage->data = (char*) malloc(SoftwareImage->bytes_per_line * SoftwareImage->height * sizeof(char));
915 } 915 }
916 916
917 if (VideoDriver) 917 if (VideoDriver)
918 VideoDriver->OnResize(core::dimension2d<u32>(Width, Height)); 918 VideoDriver->OnResize(core::dimension2d<u32>(Width, Height));
919 } 919 }
920 break; 920 break;
921 921
922 case MapNotify: 922 case MapNotify:
923 WindowMinimized=false; 923 WindowMinimized=false;
924 break; 924 break;
925 925
926 case UnmapNotify: 926 case UnmapNotify:
927 WindowMinimized=true; 927 WindowMinimized=true;
928 break; 928 break;
929 929
930 case FocusIn: 930 case FocusIn:
931 WindowHasFocus=true; 931 WindowHasFocus=true;
932 break; 932 break;
933 933
934 case FocusOut: 934 case FocusOut:
935 WindowHasFocus=false; 935 WindowHasFocus=false;
936 break; 936 break;
937 937
938 case MotionNotify: 938 case MotionNotify:
939 irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT; 939 irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT;
940 irrevent.MouseInput.Event = irr::EMIE_MOUSE_MOVED; 940 irrevent.MouseInput.Event = irr::EMIE_MOUSE_MOVED;
941 irrevent.MouseInput.X = event.xbutton.x; 941 irrevent.MouseInput.X = event.xbutton.x;
942 irrevent.MouseInput.Y = event.xbutton.y; 942 irrevent.MouseInput.Y = event.xbutton.y;
943 irrevent.MouseInput.Control = (event.xkey.state & ControlMask) != 0; 943 irrevent.MouseInput.Control = (event.xkey.state & ControlMask) != 0;
944 irrevent.MouseInput.Shift = (event.xkey.state & ShiftMask) != 0; 944 irrevent.MouseInput.Shift = (event.xkey.state & ShiftMask) != 0;
945 945
946 // mouse button states 946 // mouse button states
947 irrevent.MouseInput.ButtonStates = (event.xbutton.state & Button1Mask) ? irr::EMBSM_LEFT : 0; 947 irrevent.MouseInput.ButtonStates = (event.xbutton.state & Button1Mask) ? irr::EMBSM_LEFT : 0;
948 irrevent.MouseInput.ButtonStates |= (event.xbutton.state & Button3Mask) ? irr::EMBSM_RIGHT : 0; 948 irrevent.MouseInput.ButtonStates |= (event.xbutton.state & Button3Mask) ? irr::EMBSM_RIGHT : 0;
949 irrevent.MouseInput.ButtonStates |= (event.xbutton.state & Button2Mask) ? irr::EMBSM_MIDDLE : 0; 949 irrevent.MouseInput.ButtonStates |= (event.xbutton.state & Button2Mask) ? irr::EMBSM_MIDDLE : 0;
950 950
951 postEventFromUser(irrevent); 951 postEventFromUser(irrevent);
952 break; 952 break;
953 953
954 case ButtonPress: 954 case ButtonPress:
955 case ButtonRelease: 955 case ButtonRelease:
956 956
957 irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT; 957 irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT;
958 irrevent.MouseInput.X = event.xbutton.x; 958 irrevent.MouseInput.X = event.xbutton.x;
959 irrevent.MouseInput.Y = event.xbutton.y; 959 irrevent.MouseInput.Y = event.xbutton.y;
960 irrevent.MouseInput.Control = (event.xkey.state & ControlMask) != 0; 960 irrevent.MouseInput.Control = (event.xkey.state & ControlMask) != 0;
961 irrevent.MouseInput.Shift = (event.xkey.state & ShiftMask) != 0; 961 irrevent.MouseInput.Shift = (event.xkey.state & ShiftMask) != 0;
962 962
963 // mouse button states 963 // mouse button states
964 // This sets the state which the buttons had _prior_ to the event. 964 // This sets the state which the buttons had _prior_ to the event.
965 // So unlike on Windows the button which just got changed has still the old state here. 965 // So unlike on Windows the button which just got changed has still the old state here.
966 // We handle that below by flipping the corresponding bit later. 966 // We handle that below by flipping the corresponding bit later.
967 irrevent.MouseInput.ButtonStates = (event.xbutton.state & Button1Mask) ? irr::EMBSM_LEFT : 0; 967 irrevent.MouseInput.ButtonStates = (event.xbutton.state & Button1Mask) ? irr::EMBSM_LEFT : 0;
968 irrevent.MouseInput.ButtonStates |= (event.xbutton.state & Button3Mask) ? irr::EMBSM_RIGHT : 0; 968 irrevent.MouseInput.ButtonStates |= (event.xbutton.state & Button3Mask) ? irr::EMBSM_RIGHT : 0;
969 irrevent.MouseInput.ButtonStates |= (event.xbutton.state & Button2Mask) ? irr::EMBSM_MIDDLE : 0; 969 irrevent.MouseInput.ButtonStates |= (event.xbutton.state & Button2Mask) ? irr::EMBSM_MIDDLE : 0;
970 970
971 irrevent.MouseInput.Event = irr::EMIE_COUNT; 971 irrevent.MouseInput.Event = irr::EMIE_COUNT;
972 972
973 switch(event.xbutton.button) 973 switch(event.xbutton.button)
974 { 974 {
975 case Button1: 975 case Button1:
976 irrevent.MouseInput.Event = 976 irrevent.MouseInput.Event =
977 (event.type == ButtonPress) ? irr::EMIE_LMOUSE_PRESSED_DOWN : irr::EMIE_LMOUSE_LEFT_UP; 977 (event.type == ButtonPress) ? irr::EMIE_LMOUSE_PRESSED_DOWN : irr::EMIE_LMOUSE_LEFT_UP;
978 irrevent.MouseInput.ButtonStates ^= irr::EMBSM_LEFT; 978 irrevent.MouseInput.ButtonStates ^= irr::EMBSM_LEFT;
979 break; 979 break;
980 980
981 case Button3: 981 case Button3:
982 irrevent.MouseInput.Event = 982 irrevent.MouseInput.Event =
983 (event.type == ButtonPress) ? irr::EMIE_RMOUSE_PRESSED_DOWN : irr::EMIE_RMOUSE_LEFT_UP; 983 (event.type == ButtonPress) ? irr::EMIE_RMOUSE_PRESSED_DOWN : irr::EMIE_RMOUSE_LEFT_UP;
984 irrevent.MouseInput.ButtonStates ^= irr::EMBSM_RIGHT; 984 irrevent.MouseInput.ButtonStates ^= irr::EMBSM_RIGHT;
985 break; 985 break;
986 986
987 case Button2: 987 case Button2:
988 irrevent.MouseInput.Event = 988 irrevent.MouseInput.Event =
989 (event.type == ButtonPress) ? irr::EMIE_MMOUSE_PRESSED_DOWN : irr::EMIE_MMOUSE_LEFT_UP; 989 (event.type == ButtonPress) ? irr::EMIE_MMOUSE_PRESSED_DOWN : irr::EMIE_MMOUSE_LEFT_UP;
990 irrevent.MouseInput.ButtonStates ^= irr::EMBSM_MIDDLE; 990 irrevent.MouseInput.ButtonStates ^= irr::EMBSM_MIDDLE;
991 break; 991 break;
992 992
993 case Button4: 993 case Button4:
994 if (event.type == ButtonPress) 994 if (event.type == ButtonPress)
995 { 995 {
996 irrevent.MouseInput.Event = EMIE_MOUSE_WHEEL; 996 irrevent.MouseInput.Event = EMIE_MOUSE_WHEEL;
997 irrevent.MouseInput.Wheel = 1.0f; 997 irrevent.MouseInput.Wheel = 1.0f;
998 } 998 }
999 break; 999 break;
1000 1000
1001 case Button5: 1001 case Button5:
1002 if (event.type == ButtonPress) 1002 if (event.type == ButtonPress)
1003 { 1003 {
1004 irrevent.MouseInput.Event = EMIE_MOUSE_WHEEL; 1004 irrevent.MouseInput.Event = EMIE_MOUSE_WHEEL;
1005 irrevent.MouseInput.Wheel = -1.0f; 1005 irrevent.MouseInput.Wheel = -1.0f;
1006 } 1006 }
1007 break; 1007 break;
1008 } 1008 }
1009 1009
1010 if (irrevent.MouseInput.Event != irr::EMIE_COUNT) 1010 if (irrevent.MouseInput.Event != irr::EMIE_COUNT)
1011 { 1011 {
1012 postEventFromUser(irrevent); 1012 postEventFromUser(irrevent);
1013 1013
1014 if ( irrevent.MouseInput.Event >= EMIE_LMOUSE_PRESSED_DOWN && irrevent.MouseInput.Event <= EMIE_MMOUSE_PRESSED_DOWN ) 1014 if ( irrevent.MouseInput.Event >= EMIE_LMOUSE_PRESSED_DOWN && irrevent.MouseInput.Event <= EMIE_MMOUSE_PRESSED_DOWN )
1015 { 1015 {
1016 u32 clicks = checkSuccessiveClicks(irrevent.MouseInput.X, irrevent.MouseInput.Y, irrevent.MouseInput.Event); 1016 u32 clicks = checkSuccessiveClicks(irrevent.MouseInput.X, irrevent.MouseInput.Y, irrevent.MouseInput.Event);
1017 if ( clicks == 2 ) 1017 if ( clicks == 2 )
1018 { 1018 {
1019 irrevent.MouseInput.Event = (EMOUSE_INPUT_EVENT)(EMIE_LMOUSE_DOUBLE_CLICK + irrevent.MouseInput.Event-EMIE_LMOUSE_PRESSED_DOWN); 1019 irrevent.MouseInput.Event = (EMOUSE_INPUT_EVENT)(EMIE_LMOUSE_DOUBLE_CLICK + irrevent.MouseInput.Event-EMIE_LMOUSE_PRESSED_DOWN);
1020 postEventFromUser(irrevent); 1020 postEventFromUser(irrevent);
1021 } 1021 }
1022 else if ( clicks == 3 ) 1022 else if ( clicks == 3 )
1023 { 1023 {
1024 irrevent.MouseInput.Event = (EMOUSE_INPUT_EVENT)(EMIE_LMOUSE_TRIPLE_CLICK + irrevent.MouseInput.Event-EMIE_LMOUSE_PRESSED_DOWN); 1024 irrevent.MouseInput.Event = (EMOUSE_INPUT_EVENT)(EMIE_LMOUSE_TRIPLE_CLICK + irrevent.MouseInput.Event-EMIE_LMOUSE_PRESSED_DOWN);
1025 postEventFromUser(irrevent); 1025 postEventFromUser(irrevent);
1026 } 1026 }
1027 } 1027 }
1028 } 1028 }
1029 break; 1029 break;
1030 1030
1031 case MappingNotify: 1031 case MappingNotify:
1032 XRefreshKeyboardMapping (&event.xmapping) ; 1032 XRefreshKeyboardMapping (&event.xmapping) ;
1033 break; 1033 break;
1034 1034
1035 case KeyRelease: 1035 case KeyRelease:
1036 if (0 == AutorepeatSupport && (XPending( display ) > 0) ) 1036 if (0 == AutorepeatSupport && (XPending( display ) > 0) )
1037 { 1037 {
1038 // check for Autorepeat manually 1038 // check for Autorepeat manually
1039 // We'll do the same as Windows does: Only send KeyPressed 1039 // We'll do the same as Windows does: Only send KeyPressed
1040 // So every KeyRelease is a real release 1040 // So every KeyRelease is a real release
1041 XEvent next_event; 1041 XEvent next_event;
1042 XPeekEvent (event.xkey.display, &next_event); 1042 XPeekEvent (event.xkey.display, &next_event);
1043 if ((next_event.type == KeyPress) && 1043 if ((next_event.type == KeyPress) &&
1044 (next_event.xkey.keycode == event.xkey.keycode) && 1044 (next_event.xkey.keycode == event.xkey.keycode) &&
1045 (next_event.xkey.time - event.xkey.time) < 2) // usually same time, but on some systems a difference of 1 is possible 1045 (next_event.xkey.time - event.xkey.time) < 2) // usually same time, but on some systems a difference of 1 is possible
1046 { 1046 {
1047 /* Ignore the key release event */ 1047 /* Ignore the key release event */
1048 break; 1048 break;
1049 } 1049 }
1050 } 1050 }
1051 // fall-through in case the release should be handled 1051 // fall-through in case the release should be handled
1052 case KeyPress: 1052 case KeyPress:
1053 { 1053 {
1054 SKeyMap mp; 1054 SKeyMap mp;
1055 char buf[8]={0}; 1055 char buf[8]={0};
1056 XLookupString(&event.xkey, buf, sizeof(buf), &mp.X11Key, NULL); 1056 XLookupString(&event.xkey, buf, sizeof(buf), &mp.X11Key, NULL);
1057 1057
1058 irrevent.EventType = irr::EET_KEY_INPUT_EVENT; 1058 irrevent.EventType = irr::EET_KEY_INPUT_EVENT;
1059 irrevent.KeyInput.PressedDown = (event.type == KeyPress); 1059 irrevent.KeyInput.PressedDown = (event.type == KeyPress);
1060// mbtowc(&irrevent.KeyInput.Char, buf, sizeof(buf)); 1060// mbtowc(&irrevent.KeyInput.Char, buf, sizeof(buf));
1061 irrevent.KeyInput.Char = ((wchar_t*)(buf))[0]; 1061 irrevent.KeyInput.Char = ((wchar_t*)(buf))[0];
1062 irrevent.KeyInput.Control = (event.xkey.state & ControlMask) != 0; 1062 irrevent.KeyInput.Control = (event.xkey.state & ControlMask) != 0;
1063 irrevent.KeyInput.Shift = (event.xkey.state & ShiftMask) != 0; 1063 irrevent.KeyInput.Shift = (event.xkey.state & ShiftMask) != 0;
1064 1064
1065 event.xkey.state = 0; // ignore shift-ctrl states for figuring out the key 1065 event.xkey.state = 0; // ignore shift-ctrl states for figuring out the key
1066 XLookupString(&event.xkey, buf, sizeof(buf), &mp.X11Key, NULL); 1066 XLookupString(&event.xkey, buf, sizeof(buf), &mp.X11Key, NULL);
1067 const s32 idx = KeyMap.binary_search(mp); 1067 const s32 idx = KeyMap.binary_search(mp);
1068 if (idx != -1) 1068 if (idx != -1)
1069 { 1069 {
1070 irrevent.KeyInput.Key = (EKEY_CODE)KeyMap[idx].Win32Key; 1070 irrevent.KeyInput.Key = (EKEY_CODE)KeyMap[idx].Win32Key;
1071 } 1071 }
1072 else 1072 else
1073 { 1073 {
1074 irrevent.KeyInput.Key = (EKEY_CODE)0; 1074 irrevent.KeyInput.Key = (EKEY_CODE)0;
1075 } 1075 }
1076 if (irrevent.KeyInput.Key == 0) 1076 if (irrevent.KeyInput.Key == 0)
1077 { 1077 {
1078 // 1:1 mapping to windows-keys would require testing for keyboard type (us, ger, ...) 1078 // 1:1 mapping to windows-keys would require testing for keyboard type (us, ger, ...)
1079 // So unless we do that we will have some unknown keys here. 1079 // So unless we do that we will have some unknown keys here.
1080 if (idx == -1) 1080 if (idx == -1)
1081 { 1081 {
1082 os::Printer::log("Could not find EKEY_CODE, using orig. X11 keycode instead", core::stringc(event.xkey.keycode).c_str(), ELL_INFORMATION); 1082 os::Printer::log("Could not find EKEY_CODE, using orig. X11 keycode instead", core::stringc(event.xkey.keycode).c_str(), ELL_INFORMATION);
1083 } 1083 }
1084 else 1084 else
1085 { 1085 {
1086 os::Printer::log("EKEY_CODE is 0, using orig. X11 keycode instead", core::stringc(event.xkey.keycode).c_str(), ELL_INFORMATION); 1086 os::Printer::log("EKEY_CODE is 0, using orig. X11 keycode instead", core::stringc(event.xkey.keycode).c_str(), ELL_INFORMATION);
1087 } 1087 }
1088 // Any value is better than none, that allows at least using the keys. 1088 // Any value is better than none, that allows at least using the keys.
1089 // Worst case is that some keys will be identical, still better than _all_ 1089 // Worst case is that some keys will be identical, still better than _all_
1090 // unknown keys being identical. 1090 // unknown keys being identical.
1091 irrevent.KeyInput.Key = (EKEY_CODE)event.xkey.keycode; 1091 irrevent.KeyInput.Key = (EKEY_CODE)event.xkey.keycode;
1092 } 1092 }
1093 1093
1094 postEventFromUser(irrevent); 1094 postEventFromUser(irrevent);
1095 } 1095 }
1096 break; 1096 break;
1097 1097
1098 case ClientMessage: 1098 case ClientMessage:
1099 { 1099 {
1100 char *atom = XGetAtomName(display, event.xclient.message_type); 1100 char *atom = XGetAtomName(display, event.xclient.message_type);
1101 if (*atom == *wmDeleteWindow) 1101 if (*atom == *wmDeleteWindow)
1102 { 1102 {
1103 os::Printer::log("Quit message received.", ELL_INFORMATION); 1103 os::Printer::log("Quit message received.", ELL_INFORMATION);
1104 Close = true; 1104 Close = true;
1105 } 1105 }
1106 else 1106 else
1107 { 1107 {
1108 // we assume it's a user message 1108 // we assume it's a user message
1109 irrevent.EventType = irr::EET_USER_EVENT; 1109 irrevent.EventType = irr::EET_USER_EVENT;
1110 irrevent.UserEvent.UserData1 = (s32)event.xclient.data.l[0]; 1110 irrevent.UserEvent.UserData1 = (s32)event.xclient.data.l[0];
1111 irrevent.UserEvent.UserData2 = (s32)event.xclient.data.l[1]; 1111 irrevent.UserEvent.UserData2 = (s32)event.xclient.data.l[1];
1112 postEventFromUser(irrevent); 1112 postEventFromUser(irrevent);
1113 } 1113 }
1114 XFree(atom); 1114 XFree(atom);
1115 } 1115 }
1116 break; 1116 break;
1117 1117
1118 case SelectionRequest: 1118 case SelectionRequest:
1119 { 1119 {
1120 XEvent respond; 1120 XEvent respond;
1121 XSelectionRequestEvent *req = &(event.xselectionrequest); 1121 XSelectionRequestEvent *req = &(event.xselectionrequest);
1122 if ( req->target == XA_STRING) 1122 if ( req->target == XA_STRING)
1123 { 1123 {
1124 XChangeProperty (display, 1124 XChangeProperty (display,
1125 req->requestor, 1125 req->requestor,
1126 req->property, req->target, 1126 req->property, req->target,
1127 8, // format 1127 8, // format
1128 PropModeReplace, 1128 PropModeReplace,
1129 (unsigned char*) Clipboard.c_str(), 1129 (unsigned char*) Clipboard.c_str(),
1130 Clipboard.size()); 1130 Clipboard.size());
1131 respond.xselection.property = req->property; 1131 respond.xselection.property = req->property;
1132 } 1132 }
1133 else if ( req->target == X_ATOM_TARGETS ) 1133 else if ( req->target == X_ATOM_TARGETS )
1134 { 1134 {
1135 long data[2]; 1135 long data[2];
1136 1136
1137 data[0] = X_ATOM_TEXT; 1137 data[0] = X_ATOM_TEXT;
1138 data[1] = XA_STRING; 1138 data[1] = XA_STRING;
1139 1139
1140 XChangeProperty (display, req->requestor, 1140 XChangeProperty (display, req->requestor,
1141 req->property, req->target, 1141 req->property, req->target,
1142 8, PropModeReplace, 1142 8, PropModeReplace,
1143 (unsigned char *) &data, 1143 (unsigned char *) &data,
1144 sizeof (data)); 1144 sizeof (data));
1145 respond.xselection.property = req->property; 1145 respond.xselection.property = req->property;
1146 } 1146 }
1147 else 1147 else
1148 { 1148 {
1149 respond.xselection.property= None; 1149 respond.xselection.property= None;
1150 } 1150 }
1151 respond.xselection.type= SelectionNotify; 1151 respond.xselection.type= SelectionNotify;
1152 respond.xselection.display= req->display; 1152 respond.xselection.display= req->display;
1153 respond.xselection.requestor= req->requestor; 1153 respond.xselection.requestor= req->requestor;
1154 respond.xselection.selection=req->selection; 1154 respond.xselection.selection=req->selection;
1155 respond.xselection.target= req->target; 1155 respond.xselection.target= req->target;
1156 respond.xselection.time = req->time; 1156 respond.xselection.time = req->time;
1157 XSendEvent (display, req->requestor,0,0,&respond); 1157 XSendEvent (display, req->requestor,0,0,&respond);
1158 XFlush (display); 1158 XFlush (display);
1159 } 1159 }
1160 break; 1160 break;
1161 1161
1162 default: 1162 default:
1163 break; 1163 break;
1164 } // end switch 1164 } // end switch
1165 1165
1166 } // end while 1166 } // end while
1167 } 1167 }
1168#endif //_IRR_COMPILE_WITH_X11_ 1168#endif //_IRR_COMPILE_WITH_X11_
1169 1169
1170 if (!Close) 1170 if (!Close)
1171 pollJoysticks(); 1171 pollJoysticks();
1172 1172
1173 return !Close; 1173 return !Close;
1174} 1174}
1175 1175
1176 1176
1177//! Pause the current process for the minimum time allowed only to allow other processes to execute 1177//! Pause the current process for the minimum time allowed only to allow other processes to execute
1178void CIrrDeviceLinux::yield() 1178void CIrrDeviceLinux::yield()
1179{ 1179{
1180 struct timespec ts = {0,1}; 1180 struct timespec ts = {0,1};
1181 nanosleep(&ts, NULL); 1181 nanosleep(&ts, NULL);
1182} 1182}
1183 1183
1184 1184
1185//! Pause execution and let other processes to run for a specified amount of time. 1185//! Pause execution and let other processes to run for a specified amount of time.
1186void CIrrDeviceLinux::sleep(u32 timeMs, bool pauseTimer=false) 1186void CIrrDeviceLinux::sleep(u32 timeMs, bool pauseTimer=false)
1187{ 1187{
1188 const bool wasStopped = Timer ? Timer->isStopped() : true; 1188 const bool wasStopped = Timer ? Timer->isStopped() : true;
1189 1189
1190 struct timespec ts; 1190 struct timespec ts;
1191 ts.tv_sec = (time_t) (timeMs / 1000); 1191 ts.tv_sec = (time_t) (timeMs / 1000);
1192 ts.tv_nsec = (long) (timeMs % 1000) * 1000000; 1192 ts.tv_nsec = (long) (timeMs % 1000) * 1000000;
1193 1193
1194 if (pauseTimer && !wasStopped) 1194 if (pauseTimer && !wasStopped)
1195 Timer->stop(); 1195 Timer->stop();
1196 1196
1197 nanosleep(&ts, NULL); 1197 nanosleep(&ts, NULL);
1198 1198
1199 if (pauseTimer && !wasStopped) 1199 if (pauseTimer && !wasStopped)
1200 Timer->start(); 1200 Timer->start();
1201} 1201}
1202 1202
1203 1203
1204//! sets the caption of the window 1204//! sets the caption of the window
1205void CIrrDeviceLinux::setWindowCaption(const wchar_t* text) 1205void CIrrDeviceLinux::setWindowCaption(const wchar_t* text)
1206{ 1206{
1207#ifdef _IRR_COMPILE_WITH_X11_ 1207#ifdef _IRR_COMPILE_WITH_X11_
1208 if (CreationParams.DriverType == video::EDT_NULL) 1208 if (CreationParams.DriverType == video::EDT_NULL)
1209 return; 1209 return;
1210 1210
1211 XTextProperty txt; 1211 XTextProperty txt;
1212 if (Success==XwcTextListToTextProperty(display, const_cast<wchar_t**>(&text), 1212 if (Success==XwcTextListToTextProperty(display, const_cast<wchar_t**>(&text),
1213 1, XStdICCTextStyle, &txt)) 1213 1, XStdICCTextStyle, &txt))
1214 { 1214 {
1215 XSetWMName(display, window, &txt); 1215 XSetWMName(display, window, &txt);
1216 XSetWMIconName(display, window, &txt); 1216 XSetWMIconName(display, window, &txt);
1217 XFree(txt.value); 1217 XFree(txt.value);
1218 } 1218 }
1219#endif 1219#endif
1220} 1220}
1221 1221
1222 1222
1223//! presents a surface in the client area 1223//! presents a surface in the client area
1224bool CIrrDeviceLinux::present(video::IImage* image, void* windowId, core::rect<s32>* srcRect) 1224bool CIrrDeviceLinux::present(video::IImage* image, void* windowId, core::rect<s32>* srcRect)
1225{ 1225{
1226#ifdef _IRR_COMPILE_WITH_X11_ 1226#ifdef _IRR_COMPILE_WITH_X11_
1227 // this is only necessary for software drivers. 1227 // this is only necessary for software drivers.
1228 if (!SoftwareImage) 1228 if (!SoftwareImage)
1229 return true; 1229 return true;
1230 1230
1231 // thx to Nadav, who send me some clues of how to display the image 1231 // thx to Nadav, who send me some clues of how to display the image
1232 // to the X Server. 1232 // to the X Server.
1233 1233
1234 const u32 destwidth = SoftwareImage->width; 1234 const u32 destwidth = SoftwareImage->width;
1235 const u32 minWidth = core::min_(image->getDimension().Width, destwidth); 1235 const u32 minWidth = core::min_(image->getDimension().Width, destwidth);
1236 const u32 destPitch = SoftwareImage->bytes_per_line; 1236 const u32 destPitch = SoftwareImage->bytes_per_line;
1237 1237
1238 video::ECOLOR_FORMAT destColor; 1238 video::ECOLOR_FORMAT destColor;
1239 switch (SoftwareImage->bits_per_pixel) 1239 switch (SoftwareImage->bits_per_pixel)
1240 { 1240 {
1241 case 16: 1241 case 16:
1242 if (SoftwareImage->depth==16) 1242 if (SoftwareImage->depth==16)
1243 destColor = video::ECF_R5G6B5; 1243 destColor = video::ECF_R5G6B5;
1244 else 1244 else
1245 destColor = video::ECF_A1R5G5B5; 1245 destColor = video::ECF_A1R5G5B5;
1246 break; 1246 break;
1247 case 24: destColor = video::ECF_R8G8B8; break; 1247 case 24: destColor = video::ECF_R8G8B8; break;
1248 case 32: destColor = video::ECF_A8R8G8B8; break; 1248 case 32: destColor = video::ECF_A8R8G8B8; break;
1249 default: 1249 default:
1250 os::Printer::log("Unsupported screen depth."); 1250 os::Printer::log("Unsupported screen depth.");
1251 return false; 1251 return false;
1252 } 1252 }
1253 1253
1254 u8* srcdata = reinterpret_cast<u8*>(image->lock()); 1254 u8* srcdata = reinterpret_cast<u8*>(image->lock());
1255 u8* destData = reinterpret_cast<u8*>(SoftwareImage->data); 1255 u8* destData = reinterpret_cast<u8*>(SoftwareImage->data);
1256 1256
1257 const u32 destheight = SoftwareImage->height; 1257 const u32 destheight = SoftwareImage->height;
1258 const u32 srcheight = core::min_(image->getDimension().Height, destheight); 1258 const u32 srcheight = core::min_(image->getDimension().Height, destheight);
1259 const u32 srcPitch = image->getPitch(); 1259 const u32 srcPitch = image->getPitch();
1260 for (u32 y=0; y!=srcheight; ++y) 1260 for (u32 y=0; y!=srcheight; ++y)
1261 { 1261 {
1262 video::CColorConverter::convert_viaFormat(srcdata,image->getColorFormat(), minWidth, destData, destColor); 1262 video::CColorConverter::convert_viaFormat(srcdata,image->getColorFormat(), minWidth, destData, destColor);
1263 srcdata+=srcPitch; 1263 srcdata+=srcPitch;
1264 destData+=destPitch; 1264 destData+=destPitch;
1265 } 1265 }
1266 image->unlock(); 1266 image->unlock();
1267 1267
1268 GC gc = DefaultGC(display, DefaultScreen(display)); 1268 GC gc = DefaultGC(display, DefaultScreen(display));
1269 Window myWindow=window; 1269 Window myWindow=window;
1270 if (windowId) 1270 if (windowId)
1271 myWindow = reinterpret_cast<Window>(windowId); 1271 myWindow = reinterpret_cast<Window>(windowId);
1272 XPutImage(display, myWindow, gc, SoftwareImage, 0, 0, 0, 0, destwidth, destheight); 1272 XPutImage(display, myWindow, gc, SoftwareImage, 0, 0, 0, 0, destwidth, destheight);
1273#endif 1273#endif
1274 return true; 1274 return true;
1275} 1275}
1276 1276
1277 1277
1278//! notifies the device that it should close itself 1278//! notifies the device that it should close itself
1279void CIrrDeviceLinux::closeDevice() 1279void CIrrDeviceLinux::closeDevice()
1280{ 1280{
1281 Close = true; 1281 Close = true;
1282} 1282}
1283 1283
1284 1284
1285//! returns if window is active. if not, nothing need to be drawn 1285//! returns if window is active. if not, nothing need to be drawn
1286bool CIrrDeviceLinux::isWindowActive() const 1286bool CIrrDeviceLinux::isWindowActive() const
1287{ 1287{
1288 return (WindowHasFocus && !WindowMinimized); 1288 return (WindowHasFocus && !WindowMinimized);
1289} 1289}
1290 1290
1291 1291
1292//! returns if window has focus. 1292//! returns if window has focus.
1293bool CIrrDeviceLinux::isWindowFocused() const 1293bool CIrrDeviceLinux::isWindowFocused() const
1294{ 1294{
1295 return WindowHasFocus; 1295 return WindowHasFocus;
1296} 1296}
1297 1297
1298 1298
1299//! returns if window is minimized. 1299//! returns if window is minimized.
1300bool CIrrDeviceLinux::isWindowMinimized() const 1300bool CIrrDeviceLinux::isWindowMinimized() const
1301{ 1301{
1302 return WindowMinimized; 1302 return WindowMinimized;
1303} 1303}
1304 1304
1305 1305
1306//! returns color format of the window. 1306//! returns color format of the window.
1307video::ECOLOR_FORMAT CIrrDeviceLinux::getColorFormat() const 1307video::ECOLOR_FORMAT CIrrDeviceLinux::getColorFormat() const
1308{ 1308{
1309#ifdef _IRR_COMPILE_WITH_X11_ 1309#ifdef _IRR_COMPILE_WITH_X11_
1310 if (visual && (visual->depth != 16)) 1310 if (visual && (visual->depth != 16))
1311 return video::ECF_R8G8B8; 1311 return video::ECF_R8G8B8;
1312 else 1312 else
1313#endif 1313#endif
1314 return video::ECF_R5G6B5; 1314 return video::ECF_R5G6B5;
1315} 1315}
1316 1316
1317 1317
1318//! Sets if the window should be resizable in windowed mode. 1318//! Sets if the window should be resizable in windowed mode.
1319void CIrrDeviceLinux::setResizable(bool resize) 1319void CIrrDeviceLinux::setResizable(bool resize)
1320{ 1320{
1321#ifdef _IRR_COMPILE_WITH_X11_ 1321#ifdef _IRR_COMPILE_WITH_X11_
1322 if (CreationParams.DriverType == video::EDT_NULL || CreationParams.Fullscreen ) 1322 if (CreationParams.DriverType == video::EDT_NULL || CreationParams.Fullscreen )
1323 return; 1323 return;
1324 1324
1325 XUnmapWindow(display, window); 1325 XUnmapWindow(display, window);
1326 if ( !resize ) 1326 if ( !resize )
1327 { 1327 {
1328 // Must be heap memory because data size depends on X Server 1328 // Must be heap memory because data size depends on X Server
1329 XSizeHints *hints = XAllocSizeHints(); 1329 XSizeHints *hints = XAllocSizeHints();
1330 hints->flags=PSize|PMinSize|PMaxSize; 1330 hints->flags=PSize|PMinSize|PMaxSize;
1331 hints->min_width=hints->max_width=hints->base_width=Width; 1331 hints->min_width=hints->max_width=hints->base_width=Width;
1332 hints->min_height=hints->max_height=hints->base_height=Height; 1332 hints->min_height=hints->max_height=hints->base_height=Height;
1333 XSetWMNormalHints(display, window, hints); 1333 XSetWMNormalHints(display, window, hints);
1334 XFree(hints); 1334 XFree(hints);
1335 } 1335 }
1336 else 1336 else
1337 { 1337 {
1338 XSetWMNormalHints(display, window, StdHints); 1338 XSetWMNormalHints(display, window, StdHints);
1339 } 1339 }
1340 XMapWindow(display, window); 1340 XMapWindow(display, window);
1341 XFlush(display); 1341 XFlush(display);
1342#endif // #ifdef _IRR_COMPILE_WITH_X11_ 1342#endif // #ifdef _IRR_COMPILE_WITH_X11_
1343} 1343}
1344 1344
1345 1345
1346//! Return pointer to a list with all video modes supported by the gfx adapter. 1346//! Return pointer to a list with all video modes supported by the gfx adapter.
1347video::IVideoModeList* CIrrDeviceLinux::getVideoModeList() 1347video::IVideoModeList* CIrrDeviceLinux::getVideoModeList()
1348{ 1348{
1349#ifdef _IRR_COMPILE_WITH_X11_ 1349#ifdef _IRR_COMPILE_WITH_X11_
1350 if (!VideoModeList.getVideoModeCount()) 1350 if (!VideoModeList.getVideoModeCount())
1351 { 1351 {
1352 bool temporaryDisplay = false; 1352 bool temporaryDisplay = false;
1353 1353
1354 if (!display) 1354 if (!display)
1355 { 1355 {
1356 display = XOpenDisplay(0); 1356 display = XOpenDisplay(0);
1357 temporaryDisplay=true; 1357 temporaryDisplay=true;
1358 } 1358 }
1359 if (display) 1359 if (display)
1360 { 1360 {
1361 #if defined(_IRR_LINUX_X11_VIDMODE_) || defined(_IRR_LINUX_X11_RANDR_) 1361 #if defined(_IRR_LINUX_X11_VIDMODE_) || defined(_IRR_LINUX_X11_RANDR_)
1362 s32 eventbase, errorbase; 1362 s32 eventbase, errorbase;
1363 s32 defaultDepth=DefaultDepth(display,screennr); 1363 s32 defaultDepth=DefaultDepth(display,screennr);
1364 #endif 1364 #endif
1365 1365
1366 #ifdef _IRR_LINUX_X11_VIDMODE_ 1366 #ifdef _IRR_LINUX_X11_VIDMODE_
1367 if (XF86VidModeQueryExtension(display, &eventbase, &errorbase)) 1367 if (XF86VidModeQueryExtension(display, &eventbase, &errorbase))
1368 { 1368 {
1369 // enumerate video modes 1369 // enumerate video modes
1370 int modeCount; 1370 int modeCount;
1371 XF86VidModeModeInfo** modes; 1371 XF86VidModeModeInfo** modes;
1372 1372
1373 XF86VidModeGetAllModeLines(display, screennr, &modeCount, &modes); 1373 XF86VidModeGetAllModeLines(display, screennr, &modeCount, &modes);
1374 1374
1375 // save current video mode 1375 // save current video mode
1376 oldVideoMode = *modes[0]; 1376 oldVideoMode = *modes[0];
1377 1377
1378 // find fitting mode 1378 // find fitting mode
1379 1379
1380 VideoModeList.setDesktop(defaultDepth, core::dimension2d<u32>( 1380 VideoModeList.setDesktop(defaultDepth, core::dimension2d<u32>(
1381 modes[0]->hdisplay, modes[0]->vdisplay)); 1381 modes[0]->hdisplay, modes[0]->vdisplay));
1382 for (int i = 0; i<modeCount; ++i) 1382 for (int i = 0; i<modeCount; ++i)
1383 { 1383 {
1384 VideoModeList.addMode(core::dimension2d<u32>( 1384 VideoModeList.addMode(core::dimension2d<u32>(
1385 modes[i]->hdisplay, modes[i]->vdisplay), defaultDepth); 1385 modes[i]->hdisplay, modes[i]->vdisplay), defaultDepth);
1386 } 1386 }
1387 XFree(modes); 1387 XFree(modes);
1388 } 1388 }
1389 else 1389 else
1390 #endif 1390 #endif
1391 #ifdef _IRR_LINUX_X11_RANDR_ 1391 #ifdef _IRR_LINUX_X11_RANDR_
1392 if (XRRQueryExtension(display, &eventbase, &errorbase)) 1392 if (XRRQueryExtension(display, &eventbase, &errorbase))
1393 { 1393 {
1394 int modeCount; 1394 int modeCount;
1395 XRRScreenConfiguration *config=XRRGetScreenInfo(display,DefaultRootWindow(display)); 1395 XRRScreenConfiguration *config=XRRGetScreenInfo(display,DefaultRootWindow(display));
1396 oldRandrMode=XRRConfigCurrentConfiguration(config,&oldRandrRotation); 1396 oldRandrMode=XRRConfigCurrentConfiguration(config,&oldRandrRotation);
1397 XRRScreenSize *modes=XRRConfigSizes(config,&modeCount); 1397 XRRScreenSize *modes=XRRConfigSizes(config,&modeCount);
1398 VideoModeList.setDesktop(defaultDepth, core::dimension2d<u32>( 1398 VideoModeList.setDesktop(defaultDepth, core::dimension2d<u32>(
1399 modes[oldRandrMode].width, modes[oldRandrMode].height)); 1399 modes[oldRandrMode].width, modes[oldRandrMode].height));
1400 for (int i = 0; i<modeCount; ++i) 1400 for (int i = 0; i<modeCount; ++i)
1401 { 1401 {
1402 VideoModeList.addMode(core::dimension2d<u32>( 1402 VideoModeList.addMode(core::dimension2d<u32>(
1403 modes[i].width, modes[i].height), defaultDepth); 1403 modes[i].width, modes[i].height), defaultDepth);
1404 } 1404 }
1405 XRRFreeScreenConfigInfo(config); 1405 XRRFreeScreenConfigInfo(config);
1406 } 1406 }
1407 else 1407 else
1408 #endif 1408 #endif
1409 { 1409 {
1410 os::Printer::log("VidMode or RandR X11 extension requireed for VideoModeList." , ELL_WARNING); 1410 os::Printer::log("VidMode or RandR X11 extension requireed for VideoModeList." , ELL_WARNING);
1411 } 1411 }
1412 } 1412 }
1413 if (display && temporaryDisplay) 1413 if (display && temporaryDisplay)
1414 { 1414 {
1415 XCloseDisplay(display); 1415 XCloseDisplay(display);
1416 display=0; 1416 display=0;
1417 } 1417 }
1418 } 1418 }
1419#endif 1419#endif
1420 1420
1421 return &VideoModeList; 1421 return &VideoModeList;
1422} 1422}
1423 1423
1424 1424
1425//! Minimize window 1425//! Minimize window
1426void CIrrDeviceLinux::minimizeWindow() 1426void CIrrDeviceLinux::minimizeWindow()
1427{ 1427{
1428#ifdef _IRR_COMPILE_WITH_X11_ 1428#ifdef _IRR_COMPILE_WITH_X11_
1429 XIconifyWindow(display, window, screennr); 1429 XIconifyWindow(display, window, screennr);
1430#endif 1430#endif
1431} 1431}
1432 1432
1433 1433
1434//! Maximize window 1434//! Maximize window
1435void CIrrDeviceLinux::maximizeWindow() 1435void CIrrDeviceLinux::maximizeWindow()
1436{ 1436{
1437#ifdef _IRR_COMPILE_WITH_X11_ 1437#ifdef _IRR_COMPILE_WITH_X11_
1438 XMapWindow(display, window); 1438 XMapWindow(display, window);
1439#endif 1439#endif
1440} 1440}
1441 1441
1442 1442
1443//! Restore original window size 1443//! Restore original window size
1444void CIrrDeviceLinux::restoreWindow() 1444void CIrrDeviceLinux::restoreWindow()
1445{ 1445{
1446#ifdef _IRR_COMPILE_WITH_X11_ 1446#ifdef _IRR_COMPILE_WITH_X11_
1447 XMapWindow(display, window); 1447 XMapWindow(display, window);
1448#endif 1448#endif
1449} 1449}
1450 1450
1451 1451
1452void CIrrDeviceLinux::createKeyMap() 1452void CIrrDeviceLinux::createKeyMap()
1453{ 1453{
1454 // I don't know if this is the best method to create 1454 // I don't know if this is the best method to create
1455 // the lookuptable, but I'll leave it like that until 1455 // the lookuptable, but I'll leave it like that until
1456 // I find a better version. 1456 // I find a better version.
1457 1457
1458#ifdef _IRR_COMPILE_WITH_X11_ 1458#ifdef _IRR_COMPILE_WITH_X11_
1459 KeyMap.reallocate(84); 1459 KeyMap.reallocate(84);
1460 KeyMap.push_back(SKeyMap(XK_BackSpace, KEY_BACK)); 1460 KeyMap.push_back(SKeyMap(XK_BackSpace, KEY_BACK));
1461 KeyMap.push_back(SKeyMap(XK_Tab, KEY_TAB)); 1461 KeyMap.push_back(SKeyMap(XK_Tab, KEY_TAB));
1462 KeyMap.push_back(SKeyMap(XK_ISO_Left_Tab, KEY_TAB)); 1462 KeyMap.push_back(SKeyMap(XK_ISO_Left_Tab, KEY_TAB));
1463 KeyMap.push_back(SKeyMap(XK_Linefeed, 0)); // ??? 1463 KeyMap.push_back(SKeyMap(XK_Linefeed, 0)); // ???
1464 KeyMap.push_back(SKeyMap(XK_Clear, KEY_CLEAR)); 1464 KeyMap.push_back(SKeyMap(XK_Clear, KEY_CLEAR));
1465 KeyMap.push_back(SKeyMap(XK_Return, KEY_RETURN)); 1465 KeyMap.push_back(SKeyMap(XK_Return, KEY_RETURN));
1466 KeyMap.push_back(SKeyMap(XK_Pause, KEY_PAUSE)); 1466 KeyMap.push_back(SKeyMap(XK_Pause, KEY_PAUSE));
1467 KeyMap.push_back(SKeyMap(XK_Scroll_Lock, KEY_SCROLL)); 1467 KeyMap.push_back(SKeyMap(XK_Scroll_Lock, KEY_SCROLL));
1468 KeyMap.push_back(SKeyMap(XK_Sys_Req, 0)); // ??? 1468 KeyMap.push_back(SKeyMap(XK_Sys_Req, 0)); // ???
1469 KeyMap.push_back(SKeyMap(XK_Escape, KEY_ESCAPE)); 1469 KeyMap.push_back(SKeyMap(XK_Escape, KEY_ESCAPE));
1470 KeyMap.push_back(SKeyMap(XK_Insert, KEY_INSERT)); 1470 KeyMap.push_back(SKeyMap(XK_Insert, KEY_INSERT));
1471 KeyMap.push_back(SKeyMap(XK_Delete, KEY_DELETE)); 1471 KeyMap.push_back(SKeyMap(XK_Delete, KEY_DELETE));
1472 KeyMap.push_back(SKeyMap(XK_Home, KEY_HOME)); 1472 KeyMap.push_back(SKeyMap(XK_Home, KEY_HOME));
1473 KeyMap.push_back(SKeyMap(XK_Left, KEY_LEFT)); 1473 KeyMap.push_back(SKeyMap(XK_Left, KEY_LEFT));
1474 KeyMap.push_back(SKeyMap(XK_Up, KEY_UP)); 1474 KeyMap.push_back(SKeyMap(XK_Up, KEY_UP));
1475 KeyMap.push_back(SKeyMap(XK_Right, KEY_RIGHT)); 1475 KeyMap.push_back(SKeyMap(XK_Right, KEY_RIGHT));
1476 KeyMap.push_back(SKeyMap(XK_Down, KEY_DOWN)); 1476 KeyMap.push_back(SKeyMap(XK_Down, KEY_DOWN));
1477 KeyMap.push_back(SKeyMap(XK_Prior, KEY_PRIOR)); 1477 KeyMap.push_back(SKeyMap(XK_Prior, KEY_PRIOR));
1478 KeyMap.push_back(SKeyMap(XK_Page_Up, KEY_PRIOR)); 1478 KeyMap.push_back(SKeyMap(XK_Page_Up, KEY_PRIOR));
1479 KeyMap.push_back(SKeyMap(XK_Next, KEY_NEXT)); 1479 KeyMap.push_back(SKeyMap(XK_Next, KEY_NEXT));
1480 KeyMap.push_back(SKeyMap(XK_Page_Down, KEY_NEXT)); 1480 KeyMap.push_back(SKeyMap(XK_Page_Down, KEY_NEXT));
1481 KeyMap.push_back(SKeyMap(XK_End, KEY_END)); 1481 KeyMap.push_back(SKeyMap(XK_End, KEY_END));
1482 KeyMap.push_back(SKeyMap(XK_Begin, KEY_HOME)); 1482 KeyMap.push_back(SKeyMap(XK_Begin, KEY_HOME));
1483 KeyMap.push_back(SKeyMap(XK_Num_Lock, KEY_NUMLOCK)); 1483 KeyMap.push_back(SKeyMap(XK_Num_Lock, KEY_NUMLOCK));
1484 KeyMap.push_back(SKeyMap(XK_KP_Space, KEY_SPACE)); 1484 KeyMap.push_back(SKeyMap(XK_KP_Space, KEY_SPACE));
1485 KeyMap.push_back(SKeyMap(XK_KP_Tab, KEY_TAB)); 1485 KeyMap.push_back(SKeyMap(XK_KP_Tab, KEY_TAB));
1486 KeyMap.push_back(SKeyMap(XK_KP_Enter, KEY_RETURN)); 1486 KeyMap.push_back(SKeyMap(XK_KP_Enter, KEY_RETURN));
1487 KeyMap.push_back(SKeyMap(XK_KP_F1, KEY_F1)); 1487 KeyMap.push_back(SKeyMap(XK_KP_F1, KEY_F1));
1488 KeyMap.push_back(SKeyMap(XK_KP_F2, KEY_F2)); 1488 KeyMap.push_back(SKeyMap(XK_KP_F2, KEY_F2));
1489 KeyMap.push_back(SKeyMap(XK_KP_F3, KEY_F3)); 1489 KeyMap.push_back(SKeyMap(XK_KP_F3, KEY_F3));
1490 KeyMap.push_back(SKeyMap(XK_KP_F4, KEY_F4)); 1490 KeyMap.push_back(SKeyMap(XK_KP_F4, KEY_F4));
1491 KeyMap.push_back(SKeyMap(XK_KP_Home, KEY_HOME)); 1491 KeyMap.push_back(SKeyMap(XK_KP_Home, KEY_HOME));
1492 KeyMap.push_back(SKeyMap(XK_KP_Left, KEY_LEFT)); 1492 KeyMap.push_back(SKeyMap(XK_KP_Left, KEY_LEFT));
1493 KeyMap.push_back(SKeyMap(XK_KP_Up, KEY_UP)); 1493 KeyMap.push_back(SKeyMap(XK_KP_Up, KEY_UP));
1494 KeyMap.push_back(SKeyMap(XK_KP_Right, KEY_RIGHT)); 1494 KeyMap.push_back(SKeyMap(XK_KP_Right, KEY_RIGHT));
1495 KeyMap.push_back(SKeyMap(XK_KP_Down, KEY_DOWN)); 1495 KeyMap.push_back(SKeyMap(XK_KP_Down, KEY_DOWN));
1496 KeyMap.push_back(SKeyMap(XK_Print, KEY_PRINT)); 1496 KeyMap.push_back(SKeyMap(XK_Print, KEY_PRINT));
1497 KeyMap.push_back(SKeyMap(XK_KP_Prior, KEY_PRIOR)); 1497 KeyMap.push_back(SKeyMap(XK_KP_Prior, KEY_PRIOR));
1498 KeyMap.push_back(SKeyMap(XK_KP_Page_Up, KEY_PRIOR)); 1498 KeyMap.push_back(SKeyMap(XK_KP_Page_Up, KEY_PRIOR));
1499 KeyMap.push_back(SKeyMap(XK_KP_Next, KEY_NEXT)); 1499 KeyMap.push_back(SKeyMap(XK_KP_Next, KEY_NEXT));
1500 KeyMap.push_back(SKeyMap(XK_KP_Page_Down, KEY_NEXT)); 1500 KeyMap.push_back(SKeyMap(XK_KP_Page_Down, KEY_NEXT));
1501 KeyMap.push_back(SKeyMap(XK_KP_End, KEY_END)); 1501 KeyMap.push_back(SKeyMap(XK_KP_End, KEY_END));
1502 KeyMap.push_back(SKeyMap(XK_KP_Begin, KEY_HOME)); 1502 KeyMap.push_back(SKeyMap(XK_KP_Begin, KEY_HOME));
1503 KeyMap.push_back(SKeyMap(XK_KP_Insert, KEY_INSERT)); 1503 KeyMap.push_back(SKeyMap(XK_KP_Insert, KEY_INSERT));
1504 KeyMap.push_back(SKeyMap(XK_KP_Delete, KEY_DELETE)); 1504 KeyMap.push_back(SKeyMap(XK_KP_Delete, KEY_DELETE));
1505 KeyMap.push_back(SKeyMap(XK_KP_Equal, 0)); // ??? 1505 KeyMap.push_back(SKeyMap(XK_KP_Equal, 0)); // ???
1506 KeyMap.push_back(SKeyMap(XK_KP_Multiply, KEY_MULTIPLY)); 1506 KeyMap.push_back(SKeyMap(XK_KP_Multiply, KEY_MULTIPLY));
1507 KeyMap.push_back(SKeyMap(XK_KP_Add, KEY_ADD)); 1507 KeyMap.push_back(SKeyMap(XK_KP_Add, KEY_ADD));
1508 KeyMap.push_back(SKeyMap(XK_KP_Separator, KEY_SEPARATOR)); 1508 KeyMap.push_back(SKeyMap(XK_KP_Separator, KEY_SEPARATOR));
1509 KeyMap.push_back(SKeyMap(XK_KP_Subtract, KEY_SUBTRACT)); 1509 KeyMap.push_back(SKeyMap(XK_KP_Subtract, KEY_SUBTRACT));
1510 KeyMap.push_back(SKeyMap(XK_KP_Decimal, KEY_DECIMAL)); 1510 KeyMap.push_back(SKeyMap(XK_KP_Decimal, KEY_DECIMAL));
1511 KeyMap.push_back(SKeyMap(XK_KP_Divide, KEY_DIVIDE)); 1511 KeyMap.push_back(SKeyMap(XK_KP_Divide, KEY_DIVIDE));
1512 KeyMap.push_back(SKeyMap(XK_KP_0, KEY_KEY_0)); 1512 KeyMap.push_back(SKeyMap(XK_KP_0, KEY_KEY_0));
1513 KeyMap.push_back(SKeyMap(XK_KP_1, KEY_KEY_1)); 1513 KeyMap.push_back(SKeyMap(XK_KP_1, KEY_KEY_1));
1514 KeyMap.push_back(SKeyMap(XK_KP_2, KEY_KEY_2)); 1514 KeyMap.push_back(SKeyMap(XK_KP_2, KEY_KEY_2));
1515 KeyMap.push_back(SKeyMap(XK_KP_3, KEY_KEY_3)); 1515 KeyMap.push_back(SKeyMap(XK_KP_3, KEY_KEY_3));
1516 KeyMap.push_back(SKeyMap(XK_KP_4, KEY_KEY_4)); 1516 KeyMap.push_back(SKeyMap(XK_KP_4, KEY_KEY_4));
1517 KeyMap.push_back(SKeyMap(XK_KP_5, KEY_KEY_5)); 1517 KeyMap.push_back(SKeyMap(XK_KP_5, KEY_KEY_5));
1518 KeyMap.push_back(SKeyMap(XK_KP_6, KEY_KEY_6)); 1518 KeyMap.push_back(SKeyMap(XK_KP_6, KEY_KEY_6));
1519 KeyMap.push_back(SKeyMap(XK_KP_7, KEY_KEY_7)); 1519 KeyMap.push_back(SKeyMap(XK_KP_7, KEY_KEY_7));
1520 KeyMap.push_back(SKeyMap(XK_KP_8, KEY_KEY_8)); 1520 KeyMap.push_back(SKeyMap(XK_KP_8, KEY_KEY_8));
1521 KeyMap.push_back(SKeyMap(XK_KP_9, KEY_KEY_9)); 1521 KeyMap.push_back(SKeyMap(XK_KP_9, KEY_KEY_9));
1522 KeyMap.push_back(SKeyMap(XK_F1, KEY_F1)); 1522 KeyMap.push_back(SKeyMap(XK_F1, KEY_F1));
1523 KeyMap.push_back(SKeyMap(XK_F2, KEY_F2)); 1523 KeyMap.push_back(SKeyMap(XK_F2, KEY_F2));
1524 KeyMap.push_back(SKeyMap(XK_F3, KEY_F3)); 1524 KeyMap.push_back(SKeyMap(XK_F3, KEY_F3));
1525 KeyMap.push_back(SKeyMap(XK_F4, KEY_F4)); 1525 KeyMap.push_back(SKeyMap(XK_F4, KEY_F4));
1526 KeyMap.push_back(SKeyMap(XK_F5, KEY_F5)); 1526 KeyMap.push_back(SKeyMap(XK_F5, KEY_F5));
1527 KeyMap.push_back(SKeyMap(XK_F6, KEY_F6)); 1527 KeyMap.push_back(SKeyMap(XK_F6, KEY_F6));
1528 KeyMap.push_back(SKeyMap(XK_F7, KEY_F7)); 1528 KeyMap.push_back(SKeyMap(XK_F7, KEY_F7));
1529 KeyMap.push_back(SKeyMap(XK_F8, KEY_F8)); 1529 KeyMap.push_back(SKeyMap(XK_F8, KEY_F8));
1530 KeyMap.push_back(SKeyMap(XK_F9, KEY_F9)); 1530 KeyMap.push_back(SKeyMap(XK_F9, KEY_F9));
1531 KeyMap.push_back(SKeyMap(XK_F10, KEY_F10)); 1531 KeyMap.push_back(SKeyMap(XK_F10, KEY_F10));
1532 KeyMap.push_back(SKeyMap(XK_F11, KEY_F11)); 1532 KeyMap.push_back(SKeyMap(XK_F11, KEY_F11));
1533 KeyMap.push_back(SKeyMap(XK_F12, KEY_F12)); 1533 KeyMap.push_back(SKeyMap(XK_F12, KEY_F12));
1534 KeyMap.push_back(SKeyMap(XK_Shift_L, KEY_LSHIFT)); 1534 KeyMap.push_back(SKeyMap(XK_Shift_L, KEY_LSHIFT));
1535 KeyMap.push_back(SKeyMap(XK_Shift_R, KEY_RSHIFT)); 1535 KeyMap.push_back(SKeyMap(XK_Shift_R, KEY_RSHIFT));
1536 KeyMap.push_back(SKeyMap(XK_Control_L, KEY_LCONTROL)); 1536 KeyMap.push_back(SKeyMap(XK_Control_L, KEY_LCONTROL));
1537 KeyMap.push_back(SKeyMap(XK_Control_R, KEY_RCONTROL)); 1537 KeyMap.push_back(SKeyMap(XK_Control_R, KEY_RCONTROL));
1538 KeyMap.push_back(SKeyMap(XK_Caps_Lock, KEY_CAPITAL)); 1538 KeyMap.push_back(SKeyMap(XK_Caps_Lock, KEY_CAPITAL));
1539 KeyMap.push_back(SKeyMap(XK_Shift_Lock, KEY_CAPITAL)); 1539 KeyMap.push_back(SKeyMap(XK_Shift_Lock, KEY_CAPITAL));
1540 KeyMap.push_back(SKeyMap(XK_Meta_L, KEY_LWIN)); 1540 KeyMap.push_back(SKeyMap(XK_Meta_L, KEY_LWIN));
1541 KeyMap.push_back(SKeyMap(XK_Meta_R, KEY_RWIN)); 1541 KeyMap.push_back(SKeyMap(XK_Meta_R, KEY_RWIN));
1542 KeyMap.push_back(SKeyMap(XK_Alt_L, KEY_LMENU)); 1542 KeyMap.push_back(SKeyMap(XK_Alt_L, KEY_LMENU));
1543 KeyMap.push_back(SKeyMap(XK_Alt_R, KEY_RMENU)); 1543 KeyMap.push_back(SKeyMap(XK_Alt_R, KEY_RMENU));
1544 KeyMap.push_back(SKeyMap(XK_ISO_Level3_Shift, KEY_RMENU)); 1544 KeyMap.push_back(SKeyMap(XK_ISO_Level3_Shift, KEY_RMENU));
1545 KeyMap.push_back(SKeyMap(XK_Menu, KEY_MENU)); 1545 KeyMap.push_back(SKeyMap(XK_Menu, KEY_MENU));
1546 KeyMap.push_back(SKeyMap(XK_space, KEY_SPACE)); 1546 KeyMap.push_back(SKeyMap(XK_space, KEY_SPACE));
1547 KeyMap.push_back(SKeyMap(XK_exclam, 0)); //? 1547 KeyMap.push_back(SKeyMap(XK_exclam, 0)); //?
1548 KeyMap.push_back(SKeyMap(XK_quotedbl, 0)); //? 1548 KeyMap.push_back(SKeyMap(XK_quotedbl, 0)); //?
1549 KeyMap.push_back(SKeyMap(XK_section, 0)); //? 1549 KeyMap.push_back(SKeyMap(XK_section, 0)); //?
1550 KeyMap.push_back(SKeyMap(XK_numbersign, KEY_OEM_2)); 1550 KeyMap.push_back(SKeyMap(XK_numbersign, KEY_OEM_2));
1551 KeyMap.push_back(SKeyMap(XK_dollar, 0)); //? 1551 KeyMap.push_back(SKeyMap(XK_dollar, 0)); //?
1552 KeyMap.push_back(SKeyMap(XK_percent, 0)); //? 1552 KeyMap.push_back(SKeyMap(XK_percent, 0)); //?
1553 KeyMap.push_back(SKeyMap(XK_ampersand, 0)); //? 1553 KeyMap.push_back(SKeyMap(XK_ampersand, 0)); //?
1554 KeyMap.push_back(SKeyMap(XK_apostrophe, KEY_OEM_7)); 1554 KeyMap.push_back(SKeyMap(XK_apostrophe, KEY_OEM_7));
1555 KeyMap.push_back(SKeyMap(XK_parenleft, 0)); //? 1555 KeyMap.push_back(SKeyMap(XK_parenleft, 0)); //?
1556 KeyMap.push_back(SKeyMap(XK_parenright, 0)); //? 1556 KeyMap.push_back(SKeyMap(XK_parenright, 0)); //?
1557 KeyMap.push_back(SKeyMap(XK_asterisk, 0)); //? 1557 KeyMap.push_back(SKeyMap(XK_asterisk, 0)); //?
1558 KeyMap.push_back(SKeyMap(XK_plus, KEY_PLUS)); //? 1558 KeyMap.push_back(SKeyMap(XK_plus, KEY_PLUS)); //?
1559 KeyMap.push_back(SKeyMap(XK_comma, KEY_COMMA)); //? 1559 KeyMap.push_back(SKeyMap(XK_comma, KEY_COMMA)); //?
1560 KeyMap.push_back(SKeyMap(XK_minus, KEY_MINUS)); //? 1560 KeyMap.push_back(SKeyMap(XK_minus, KEY_MINUS)); //?
1561 KeyMap.push_back(SKeyMap(XK_period, KEY_PERIOD)); //? 1561 KeyMap.push_back(SKeyMap(XK_period, KEY_PERIOD)); //?
1562 KeyMap.push_back(SKeyMap(XK_slash, KEY_OEM_2)); //? 1562 KeyMap.push_back(SKeyMap(XK_slash, KEY_OEM_2)); //?
1563 KeyMap.push_back(SKeyMap(XK_0, KEY_KEY_0)); 1563 KeyMap.push_back(SKeyMap(XK_0, KEY_KEY_0));
1564 KeyMap.push_back(SKeyMap(XK_1, KEY_KEY_1)); 1564 KeyMap.push_back(SKeyMap(XK_1, KEY_KEY_1));
1565 KeyMap.push_back(SKeyMap(XK_2, KEY_KEY_2)); 1565 KeyMap.push_back(SKeyMap(XK_2, KEY_KEY_2));
1566 KeyMap.push_back(SKeyMap(XK_3, KEY_KEY_3)); 1566 KeyMap.push_back(SKeyMap(XK_3, KEY_KEY_3));
1567 KeyMap.push_back(SKeyMap(XK_4, KEY_KEY_4)); 1567 KeyMap.push_back(SKeyMap(XK_4, KEY_KEY_4));
1568 KeyMap.push_back(SKeyMap(XK_5, KEY_KEY_5)); 1568 KeyMap.push_back(SKeyMap(XK_5, KEY_KEY_5));
1569 KeyMap.push_back(SKeyMap(XK_6, KEY_KEY_6)); 1569 KeyMap.push_back(SKeyMap(XK_6, KEY_KEY_6));
1570 KeyMap.push_back(SKeyMap(XK_7, KEY_KEY_7)); 1570 KeyMap.push_back(SKeyMap(XK_7, KEY_KEY_7));
1571 KeyMap.push_back(SKeyMap(XK_8, KEY_KEY_8)); 1571 KeyMap.push_back(SKeyMap(XK_8, KEY_KEY_8));
1572 KeyMap.push_back(SKeyMap(XK_9, KEY_KEY_9)); 1572 KeyMap.push_back(SKeyMap(XK_9, KEY_KEY_9));
1573 KeyMap.push_back(SKeyMap(XK_colon, 0)); //? 1573 KeyMap.push_back(SKeyMap(XK_colon, 0)); //?
1574 KeyMap.push_back(SKeyMap(XK_semicolon, KEY_OEM_1)); 1574 KeyMap.push_back(SKeyMap(XK_semicolon, KEY_OEM_1));
1575 KeyMap.push_back(SKeyMap(XK_less, KEY_OEM_102)); 1575 KeyMap.push_back(SKeyMap(XK_less, KEY_OEM_102));
1576 KeyMap.push_back(SKeyMap(XK_equal, KEY_PLUS)); 1576 KeyMap.push_back(SKeyMap(XK_equal, KEY_PLUS));
1577 KeyMap.push_back(SKeyMap(XK_greater, 0)); //? 1577 KeyMap.push_back(SKeyMap(XK_greater, 0)); //?
1578 KeyMap.push_back(SKeyMap(XK_question, 0)); //? 1578 KeyMap.push_back(SKeyMap(XK_question, 0)); //?
1579 KeyMap.push_back(SKeyMap(XK_at, KEY_KEY_2)); //? 1579 KeyMap.push_back(SKeyMap(XK_at, KEY_KEY_2)); //?
1580 KeyMap.push_back(SKeyMap(XK_mu, 0)); //? 1580 KeyMap.push_back(SKeyMap(XK_mu, 0)); //?
1581 KeyMap.push_back(SKeyMap(XK_EuroSign, 0)); //? 1581 KeyMap.push_back(SKeyMap(XK_EuroSign, 0)); //?
1582 KeyMap.push_back(SKeyMap(XK_A, KEY_KEY_A)); 1582 KeyMap.push_back(SKeyMap(XK_A, KEY_KEY_A));
1583 KeyMap.push_back(SKeyMap(XK_B, KEY_KEY_B)); 1583 KeyMap.push_back(SKeyMap(XK_B, KEY_KEY_B));
1584 KeyMap.push_back(SKeyMap(XK_C, KEY_KEY_C)); 1584 KeyMap.push_back(SKeyMap(XK_C, KEY_KEY_C));
1585 KeyMap.push_back(SKeyMap(XK_D, KEY_KEY_D)); 1585 KeyMap.push_back(SKeyMap(XK_D, KEY_KEY_D));
1586 KeyMap.push_back(SKeyMap(XK_E, KEY_KEY_E)); 1586 KeyMap.push_back(SKeyMap(XK_E, KEY_KEY_E));
1587 KeyMap.push_back(SKeyMap(XK_F, KEY_KEY_F)); 1587 KeyMap.push_back(SKeyMap(XK_F, KEY_KEY_F));
1588 KeyMap.push_back(SKeyMap(XK_G, KEY_KEY_G)); 1588 KeyMap.push_back(SKeyMap(XK_G, KEY_KEY_G));
1589 KeyMap.push_back(SKeyMap(XK_H, KEY_KEY_H)); 1589 KeyMap.push_back(SKeyMap(XK_H, KEY_KEY_H));
1590 KeyMap.push_back(SKeyMap(XK_I, KEY_KEY_I)); 1590 KeyMap.push_back(SKeyMap(XK_I, KEY_KEY_I));
1591 KeyMap.push_back(SKeyMap(XK_J, KEY_KEY_J)); 1591 KeyMap.push_back(SKeyMap(XK_J, KEY_KEY_J));
1592 KeyMap.push_back(SKeyMap(XK_K, KEY_KEY_K)); 1592 KeyMap.push_back(SKeyMap(XK_K, KEY_KEY_K));
1593 KeyMap.push_back(SKeyMap(XK_L, KEY_KEY_L)); 1593 KeyMap.push_back(SKeyMap(XK_L, KEY_KEY_L));
1594 KeyMap.push_back(SKeyMap(XK_M, KEY_KEY_M)); 1594 KeyMap.push_back(SKeyMap(XK_M, KEY_KEY_M));
1595 KeyMap.push_back(SKeyMap(XK_N, KEY_KEY_N)); 1595 KeyMap.push_back(SKeyMap(XK_N, KEY_KEY_N));
1596 KeyMap.push_back(SKeyMap(XK_O, KEY_KEY_O)); 1596 KeyMap.push_back(SKeyMap(XK_O, KEY_KEY_O));
1597 KeyMap.push_back(SKeyMap(XK_P, KEY_KEY_P)); 1597 KeyMap.push_back(SKeyMap(XK_P, KEY_KEY_P));
1598 KeyMap.push_back(SKeyMap(XK_Q, KEY_KEY_Q)); 1598 KeyMap.push_back(SKeyMap(XK_Q, KEY_KEY_Q));
1599 KeyMap.push_back(SKeyMap(XK_R, KEY_KEY_R)); 1599 KeyMap.push_back(SKeyMap(XK_R, KEY_KEY_R));
1600 KeyMap.push_back(SKeyMap(XK_S, KEY_KEY_S)); 1600 KeyMap.push_back(SKeyMap(XK_S, KEY_KEY_S));
1601 KeyMap.push_back(SKeyMap(XK_T, KEY_KEY_T)); 1601 KeyMap.push_back(SKeyMap(XK_T, KEY_KEY_T));
1602 KeyMap.push_back(SKeyMap(XK_U, KEY_KEY_U)); 1602 KeyMap.push_back(SKeyMap(XK_U, KEY_KEY_U));
1603 KeyMap.push_back(SKeyMap(XK_V, KEY_KEY_V)); 1603 KeyMap.push_back(SKeyMap(XK_V, KEY_KEY_V));
1604 KeyMap.push_back(SKeyMap(XK_W, KEY_KEY_W)); 1604 KeyMap.push_back(SKeyMap(XK_W, KEY_KEY_W));
1605 KeyMap.push_back(SKeyMap(XK_X, KEY_KEY_X)); 1605 KeyMap.push_back(SKeyMap(XK_X, KEY_KEY_X));
1606 KeyMap.push_back(SKeyMap(XK_Y, KEY_KEY_Y)); 1606 KeyMap.push_back(SKeyMap(XK_Y, KEY_KEY_Y));
1607 KeyMap.push_back(SKeyMap(XK_Z, KEY_KEY_Z)); 1607 KeyMap.push_back(SKeyMap(XK_Z, KEY_KEY_Z));
1608 KeyMap.push_back(SKeyMap(XK_bracketleft, KEY_OEM_4)); 1608 KeyMap.push_back(SKeyMap(XK_bracketleft, KEY_OEM_4));
1609 KeyMap.push_back(SKeyMap(XK_backslash, KEY_OEM_5)); 1609 KeyMap.push_back(SKeyMap(XK_backslash, KEY_OEM_5));
1610 KeyMap.push_back(SKeyMap(XK_bracketright, KEY_OEM_6)); 1610 KeyMap.push_back(SKeyMap(XK_bracketright, KEY_OEM_6));
1611 KeyMap.push_back(SKeyMap(XK_asciicircum, KEY_OEM_5)); 1611 KeyMap.push_back(SKeyMap(XK_asciicircum, KEY_OEM_5));
1612 KeyMap.push_back(SKeyMap(XK_degree, 0)); //? 1612 KeyMap.push_back(SKeyMap(XK_degree, 0)); //?
1613 KeyMap.push_back(SKeyMap(XK_underscore, KEY_MINUS)); //? 1613 KeyMap.push_back(SKeyMap(XK_underscore, KEY_MINUS)); //?
1614 KeyMap.push_back(SKeyMap(XK_grave, KEY_OEM_3)); 1614 KeyMap.push_back(SKeyMap(XK_grave, KEY_OEM_3));
1615 KeyMap.push_back(SKeyMap(XK_acute, KEY_OEM_6)); 1615 KeyMap.push_back(SKeyMap(XK_acute, KEY_OEM_6));
1616 KeyMap.push_back(SKeyMap(XK_a, KEY_KEY_A)); 1616 KeyMap.push_back(SKeyMap(XK_a, KEY_KEY_A));
1617 KeyMap.push_back(SKeyMap(XK_b, KEY_KEY_B)); 1617 KeyMap.push_back(SKeyMap(XK_b, KEY_KEY_B));
1618 KeyMap.push_back(SKeyMap(XK_c, KEY_KEY_C)); 1618 KeyMap.push_back(SKeyMap(XK_c, KEY_KEY_C));
1619 KeyMap.push_back(SKeyMap(XK_d, KEY_KEY_D)); 1619 KeyMap.push_back(SKeyMap(XK_d, KEY_KEY_D));
1620 KeyMap.push_back(SKeyMap(XK_e, KEY_KEY_E)); 1620 KeyMap.push_back(SKeyMap(XK_e, KEY_KEY_E));
1621 KeyMap.push_back(SKeyMap(XK_f, KEY_KEY_F)); 1621 KeyMap.push_back(SKeyMap(XK_f, KEY_KEY_F));
1622 KeyMap.push_back(SKeyMap(XK_g, KEY_KEY_G)); 1622 KeyMap.push_back(SKeyMap(XK_g, KEY_KEY_G));
1623 KeyMap.push_back(SKeyMap(XK_h, KEY_KEY_H)); 1623 KeyMap.push_back(SKeyMap(XK_h, KEY_KEY_H));
1624 KeyMap.push_back(SKeyMap(XK_i, KEY_KEY_I)); 1624 KeyMap.push_back(SKeyMap(XK_i, KEY_KEY_I));
1625 KeyMap.push_back(SKeyMap(XK_j, KEY_KEY_J)); 1625 KeyMap.push_back(SKeyMap(XK_j, KEY_KEY_J));
1626 KeyMap.push_back(SKeyMap(XK_k, KEY_KEY_K)); 1626 KeyMap.push_back(SKeyMap(XK_k, KEY_KEY_K));
1627 KeyMap.push_back(SKeyMap(XK_l, KEY_KEY_L)); 1627 KeyMap.push_back(SKeyMap(XK_l, KEY_KEY_L));
1628 KeyMap.push_back(SKeyMap(XK_m, KEY_KEY_M)); 1628 KeyMap.push_back(SKeyMap(XK_m, KEY_KEY_M));
1629 KeyMap.push_back(SKeyMap(XK_n, KEY_KEY_N)); 1629 KeyMap.push_back(SKeyMap(XK_n, KEY_KEY_N));
1630 KeyMap.push_back(SKeyMap(XK_o, KEY_KEY_O)); 1630 KeyMap.push_back(SKeyMap(XK_o, KEY_KEY_O));
1631 KeyMap.push_back(SKeyMap(XK_p, KEY_KEY_P)); 1631 KeyMap.push_back(SKeyMap(XK_p, KEY_KEY_P));
1632 KeyMap.push_back(SKeyMap(XK_q, KEY_KEY_Q)); 1632 KeyMap.push_back(SKeyMap(XK_q, KEY_KEY_Q));
1633 KeyMap.push_back(SKeyMap(XK_r, KEY_KEY_R)); 1633 KeyMap.push_back(SKeyMap(XK_r, KEY_KEY_R));
1634 KeyMap.push_back(SKeyMap(XK_s, KEY_KEY_S)); 1634 KeyMap.push_back(SKeyMap(XK_s, KEY_KEY_S));
1635 KeyMap.push_back(SKeyMap(XK_t, KEY_KEY_T)); 1635 KeyMap.push_back(SKeyMap(XK_t, KEY_KEY_T));
1636 KeyMap.push_back(SKeyMap(XK_u, KEY_KEY_U)); 1636 KeyMap.push_back(SKeyMap(XK_u, KEY_KEY_U));
1637 KeyMap.push_back(SKeyMap(XK_v, KEY_KEY_V)); 1637 KeyMap.push_back(SKeyMap(XK_v, KEY_KEY_V));
1638 KeyMap.push_back(SKeyMap(XK_w, KEY_KEY_W)); 1638 KeyMap.push_back(SKeyMap(XK_w, KEY_KEY_W));
1639 KeyMap.push_back(SKeyMap(XK_x, KEY_KEY_X)); 1639 KeyMap.push_back(SKeyMap(XK_x, KEY_KEY_X));
1640 KeyMap.push_back(SKeyMap(XK_y, KEY_KEY_Y)); 1640 KeyMap.push_back(SKeyMap(XK_y, KEY_KEY_Y));
1641 KeyMap.push_back(SKeyMap(XK_z, KEY_KEY_Z)); 1641 KeyMap.push_back(SKeyMap(XK_z, KEY_KEY_Z));
1642 KeyMap.push_back(SKeyMap(XK_ssharp, KEY_OEM_4)); 1642 KeyMap.push_back(SKeyMap(XK_ssharp, KEY_OEM_4));
1643 KeyMap.push_back(SKeyMap(XK_adiaeresis, KEY_OEM_7)); 1643 KeyMap.push_back(SKeyMap(XK_adiaeresis, KEY_OEM_7));
1644 KeyMap.push_back(SKeyMap(XK_odiaeresis, KEY_OEM_3)); 1644 KeyMap.push_back(SKeyMap(XK_odiaeresis, KEY_OEM_3));
1645 KeyMap.push_back(SKeyMap(XK_udiaeresis, KEY_OEM_1)); 1645 KeyMap.push_back(SKeyMap(XK_udiaeresis, KEY_OEM_1));
1646 KeyMap.push_back(SKeyMap(XK_Super_L, KEY_LWIN)); 1646 KeyMap.push_back(SKeyMap(XK_Super_L, KEY_LWIN));
1647 KeyMap.push_back(SKeyMap(XK_Super_R, KEY_RWIN)); 1647 KeyMap.push_back(SKeyMap(XK_Super_R, KEY_RWIN));
1648 1648
1649 KeyMap.sort(); 1649 KeyMap.sort();
1650#endif 1650#endif
1651} 1651}
1652 1652
1653bool CIrrDeviceLinux::activateJoysticks(core::array<SJoystickInfo> & joystickInfo) 1653bool CIrrDeviceLinux::activateJoysticks(core::array<SJoystickInfo> & joystickInfo)
1654{ 1654{
1655#if defined (_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) 1655#if defined (_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
1656 1656
1657 joystickInfo.clear(); 1657 joystickInfo.clear();
1658 1658
1659 u32 joystick; 1659 u32 joystick;
1660 for (joystick = 0; joystick < 32; ++joystick) 1660 for (joystick = 0; joystick < 32; ++joystick)
1661 { 1661 {
1662 // The joystick device could be here... 1662 // The joystick device could be here...
1663 core::stringc devName = "/dev/js"; 1663 core::stringc devName = "/dev/js";
1664 devName += joystick; 1664 devName += joystick;
1665 1665
1666 SJoystickInfo returnInfo; 1666 SJoystickInfo returnInfo;
1667 JoystickInfo info; 1667 JoystickInfo info;
1668 1668
1669 info.fd = open(devName.c_str(), O_RDONLY); 1669 info.fd = open(devName.c_str(), O_RDONLY);
1670 if (-1 == info.fd) 1670 if (-1 == info.fd)
1671 { 1671 {
1672 // ...but Ubuntu and possibly other distros 1672 // ...but Ubuntu and possibly other distros
1673 // create the devices in /dev/input 1673 // create the devices in /dev/input
1674 devName = "/dev/input/js"; 1674 devName = "/dev/input/js";
1675 devName += joystick; 1675 devName += joystick;
1676 info.fd = open(devName.c_str(), O_RDONLY); 1676 info.fd = open(devName.c_str(), O_RDONLY);
1677 if (-1 == info.fd) 1677 if (-1 == info.fd)
1678 { 1678 {
1679 // and BSD here 1679 // and BSD here
1680 devName = "/dev/joy"; 1680 devName = "/dev/joy";
1681 devName += joystick; 1681 devName += joystick;
1682 info.fd = open(devName.c_str(), O_RDONLY); 1682 info.fd = open(devName.c_str(), O_RDONLY);
1683 } 1683 }
1684 } 1684 }
1685 1685
1686 if (-1 == info.fd) 1686 if (-1 == info.fd)
1687 continue; 1687 continue;
1688 1688
1689#ifdef __FREE_BSD_ 1689#ifdef __FREE_BSD_
1690 info.axes=2; 1690 info.axes=2;
1691 info.buttons=2; 1691 info.buttons=2;
1692#else 1692#else
1693 ioctl( info.fd, JSIOCGAXES, &(info.axes) ); 1693 ioctl( info.fd, JSIOCGAXES, &(info.axes) );
1694 ioctl( info.fd, JSIOCGBUTTONS, &(info.buttons) ); 1694 ioctl( info.fd, JSIOCGBUTTONS, &(info.buttons) );
1695 fcntl( info.fd, F_SETFL, O_NONBLOCK ); 1695 fcntl( info.fd, F_SETFL, O_NONBLOCK );
1696#endif 1696#endif
1697 1697
1698 (void)memset(&info.persistentData, 0, sizeof(info.persistentData)); 1698 (void)memset(&info.persistentData, 0, sizeof(info.persistentData));
1699 info.persistentData.EventType = irr::EET_JOYSTICK_INPUT_EVENT; 1699 info.persistentData.EventType = irr::EET_JOYSTICK_INPUT_EVENT;
1700 info.persistentData.JoystickEvent.Joystick = ActiveJoysticks.size(); 1700 info.persistentData.JoystickEvent.Joystick = ActiveJoysticks.size();
1701 1701
1702 // There's no obvious way to determine which (if any) axes represent a POV 1702 // There's no obvious way to determine which (if any) axes represent a POV
1703 // hat, so we'll just set it to "not used" and forget about it. 1703 // hat, so we'll just set it to "not used" and forget about it.
1704 info.persistentData.JoystickEvent.POV = 65535; 1704 info.persistentData.JoystickEvent.POV = 65535;
1705 1705
1706 ActiveJoysticks.push_back(info); 1706 ActiveJoysticks.push_back(info);
1707 1707
1708 returnInfo.Joystick = joystick; 1708 returnInfo.Joystick = joystick;
1709 returnInfo.PovHat = SJoystickInfo::POV_HAT_UNKNOWN; 1709 returnInfo.PovHat = SJoystickInfo::POV_HAT_UNKNOWN;
1710 returnInfo.Axes = info.axes; 1710 returnInfo.Axes = info.axes;
1711 returnInfo.Buttons = info.buttons; 1711 returnInfo.Buttons = info.buttons;
1712 1712
1713#ifndef __FREE_BSD_ 1713#ifndef __FREE_BSD_
1714 char name[80]; 1714 char name[80];
1715 ioctl( info.fd, JSIOCGNAME(80), name); 1715 ioctl( info.fd, JSIOCGNAME(80), name);
1716 returnInfo.Name = name; 1716 returnInfo.Name = name;
1717#endif 1717#endif
1718 1718
1719 joystickInfo.push_back(returnInfo); 1719 joystickInfo.push_back(returnInfo);
1720 } 1720 }
1721 1721
1722 for (joystick = 0; joystick < joystickInfo.size(); ++joystick) 1722 for (joystick = 0; joystick < joystickInfo.size(); ++joystick)
1723 { 1723 {
1724 char logString[256]; 1724 char logString[256];
1725 (void)sprintf(logString, "Found joystick %u, %u axes, %u buttons '%s'", 1725 (void)sprintf(logString, "Found joystick %u, %u axes, %u buttons '%s'",
1726 joystick, joystickInfo[joystick].Axes, 1726 joystick, joystickInfo[joystick].Axes,
1727 joystickInfo[joystick].Buttons, joystickInfo[joystick].Name.c_str()); 1727 joystickInfo[joystick].Buttons, joystickInfo[joystick].Name.c_str());
1728 os::Printer::log(logString, ELL_INFORMATION); 1728 os::Printer::log(logString, ELL_INFORMATION);
1729 } 1729 }
1730 1730
1731 return true; 1731 return true;
1732#else 1732#else
1733 return false; 1733 return false;
1734#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ 1734#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
1735} 1735}
1736 1736
1737 1737
1738void CIrrDeviceLinux::pollJoysticks() 1738void CIrrDeviceLinux::pollJoysticks()
1739{ 1739{
1740#if defined (_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) 1740#if defined (_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
1741 if (0 == ActiveJoysticks.size()) 1741 if (0 == ActiveJoysticks.size())
1742 return; 1742 return;
1743 1743
1744 for (u32 j= 0; j< ActiveJoysticks.size(); ++j) 1744 for (u32 j= 0; j< ActiveJoysticks.size(); ++j)
1745 { 1745 {
1746 JoystickInfo & info = ActiveJoysticks[j]; 1746 JoystickInfo & info = ActiveJoysticks[j];
1747 1747
1748#ifdef __FREE_BSD_ 1748#ifdef __FREE_BSD_
1749 struct joystick js; 1749 struct joystick js;
1750 if (read(info.fd, &js, JS_RETURN) == JS_RETURN) 1750 if (read(info.fd, &js, JS_RETURN) == JS_RETURN)
1751 { 1751 {
1752 info.persistentData.JoystickEvent.ButtonStates = js.buttons; /* should be a two-bit field */ 1752 info.persistentData.JoystickEvent.ButtonStates = js.buttons; /* should be a two-bit field */
1753 info.persistentData.JoystickEvent.Axis[0] = js.x; /* X axis */ 1753 info.persistentData.JoystickEvent.Axis[0] = js.x; /* X axis */
1754 info.persistentData.JoystickEvent.Axis[1] = js.y; /* Y axis */ 1754 info.persistentData.JoystickEvent.Axis[1] = js.y; /* Y axis */
1755#else 1755#else
1756 struct js_event event; 1756 struct js_event event;
1757 while (sizeof(event) == read(info.fd, &event, sizeof(event))) 1757 while (sizeof(event) == read(info.fd, &event, sizeof(event)))
1758 { 1758 {
1759 switch(event.type & ~JS_EVENT_INIT) 1759 switch(event.type & ~JS_EVENT_INIT)
1760 { 1760 {
1761 case JS_EVENT_BUTTON: 1761 case JS_EVENT_BUTTON:
1762 if (event.value) 1762 if (event.value)
1763 info.persistentData.JoystickEvent.ButtonStates |= (1 << event.number); 1763 info.persistentData.JoystickEvent.ButtonStates |= (1 << event.number);
1764 else 1764 else
1765 info.persistentData.JoystickEvent.ButtonStates &= ~(1 << event.number); 1765 info.persistentData.JoystickEvent.ButtonStates &= ~(1 << event.number);
1766 break; 1766 break;
1767 1767
1768 case JS_EVENT_AXIS: 1768 case JS_EVENT_AXIS:
1769 if (event.number < SEvent::SJoystickEvent::NUMBER_OF_AXES) 1769 if (event.number < SEvent::SJoystickEvent::NUMBER_OF_AXES)
1770 info.persistentData.JoystickEvent.Axis[event.number] = event.value; 1770 info.persistentData.JoystickEvent.Axis[event.number] = event.value;
1771 break; 1771 break;
1772 1772
1773 default: 1773 default:
1774 break; 1774 break;
1775 } 1775 }
1776 } 1776 }
1777#endif 1777#endif
1778 1778
1779 // Send an irrlicht joystick event once per ::run() even if no new data were received. 1779 // Send an irrlicht joystick event once per ::run() even if no new data were received.
1780 (void)postEventFromUser(info.persistentData); 1780 (void)postEventFromUser(info.persistentData);
1781 } 1781 }
1782#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ 1782#endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
1783} 1783}
1784 1784
1785 1785
1786//! Set the current Gamma Value for the Display 1786//! Set the current Gamma Value for the Display
1787bool CIrrDeviceLinux::setGammaRamp( f32 red, f32 green, f32 blue, f32 brightness, f32 contrast ) 1787bool CIrrDeviceLinux::setGammaRamp( f32 red, f32 green, f32 blue, f32 brightness, f32 contrast )
1788{ 1788{
1789 #if defined(_IRR_LINUX_X11_VIDMODE_) || defined(_IRR_LINUX_X11_RANDR_) 1789 #if defined(_IRR_LINUX_X11_VIDMODE_) || defined(_IRR_LINUX_X11_RANDR_)
1790 s32 eventbase, errorbase; 1790 s32 eventbase, errorbase;
1791 #ifdef _IRR_LINUX_X11_VIDMODE_ 1791 #ifdef _IRR_LINUX_X11_VIDMODE_
1792 if (XF86VidModeQueryExtension(display, &eventbase, &errorbase)) 1792 if (XF86VidModeQueryExtension(display, &eventbase, &errorbase))
1793 { 1793 {
1794 XF86VidModeGamma gamma; 1794 XF86VidModeGamma gamma;
1795 gamma.red=red; 1795 gamma.red=red;
1796 gamma.green=green; 1796 gamma.green=green;
1797 gamma.blue=blue; 1797 gamma.blue=blue;
1798 XF86VidModeSetGamma(display, screennr, &gamma); 1798 XF86VidModeSetGamma(display, screennr, &gamma);
1799 return true; 1799 return true;
1800 } 1800 }
1801 #endif 1801 #endif
1802 #if defined(_IRR_LINUX_X11_VIDMODE_) && defined(_IRR_LINUX_X11_RANDR_) 1802 #if defined(_IRR_LINUX_X11_VIDMODE_) && defined(_IRR_LINUX_X11_RANDR_)
1803 else 1803 else
1804 #endif 1804 #endif
1805 #ifdef _IRR_LINUX_X11_RANDR_ 1805 #ifdef _IRR_LINUX_X11_RANDR_
1806 if (XRRQueryExtension(display, &eventbase, &errorbase)) 1806 if (XRRQueryExtension(display, &eventbase, &errorbase))
1807 { 1807 {
1808 XRRQueryVersion(display, &eventbase, &errorbase); // major, minor 1808 XRRQueryVersion(display, &eventbase, &errorbase); // major, minor
1809 if (eventbase>=1 && errorbase>1) 1809 if (eventbase>=1 && errorbase>1)
1810 { 1810 {
1811 #if (RANDR_MAJOR>1 || RANDR_MINOR>1) 1811 #if (RANDR_MAJOR>1 || RANDR_MINOR>1)
1812 XRRCrtcGamma *gamma = XRRGetCrtcGamma(display, screennr); 1812 XRRCrtcGamma *gamma = XRRGetCrtcGamma(display, screennr);
1813 if (gamma) 1813 if (gamma)
1814 { 1814 {
1815 *gamma->red=(u16)red; 1815 *gamma->red=(u16)red;
1816 *gamma->green=(u16)green; 1816 *gamma->green=(u16)green;
1817 *gamma->blue=(u16)blue; 1817 *gamma->blue=(u16)blue;
1818 XRRSetCrtcGamma(display, screennr, gamma); 1818 XRRSetCrtcGamma(display, screennr, gamma);
1819 XRRFreeGamma(gamma); 1819 XRRFreeGamma(gamma);
1820 return true; 1820 return true;
1821 } 1821 }
1822 #endif 1822 #endif
1823 } 1823 }
1824 } 1824 }
1825 #endif 1825 #endif
1826 #endif 1826 #endif
1827 return false; 1827 return false;
1828} 1828}
1829 1829
1830 1830
1831//! Get the current Gamma Value for the Display 1831//! Get the current Gamma Value for the Display
1832bool CIrrDeviceLinux::getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast ) 1832bool CIrrDeviceLinux::getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast )
1833{ 1833{
1834 brightness = 0.f; 1834 brightness = 0.f;
1835 contrast = 0.f; 1835 contrast = 0.f;
1836 #if defined(_IRR_LINUX_X11_VIDMODE_) || defined(_IRR_LINUX_X11_RANDR_) 1836 #if defined(_IRR_LINUX_X11_VIDMODE_) || defined(_IRR_LINUX_X11_RANDR_)
1837 s32 eventbase, errorbase; 1837 s32 eventbase, errorbase;
1838 #ifdef _IRR_LINUX_X11_VIDMODE_ 1838 #ifdef _IRR_LINUX_X11_VIDMODE_
1839 if (XF86VidModeQueryExtension(display, &eventbase, &errorbase)) 1839 if (XF86VidModeQueryExtension(display, &eventbase, &errorbase))
1840 { 1840 {
1841 XF86VidModeGamma gamma; 1841 XF86VidModeGamma gamma;
1842 XF86VidModeGetGamma(display, screennr, &gamma); 1842 XF86VidModeGetGamma(display, screennr, &gamma);
1843 red = gamma.red; 1843 red = gamma.red;
1844 green = gamma.green; 1844 green = gamma.green;
1845 blue = gamma.blue; 1845 blue = gamma.blue;
1846 return true; 1846 return true;
1847 } 1847 }
1848 #endif 1848 #endif
1849 #if defined(_IRR_LINUX_X11_VIDMODE_) && defined(_IRR_LINUX_X11_RANDR_) 1849 #if defined(_IRR_LINUX_X11_VIDMODE_) && defined(_IRR_LINUX_X11_RANDR_)
1850 else 1850 else
1851 #endif 1851 #endif
1852 #ifdef _IRR_LINUX_X11_RANDR_ 1852 #ifdef _IRR_LINUX_X11_RANDR_
1853 if (XRRQueryExtension(display, &eventbase, &errorbase)) 1853 if (XRRQueryExtension(display, &eventbase, &errorbase))
1854 { 1854 {
1855 XRRQueryVersion(display, &eventbase, &errorbase); // major, minor 1855 XRRQueryVersion(display, &eventbase, &errorbase); // major, minor
1856 if (eventbase>=1 && errorbase>1) 1856 if (eventbase>=1 && errorbase>1)
1857 { 1857 {
1858 #if (RANDR_MAJOR>1 || RANDR_MINOR>1) 1858 #if (RANDR_MAJOR>1 || RANDR_MINOR>1)
1859 XRRCrtcGamma *gamma = XRRGetCrtcGamma(display, screennr); 1859 XRRCrtcGamma *gamma = XRRGetCrtcGamma(display, screennr);
1860 if (gamma) 1860 if (gamma)
1861 { 1861 {
1862 red = *gamma->red; 1862 red = *gamma->red;
1863 green = *gamma->green; 1863 green = *gamma->green;
1864 blue= *gamma->blue; 1864 blue= *gamma->blue;
1865 XRRFreeGamma(gamma); 1865 XRRFreeGamma(gamma);
1866 return true; 1866 return true;
1867 } 1867 }
1868 #endif 1868 #endif
1869 } 1869 }
1870 } 1870 }
1871 #endif 1871 #endif
1872 #endif 1872 #endif
1873 return false; 1873 return false;
1874} 1874}
1875 1875
1876 1876
1877//! gets text from the clipboard 1877//! gets text from the clipboard
1878//! \return Returns 0 if no string is in there. 1878//! \return Returns 0 if no string is in there.
1879const c8* CIrrDeviceLinux::getTextFromClipboard() const 1879const c8* CIrrDeviceLinux::getTextFromClipboard() const
1880{ 1880{
1881#if defined(_IRR_COMPILE_WITH_X11_) 1881#if defined(_IRR_COMPILE_WITH_X11_)
1882 Window ownerWindow = XGetSelectionOwner (display, X_ATOM_CLIPBOARD); 1882 Window ownerWindow = XGetSelectionOwner (display, X_ATOM_CLIPBOARD);
1883 if ( ownerWindow == window ) 1883 if ( ownerWindow == window )
1884 { 1884 {
1885 return Clipboard.c_str(); 1885 return Clipboard.c_str();
1886 } 1886 }
1887 Clipboard = ""; 1887 Clipboard = "";
1888 if (ownerWindow != None ) 1888 if (ownerWindow != None )
1889 { 1889 {
1890 XConvertSelection (display, X_ATOM_CLIPBOARD, XA_STRING, None, ownerWindow, CurrentTime); 1890 XConvertSelection (display, X_ATOM_CLIPBOARD, XA_STRING, None, ownerWindow, CurrentTime);
1891 XFlush (display); 1891 XFlush (display);
1892 1892
1893 // check for data 1893 // check for data
1894 Atom type; 1894 Atom type;
1895 int format; 1895 int format;
1896 unsigned long numItems, bytesLeft, dummy; 1896 unsigned long numItems, bytesLeft, dummy;
1897 unsigned char *data; 1897 unsigned char *data;
1898 XGetWindowProperty (display, ownerWindow, 1898 XGetWindowProperty (display, ownerWindow,
1899 XA_STRING, // property name 1899 XA_STRING, // property name
1900 0, // offset 1900 0, // offset
1901 0, // length (we only check for data, so 0) 1901 0, // length (we only check for data, so 0)
1902 0, // Delete 0==false 1902 0, // Delete 0==false
1903 AnyPropertyType, // AnyPropertyType or property identifier 1903 AnyPropertyType, // AnyPropertyType or property identifier
1904 &type, // return type 1904 &type, // return type
1905 &format, // return format 1905 &format, // return format
1906 &numItems, // number items 1906 &numItems, // number items
1907 &bytesLeft, // remaining bytes for partial reads 1907 &bytesLeft, // remaining bytes for partial reads
1908 &data); // data 1908 &data); // data
1909 if ( bytesLeft > 0 ) 1909 if ( bytesLeft > 0 )
1910 { 1910 {
1911 // there is some data to get 1911 // there is some data to get
1912 int result = XGetWindowProperty (display, ownerWindow, XA_STRING, 0, 1912 int result = XGetWindowProperty (display, ownerWindow, XA_STRING, 0,
1913 bytesLeft, 0, AnyPropertyType, &type, &format, 1913 bytesLeft, 0, AnyPropertyType, &type, &format,
1914 &numItems, &dummy, &data); 1914 &numItems, &dummy, &data);
1915 if (result == Success) 1915 if (result == Success)
1916 Clipboard = (irr::c8*)data; 1916 Clipboard = (irr::c8*)data;
1917 XFree (data); 1917 XFree (data);
1918 } 1918 }
1919 } 1919 }
1920 1920
1921 return Clipboard.c_str(); 1921 return Clipboard.c_str();
1922 1922
1923#else 1923#else
1924 return 0; 1924 return 0;
1925#endif 1925#endif
1926} 1926}
1927 1927
1928//! copies text to the clipboard 1928//! copies text to the clipboard
1929void CIrrDeviceLinux::copyToClipboard(const c8* text) const 1929void CIrrDeviceLinux::copyToClipboard(const c8* text) const
1930{ 1930{
1931#if defined(_IRR_COMPILE_WITH_X11_) 1931#if defined(_IRR_COMPILE_WITH_X11_)
1932 // Actually there is no clipboard on X but applications just say they own the clipboard and return text when asked. 1932 // Actually there is no clipboard on X but applications just say they own the clipboard and return text when asked.
1933 // Which btw. also means that on X you lose clipboard content when closing applications. 1933 // Which btw. also means that on X you lose clipboard content when closing applications.
1934 Clipboard = text; 1934 Clipboard = text;
1935 XSetSelectionOwner (display, X_ATOM_CLIPBOARD, window, CurrentTime); 1935 XSetSelectionOwner (display, X_ATOM_CLIPBOARD, window, CurrentTime);
1936 XFlush (display); 1936 XFlush (display);
1937#endif 1937#endif
1938} 1938}
1939 1939
1940#ifdef _IRR_COMPILE_WITH_X11_ 1940#ifdef _IRR_COMPILE_WITH_X11_
1941// return true if the passed event has the type passed in parameter arg 1941// return true if the passed event has the type passed in parameter arg
1942Bool PredicateIsEventType(Display *display, XEvent *event, XPointer arg) 1942Bool PredicateIsEventType(Display *display, XEvent *event, XPointer arg)
1943{ 1943{
1944 if ( event && event->type == *(int*)arg ) 1944 if ( event && event->type == *(int*)arg )
1945 { 1945 {
1946// os::Printer::log("remove event:", core::stringc((int)arg).c_str(), ELL_INFORMATION); 1946// os::Printer::log("remove event:", core::stringc((int)arg).c_str(), ELL_INFORMATION);
1947 return True; 1947 return True;
1948 } 1948 }
1949 return False; 1949 return False;
1950} 1950}
1951#endif //_IRR_COMPILE_WITH_X11_ 1951#endif //_IRR_COMPILE_WITH_X11_
1952 1952
1953//! Remove all messages pending in the system message loop 1953//! Remove all messages pending in the system message loop
1954void CIrrDeviceLinux::clearSystemMessages() 1954void CIrrDeviceLinux::clearSystemMessages()
1955{ 1955{
1956#ifdef _IRR_COMPILE_WITH_X11_ 1956#ifdef _IRR_COMPILE_WITH_X11_
1957 if (CreationParams.DriverType != video::EDT_NULL) 1957 if (CreationParams.DriverType != video::EDT_NULL)
1958 { 1958 {
1959 XEvent event; 1959 XEvent event;
1960 int usrArg = ButtonPress; 1960 int usrArg = ButtonPress;
1961 while ( XCheckIfEvent(display, &event, PredicateIsEventType, XPointer(&usrArg)) == True ) {} 1961 while ( XCheckIfEvent(display, &event, PredicateIsEventType, XPointer(&usrArg)) == True ) {}
1962 usrArg = ButtonRelease; 1962 usrArg = ButtonRelease;
1963 while ( XCheckIfEvent(display, &event, PredicateIsEventType, XPointer(&usrArg)) == True ) {} 1963 while ( XCheckIfEvent(display, &event, PredicateIsEventType, XPointer(&usrArg)) == True ) {}
1964 usrArg = MotionNotify; 1964 usrArg = MotionNotify;
1965 while ( XCheckIfEvent(display, &event, PredicateIsEventType, XPointer(&usrArg)) == True ) {} 1965 while ( XCheckIfEvent(display, &event, PredicateIsEventType, XPointer(&usrArg)) == True ) {}
1966 usrArg = KeyRelease; 1966 usrArg = KeyRelease;
1967 while ( XCheckIfEvent(display, &event, PredicateIsEventType, XPointer(&usrArg)) == True ) {} 1967 while ( XCheckIfEvent(display, &event, PredicateIsEventType, XPointer(&usrArg)) == True ) {}
1968 usrArg = KeyPress; 1968 usrArg = KeyPress;
1969 while ( XCheckIfEvent(display, &event, PredicateIsEventType, XPointer(&usrArg)) == True ) {} 1969 while ( XCheckIfEvent(display, &event, PredicateIsEventType, XPointer(&usrArg)) == True ) {}
1970 } 1970 }
1971#endif //_IRR_COMPILE_WITH_X11_ 1971#endif //_IRR_COMPILE_WITH_X11_
1972} 1972}
1973 1973
1974void CIrrDeviceLinux::initXAtoms() 1974void CIrrDeviceLinux::initXAtoms()
1975{ 1975{
1976#ifdef _IRR_COMPILE_WITH_X11_ 1976#ifdef _IRR_COMPILE_WITH_X11_
1977 X_ATOM_CLIPBOARD = XInternAtom(display, "CLIPBOARD", False); 1977 X_ATOM_CLIPBOARD = XInternAtom(display, "CLIPBOARD", False);
1978 X_ATOM_TARGETS = XInternAtom(display, "TARGETS", False); 1978 X_ATOM_TARGETS = XInternAtom(display, "TARGETS", False);
1979 X_ATOM_UTF8_STRING = XInternAtom (display, "UTF8_STRING", False); 1979 X_ATOM_UTF8_STRING = XInternAtom (display, "UTF8_STRING", False);
1980 X_ATOM_TEXT = XInternAtom (display, "TEXT", False); 1980 X_ATOM_TEXT = XInternAtom (display, "TEXT", False);
1981#endif 1981#endif
1982} 1982}
1983 1983
1984 1984
1985#ifdef _IRR_COMPILE_WITH_X11_ 1985#ifdef _IRR_COMPILE_WITH_X11_
1986 1986
1987Cursor CIrrDeviceLinux::TextureToMonochromeCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot) 1987Cursor CIrrDeviceLinux::TextureToMonochromeCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot)
1988{ 1988{
1989 XImage * sourceImage = XCreateImage(display, visual->visual, 1989 XImage * sourceImage = XCreateImage(display, visual->visual,
1990 1, // depth, 1990 1, // depth,
1991 ZPixmap, // XYBitmap (depth=1), ZPixmap(depth=x) 1991 ZPixmap, // XYBitmap (depth=1), ZPixmap(depth=x)
1992 0, 0, sourceRect.getWidth(), sourceRect.getHeight(), 1992 0, 0, sourceRect.getWidth(), sourceRect.getHeight(),
1993 32, // bitmap_pad, 1993 32, // bitmap_pad,
1994 0// bytes_per_line (0 means continuos in memory) 1994 0// bytes_per_line (0 means continuos in memory)
1995 ); 1995 );
1996 sourceImage->data = new char[sourceImage->height * sourceImage->bytes_per_line]; 1996 sourceImage->data = new char[sourceImage->height * sourceImage->bytes_per_line];
1997 XImage * maskImage = XCreateImage(display, visual->visual, 1997 XImage * maskImage = XCreateImage(display, visual->visual,
1998 1, // depth, 1998 1, // depth,
1999 ZPixmap, 1999 ZPixmap,
2000 0, 0, sourceRect.getWidth(), sourceRect.getHeight(), 2000 0, 0, sourceRect.getWidth(), sourceRect.getHeight(),
2001 32, // bitmap_pad, 2001 32, // bitmap_pad,
2002 0 // bytes_per_line 2002 0 // bytes_per_line
2003 ); 2003 );
2004 maskImage->data = new char[maskImage->height * maskImage->bytes_per_line]; 2004 maskImage->data = new char[maskImage->height * maskImage->bytes_per_line];
2005 2005
2006 // write texture into XImage 2006 // write texture into XImage
2007 video::ECOLOR_FORMAT format = tex->getColorFormat(); 2007 video::ECOLOR_FORMAT format = tex->getColorFormat();
2008 u32 bytesPerPixel = video::IImage::getBitsPerPixelFromFormat(format) / 8; 2008 u32 bytesPerPixel = video::IImage::getBitsPerPixelFromFormat(format) / 8;
2009 u32 bytesLeftGap = sourceRect.UpperLeftCorner.X * bytesPerPixel; 2009 u32 bytesLeftGap = sourceRect.UpperLeftCorner.X * bytesPerPixel;
2010 u32 bytesRightGap = tex->getPitch() - sourceRect.LowerRightCorner.X * bytesPerPixel; 2010 u32 bytesRightGap = tex->getPitch() - sourceRect.LowerRightCorner.X * bytesPerPixel;
2011 const u8* data = (const u8*)tex->lock(video::ETLM_READ_ONLY, 0); 2011 const u8* data = (const u8*)tex->lock(video::ETLM_READ_ONLY, 0);
2012 data += sourceRect.UpperLeftCorner.Y*tex->getPitch(); 2012 data += sourceRect.UpperLeftCorner.Y*tex->getPitch();
2013 for ( s32 y = 0; y < sourceRect.getHeight(); ++y ) 2013 for ( s32 y = 0; y < sourceRect.getHeight(); ++y )
2014 { 2014 {
2015 data += bytesLeftGap; 2015 data += bytesLeftGap;
2016 for ( s32 x = 0; x < sourceRect.getWidth(); ++x ) 2016 for ( s32 x = 0; x < sourceRect.getWidth(); ++x )
2017 { 2017 {
2018 video::SColor pixelCol; 2018 video::SColor pixelCol;
2019 pixelCol.setData((const void*)data, format); 2019 pixelCol.setData((const void*)data, format);
2020 data += bytesPerPixel; 2020 data += bytesPerPixel;
2021 2021
2022 if ( pixelCol.getAlpha() == 0 ) // transparent 2022 if ( pixelCol.getAlpha() == 0 ) // transparent
2023 { 2023 {
2024 XPutPixel(maskImage, x, y, 0); 2024 XPutPixel(maskImage, x, y, 0);
2025 XPutPixel(sourceImage, x, y, 0); 2025 XPutPixel(sourceImage, x, y, 0);
2026 } 2026 }
2027 else // color 2027 else // color
2028 { 2028 {
2029 if ( pixelCol.getAverage() >= 127 ) 2029 if ( pixelCol.getAverage() >= 127 )
2030 XPutPixel(sourceImage, x, y, 1); 2030 XPutPixel(sourceImage, x, y, 1);
2031 else 2031 else
2032 XPutPixel(sourceImage, x, y, 0); 2032 XPutPixel(sourceImage, x, y, 0);
2033 XPutPixel(maskImage, x, y, 1); 2033 XPutPixel(maskImage, x, y, 1);
2034 } 2034 }
2035 } 2035 }
2036 data += bytesRightGap; 2036 data += bytesRightGap;
2037 } 2037 }
2038 tex->unlock(); 2038 tex->unlock();
2039 2039
2040 Pixmap sourcePixmap = XCreatePixmap(display, window, sourceImage->width, sourceImage->height, sourceImage->depth); 2040 Pixmap sourcePixmap = XCreatePixmap(display, window, sourceImage->width, sourceImage->height, sourceImage->depth);
2041 Pixmap maskPixmap = XCreatePixmap(display, window, maskImage->width, maskImage->height, maskImage->depth); 2041 Pixmap maskPixmap = XCreatePixmap(display, window, maskImage->width, maskImage->height, maskImage->depth);
2042 2042
2043 XGCValues values; 2043 XGCValues values;
2044 values.foreground = 1; 2044 values.foreground = 1;
2045 values.background = 1; 2045 values.background = 1;
2046 GC gc = XCreateGC( display, sourcePixmap, GCForeground | GCBackground, &values ); 2046 GC gc = XCreateGC( display, sourcePixmap, GCForeground | GCBackground, &values );
2047 2047
2048 XPutImage(display, sourcePixmap, gc, sourceImage, 0, 0, 0, 0, sourceImage->width, sourceImage->height); 2048 XPutImage(display, sourcePixmap, gc, sourceImage, 0, 0, 0, 0, sourceImage->width, sourceImage->height);
2049 XPutImage(display, maskPixmap, gc, maskImage, 0, 0, 0, 0, maskImage->width, maskImage->height); 2049 XPutImage(display, maskPixmap, gc, maskImage, 0, 0, 0, 0, maskImage->width, maskImage->height);
2050 2050
2051 XFreeGC(display, gc); 2051 XFreeGC(display, gc);
2052 XDestroyImage(sourceImage); 2052 XDestroyImage(sourceImage);
2053 XDestroyImage(maskImage); 2053 XDestroyImage(maskImage);
2054 2054
2055 Cursor cursorResult = 0; 2055 Cursor cursorResult = 0;
2056 XColor foreground, background; 2056 XColor foreground, background;
2057 foreground.red = 65535; 2057 foreground.red = 65535;
2058 foreground.green = 65535; 2058 foreground.green = 65535;
2059 foreground.blue = 65535; 2059 foreground.blue = 65535;
2060 foreground.flags = DoRed | DoGreen | DoBlue; 2060 foreground.flags = DoRed | DoGreen | DoBlue;
2061 background.red = 0; 2061 background.red = 0;
2062 background.green = 0; 2062 background.green = 0;
2063 background.blue = 0; 2063 background.blue = 0;
2064 background.flags = DoRed | DoGreen | DoBlue; 2064 background.flags = DoRed | DoGreen | DoBlue;
2065 2065
2066 cursorResult = XCreatePixmapCursor(display, sourcePixmap, maskPixmap, &foreground, &background, hotspot.X, hotspot.Y); 2066 cursorResult = XCreatePixmapCursor(display, sourcePixmap, maskPixmap, &foreground, &background, hotspot.X, hotspot.Y);
2067 2067
2068 XFreePixmap(display, sourcePixmap); 2068 XFreePixmap(display, sourcePixmap);
2069 XFreePixmap(display, maskPixmap); 2069 XFreePixmap(display, maskPixmap);
2070 2070
2071 return cursorResult; 2071 return cursorResult;
2072} 2072}
2073 2073
2074#ifdef _IRR_LINUX_XCURSOR_ 2074#ifdef _IRR_LINUX_XCURSOR_
2075Cursor CIrrDeviceLinux::TextureToARGBCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot) 2075Cursor CIrrDeviceLinux::TextureToARGBCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot)
2076{ 2076{
2077 XcursorImage * image = XcursorImageCreate (sourceRect.getWidth(), sourceRect.getHeight()); 2077 XcursorImage * image = XcursorImageCreate (sourceRect.getWidth(), sourceRect.getHeight());
2078 image->xhot = hotspot.X; 2078 image->xhot = hotspot.X;
2079 image->yhot = hotspot.Y; 2079 image->yhot = hotspot.Y;
2080 2080
2081 // write texture into XcursorImage 2081 // write texture into XcursorImage
2082 video::ECOLOR_FORMAT format = tex->getColorFormat(); 2082 video::ECOLOR_FORMAT format = tex->getColorFormat();
2083 u32 bytesPerPixel = video::IImage::getBitsPerPixelFromFormat(format) / 8; 2083 u32 bytesPerPixel = video::IImage::getBitsPerPixelFromFormat(format) / 8;
2084 u32 bytesLeftGap = sourceRect.UpperLeftCorner.X * bytesPerPixel; 2084 u32 bytesLeftGap = sourceRect.UpperLeftCorner.X * bytesPerPixel;
2085 u32 bytesRightGap = tex->getPitch() - sourceRect.LowerRightCorner.X * bytesPerPixel; 2085 u32 bytesRightGap = tex->getPitch() - sourceRect.LowerRightCorner.X * bytesPerPixel;
2086 XcursorPixel* target = image->pixels; 2086 XcursorPixel* target = image->pixels;
2087 const u8* data = (const u8*)tex->lock(ETLM_READ_ONLY, 0); 2087 const u8* data = (const u8*)tex->lock(ETLM_READ_ONLY, 0);
2088 data += sourceRect.UpperLeftCorner.Y*tex->getPitch(); 2088 data += sourceRect.UpperLeftCorner.Y*tex->getPitch();
2089 for ( s32 y = 0; y < sourceRect.getHeight(); ++y ) 2089 for ( s32 y = 0; y < sourceRect.getHeight(); ++y )
2090 { 2090 {
2091 data += bytesLeftGap; 2091 data += bytesLeftGap;
2092 for ( s32 x = 0; x < sourceRect.getWidth(); ++x ) 2092 for ( s32 x = 0; x < sourceRect.getWidth(); ++x )
2093 { 2093 {
2094 video::SColor pixelCol; 2094 video::SColor pixelCol;
2095 pixelCol.setData((const void*)data, format); 2095 pixelCol.setData((const void*)data, format);
2096 data += bytesPerPixel; 2096 data += bytesPerPixel;
2097 2097
2098 *target = (XcursorPixel)pixelCol.color; 2098 *target = (XcursorPixel)pixelCol.color;
2099 ++target; 2099 ++target;
2100 } 2100 }
2101 data += bytesRightGap; 2101 data += bytesRightGap;
2102 } 2102 }
2103 tex->unlock(); 2103 tex->unlock();
2104 2104
2105 Cursor cursorResult=XcursorImageLoadCursor(display, image); 2105 Cursor cursorResult=XcursorImageLoadCursor(display, image);
2106 2106
2107 XcursorImageDestroy(image); 2107 XcursorImageDestroy(image);
2108 2108
2109 2109
2110 return cursorResult; 2110 return cursorResult;
2111} 2111}
2112#endif // #ifdef _IRR_LINUX_XCURSOR_ 2112#endif // #ifdef _IRR_LINUX_XCURSOR_
2113 2113
2114Cursor CIrrDeviceLinux::TextureToCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot) 2114Cursor CIrrDeviceLinux::TextureToCursor(irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot)
2115{ 2115{
2116#ifdef _IRR_LINUX_XCURSOR_ 2116#ifdef _IRR_LINUX_XCURSOR_
2117 return TextureToARGBCursor( tex, sourceRect, hotspot ); 2117 return TextureToARGBCursor( tex, sourceRect, hotspot );
2118#else 2118#else
2119 return TextureToMonochromeCursor( tex, sourceRect, hotspot ); 2119 return TextureToMonochromeCursor( tex, sourceRect, hotspot );
2120#endif 2120#endif
2121} 2121}
2122#endif // _IRR_COMPILE_WITH_X11_ 2122#endif // _IRR_COMPILE_WITH_X11_
2123 2123
2124 2124
2125CIrrDeviceLinux::CCursorControl::CCursorControl(CIrrDeviceLinux* dev, bool null) 2125CIrrDeviceLinux::CCursorControl::CCursorControl(CIrrDeviceLinux* dev, bool null)
2126 : Device(dev) 2126 : Device(dev)
2127#ifdef _IRR_COMPILE_WITH_X11_ 2127#ifdef _IRR_COMPILE_WITH_X11_
2128 , PlatformBehavior(gui::ECPB_NONE), lastQuery(0) 2128 , PlatformBehavior(gui::ECPB_NONE), lastQuery(0)
2129#endif 2129#endif
2130 , IsVisible(true), Null(null), UseReferenceRect(false) 2130 , IsVisible(true), Null(null), UseReferenceRect(false)
2131 , ActiveIcon(gui::ECI_NORMAL), ActiveIconStartTime(0) 2131 , ActiveIcon(gui::ECI_NORMAL), ActiveIconStartTime(0)
2132{ 2132{
2133#ifdef _IRR_COMPILE_WITH_X11_ 2133#ifdef _IRR_COMPILE_WITH_X11_
2134 if (!Null) 2134 if (!Null)
2135 { 2135 {
2136 XGCValues values; 2136 XGCValues values;
2137 unsigned long valuemask = 0; 2137 unsigned long valuemask = 0;
2138 2138
2139 XColor fg, bg; 2139 XColor fg, bg;
2140 2140
2141 // this code, for making the cursor invisible was sent in by 2141 // this code, for making the cursor invisible was sent in by
2142 // Sirshane, thank your very much! 2142 // Sirshane, thank your very much!
2143 2143
2144 2144
2145 Pixmap invisBitmap = XCreatePixmap(Device->display, Device->window, 32, 32, 1); 2145 Pixmap invisBitmap = XCreatePixmap(Device->display, Device->window, 32, 32, 1);
2146 Pixmap maskBitmap = XCreatePixmap(Device->display, Device->window, 32, 32, 1); 2146 Pixmap maskBitmap = XCreatePixmap(Device->display, Device->window, 32, 32, 1);
2147 Colormap screen_colormap = DefaultColormap( Device->display, DefaultScreen( Device->display ) ); 2147 Colormap screen_colormap = DefaultColormap( Device->display, DefaultScreen( Device->display ) );
2148 XAllocNamedColor( Device->display, screen_colormap, "black", &fg, &fg ); 2148 XAllocNamedColor( Device->display, screen_colormap, "black", &fg, &fg );
2149 XAllocNamedColor( Device->display, screen_colormap, "white", &bg, &bg ); 2149 XAllocNamedColor( Device->display, screen_colormap, "white", &bg, &bg );
2150 2150
2151 GC gc = XCreateGC( Device->display, invisBitmap, valuemask, &values ); 2151 GC gc = XCreateGC( Device->display, invisBitmap, valuemask, &values );
2152 2152
2153 XSetForeground( Device->display, gc, BlackPixel( Device->display, DefaultScreen( Device->display ) ) ); 2153 XSetForeground( Device->display, gc, BlackPixel( Device->display, DefaultScreen( Device->display ) ) );
2154 XFillRectangle( Device->display, invisBitmap, gc, 0, 0, 32, 32 ); 2154 XFillRectangle( Device->display, invisBitmap, gc, 0, 0, 32, 32 );
2155 XFillRectangle( Device->display, maskBitmap, gc, 0, 0, 32, 32 ); 2155 XFillRectangle( Device->display, maskBitmap, gc, 0, 0, 32, 32 );
2156 2156
2157 invisCursor = XCreatePixmapCursor( Device->display, invisBitmap, maskBitmap, &fg, &bg, 1, 1 ); 2157 invisCursor = XCreatePixmapCursor( Device->display, invisBitmap, maskBitmap, &fg, &bg, 1, 1 );
2158 XFreeGC(Device->display, gc); 2158 XFreeGC(Device->display, gc);
2159 XFreePixmap(Device->display, invisBitmap); 2159 XFreePixmap(Device->display, invisBitmap);
2160 XFreePixmap(Device->display, maskBitmap); 2160 XFreePixmap(Device->display, maskBitmap);
2161 2161
2162 initCursors(); 2162 initCursors();
2163 } 2163 }
2164#endif 2164#endif
2165} 2165}
2166 2166
2167CIrrDeviceLinux::CCursorControl::~CCursorControl() 2167CIrrDeviceLinux::CCursorControl::~CCursorControl()
2168{ 2168{
2169 // Do not clearCursors here as the display is already closed 2169 // Do not clearCursors here as the display is already closed
2170 // TODO (cutealien): droping cursorcontrol earlier might work, not sure about reason why that's done in stub currently. 2170 // TODO (cutealien): droping cursorcontrol earlier might work, not sure about reason why that's done in stub currently.
2171} 2171}
2172 2172
2173#ifdef _IRR_COMPILE_WITH_X11_ 2173#ifdef _IRR_COMPILE_WITH_X11_
2174void CIrrDeviceLinux::CCursorControl::clearCursors() 2174void CIrrDeviceLinux::CCursorControl::clearCursors()
2175{ 2175{
2176 if (!Null) 2176 if (!Null)
2177 XFreeCursor(Device->display, invisCursor); 2177 XFreeCursor(Device->display, invisCursor);
2178 for ( u32 i=0; i < Cursors.size(); ++i ) 2178 for ( u32 i=0; i < Cursors.size(); ++i )
2179 { 2179 {
2180 for ( u32 f=0; f < Cursors[i].Frames.size(); ++f ) 2180 for ( u32 f=0; f < Cursors[i].Frames.size(); ++f )
2181 { 2181 {
2182 XFreeCursor(Device->display, Cursors[i].Frames[f].IconHW); 2182 XFreeCursor(Device->display, Cursors[i].Frames[f].IconHW);
2183 } 2183 }
2184 } 2184 }
2185} 2185}
2186 2186
2187void CIrrDeviceLinux::CCursorControl::initCursors() 2187void CIrrDeviceLinux::CCursorControl::initCursors()
2188{ 2188{
2189 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_top_left_arrow)) ); // (or XC_arrow?) 2189 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_top_left_arrow)) ); // (or XC_arrow?)
2190 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_crosshair)) ); 2190 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_crosshair)) );
2191 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_hand2)) ); // (or XC_hand1? ) 2191 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_hand2)) ); // (or XC_hand1? )
2192 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_question_arrow)) ); 2192 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_question_arrow)) );
2193 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_xterm)) ); 2193 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_xterm)) );
2194 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_X_cursor)) ); // (or XC_pirate?) 2194 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_X_cursor)) ); // (or XC_pirate?)
2195 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_watch)) ); // (or XC_clock?) 2195 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_watch)) ); // (or XC_clock?)
2196 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_fleur)) ); 2196 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_fleur)) );
2197 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_top_right_corner)) ); // NESW not available in X11 2197 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_top_right_corner)) ); // NESW not available in X11
2198 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_top_left_corner)) ); // NWSE not available in X11 2198 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_top_left_corner)) ); // NWSE not available in X11
2199 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_sb_v_double_arrow)) ); 2199 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_sb_v_double_arrow)) );
2200 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_sb_h_double_arrow)) ); 2200 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_sb_h_double_arrow)) );
2201 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_sb_up_arrow)) ); // (or XC_center_ptr?) 2201 Cursors.push_back( CursorX11(XCreateFontCursor(Device->display, XC_sb_up_arrow)) ); // (or XC_center_ptr?)
2202} 2202}
2203 2203
2204void CIrrDeviceLinux::CCursorControl::update() 2204void CIrrDeviceLinux::CCursorControl::update()
2205{ 2205{
2206 if ( (u32)ActiveIcon < Cursors.size() && !Cursors[ActiveIcon].Frames.empty() && Cursors[ActiveIcon].FrameTime ) 2206 if ( (u32)ActiveIcon < Cursors.size() && !Cursors[ActiveIcon].Frames.empty() && Cursors[ActiveIcon].FrameTime )
2207 { 2207 {
2208 // update animated cursors. This could also be done by X11 in case someone wants to figure that out (this way was just easier to implement) 2208 // update animated cursors. This could also be done by X11 in case someone wants to figure that out (this way was just easier to implement)
2209 u32 now = Device->getTimer()->getRealTime(); 2209 u32 now = Device->getTimer()->getRealTime();
2210 u32 frame = ((now - ActiveIconStartTime) / Cursors[ActiveIcon].FrameTime) % Cursors[ActiveIcon].Frames.size(); 2210 u32 frame = ((now - ActiveIconStartTime) / Cursors[ActiveIcon].FrameTime) % Cursors[ActiveIcon].Frames.size();
2211 XDefineCursor(Device->display, Device->window, Cursors[ActiveIcon].Frames[frame].IconHW); 2211 XDefineCursor(Device->display, Device->window, Cursors[ActiveIcon].Frames[frame].IconHW);
2212 } 2212 }
2213} 2213}
2214#endif 2214#endif
2215 2215
2216//! Sets the active cursor icon 2216//! Sets the active cursor icon
2217void CIrrDeviceLinux::CCursorControl::setActiveIcon(gui::ECURSOR_ICON iconId) 2217void CIrrDeviceLinux::CCursorControl::setActiveIcon(gui::ECURSOR_ICON iconId)
2218{ 2218{
2219#ifdef _IRR_COMPILE_WITH_X11_ 2219#ifdef _IRR_COMPILE_WITH_X11_
2220 if ( iconId >= (s32)Cursors.size() ) 2220 if ( iconId >= (s32)Cursors.size() )
2221 return; 2221 return;
2222 2222
2223 if ( Cursors[iconId].Frames.size() ) 2223 if ( Cursors[iconId].Frames.size() )
2224 XDefineCursor(Device->display, Device->window, Cursors[iconId].Frames[0].IconHW); 2224 XDefineCursor(Device->display, Device->window, Cursors[iconId].Frames[0].IconHW);
2225 2225
2226 ActiveIconStartTime = Device->getTimer()->getRealTime(); 2226 ActiveIconStartTime = Device->getTimer()->getRealTime();
2227 ActiveIcon = iconId; 2227 ActiveIcon = iconId;
2228#endif 2228#endif
2229} 2229}
2230 2230
2231 2231
2232//! Add a custom sprite as cursor icon. 2232//! Add a custom sprite as cursor icon.
2233gui::ECURSOR_ICON CIrrDeviceLinux::CCursorControl::addIcon(const gui::SCursorSprite& icon) 2233gui::ECURSOR_ICON CIrrDeviceLinux::CCursorControl::addIcon(const gui::SCursorSprite& icon)
2234{ 2234{
2235#ifdef _IRR_COMPILE_WITH_X11_ 2235#ifdef _IRR_COMPILE_WITH_X11_
2236 if ( icon.SpriteId >= 0 ) 2236 if ( icon.SpriteId >= 0 )
2237 { 2237 {
2238 CursorX11 cX11; 2238 CursorX11 cX11;
2239 cX11.FrameTime = icon.SpriteBank->getSprites()[icon.SpriteId].frameTime; 2239 cX11.FrameTime = icon.SpriteBank->getSprites()[icon.SpriteId].frameTime;
2240 for ( u32 i=0; i < icon.SpriteBank->getSprites()[icon.SpriteId].Frames.size(); ++i ) 2240 for ( u32 i=0; i < icon.SpriteBank->getSprites()[icon.SpriteId].Frames.size(); ++i )
2241 { 2241 {
2242 irr::u32 texId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].textureNumber; 2242 irr::u32 texId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].textureNumber;
2243 irr::u32 rectId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].rectNumber; 2243 irr::u32 rectId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].rectNumber;
2244 irr::core::rect<s32> rectIcon = icon.SpriteBank->getPositions()[rectId]; 2244 irr::core::rect<s32> rectIcon = icon.SpriteBank->getPositions()[rectId];
2245 Cursor cursor = Device->TextureToCursor(icon.SpriteBank->getTexture(texId), rectIcon, icon.HotSpot); 2245 Cursor cursor = Device->TextureToCursor(icon.SpriteBank->getTexture(texId), rectIcon, icon.HotSpot);
2246 cX11.Frames.push_back( CursorFrameX11(cursor) ); 2246 cX11.Frames.push_back( CursorFrameX11(cursor) );
2247 } 2247 }
2248 2248
2249 Cursors.push_back( cX11 ); 2249 Cursors.push_back( cX11 );
2250 2250
2251 return (gui::ECURSOR_ICON)(Cursors.size() - 1); 2251 return (gui::ECURSOR_ICON)(Cursors.size() - 1);
2252 } 2252 }
2253#endif 2253#endif
2254 return gui::ECI_NORMAL; 2254 return gui::ECI_NORMAL;
2255} 2255}
2256 2256
2257//! replace the given cursor icon. 2257//! replace the given cursor icon.
2258void CIrrDeviceLinux::CCursorControl::changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite& icon) 2258void CIrrDeviceLinux::CCursorControl::changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite& icon)
2259{ 2259{
2260#ifdef _IRR_COMPILE_WITH_X11_ 2260#ifdef _IRR_COMPILE_WITH_X11_
2261 if ( iconId >= (s32)Cursors.size() ) 2261 if ( iconId >= (s32)Cursors.size() )
2262 return; 2262 return;
2263 2263
2264 for ( u32 i=0; i < Cursors[iconId].Frames.size(); ++i ) 2264 for ( u32 i=0; i < Cursors[iconId].Frames.size(); ++i )
2265 XFreeCursor(Device->display, Cursors[iconId].Frames[i].IconHW); 2265 XFreeCursor(Device->display, Cursors[iconId].Frames[i].IconHW);
2266 2266
2267 if ( icon.SpriteId >= 0 ) 2267 if ( icon.SpriteId >= 0 )
2268 { 2268 {
2269 CursorX11 cX11; 2269 CursorX11 cX11;
2270 cX11.FrameTime = icon.SpriteBank->getSprites()[icon.SpriteId].frameTime; 2270 cX11.FrameTime = icon.SpriteBank->getSprites()[icon.SpriteId].frameTime;
2271 for ( u32 i=0; i < icon.SpriteBank->getSprites()[icon.SpriteId].Frames.size(); ++i ) 2271 for ( u32 i=0; i < icon.SpriteBank->getSprites()[icon.SpriteId].Frames.size(); ++i )
2272 { 2272 {
2273 irr::u32 texId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].textureNumber; 2273 irr::u32 texId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].textureNumber;
2274 irr::u32 rectId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].rectNumber; 2274 irr::u32 rectId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].rectNumber;
2275 irr::core::rect<s32> rectIcon = icon.SpriteBank->getPositions()[rectId]; 2275 irr::core::rect<s32> rectIcon = icon.SpriteBank->getPositions()[rectId];
2276 Cursor cursor = Device->TextureToCursor(icon.SpriteBank->getTexture(texId), rectIcon, icon.HotSpot); 2276 Cursor cursor = Device->TextureToCursor(icon.SpriteBank->getTexture(texId), rectIcon, icon.HotSpot);
2277 cX11.Frames.push_back( CursorFrameX11(cursor) ); 2277 cX11.Frames.push_back( CursorFrameX11(cursor) );
2278 } 2278 }
2279 2279
2280 Cursors[iconId] = cX11; 2280 Cursors[iconId] = cX11;
2281 } 2281 }
2282#endif 2282#endif
2283} 2283}
2284 2284
2285irr::core::dimension2di CIrrDeviceLinux::CCursorControl::getSupportedIconSize() const 2285irr::core::dimension2di CIrrDeviceLinux::CCursorControl::getSupportedIconSize() const
2286{ 2286{
2287 // this returns the closest match that is smaller or same size, so we just pass a value which should be large enough for cursors 2287 // this returns the closest match that is smaller or same size, so we just pass a value which should be large enough for cursors
2288 unsigned int width=0, height=0; 2288 unsigned int width=0, height=0;
2289#ifdef _IRR_COMPILE_WITH_X11_ 2289#ifdef _IRR_COMPILE_WITH_X11_
2290 XQueryBestCursor(Device->display, Device->window, 64, 64, &width, &height); 2290 XQueryBestCursor(Device->display, Device->window, 64, 64, &width, &height);
2291#endif 2291#endif
2292 return core::dimension2di(width, height); 2292 return core::dimension2di(width, height);
2293} 2293}
2294 2294
2295} // end namespace 2295} // end namespace
2296 2296
2297#endif // _IRR_COMPILE_WITH_X11_DEVICE_ 2297#endif // _IRR_COMPILE_WITH_X11_DEVICE_
2298 2298