~ubuntu-branches/ubuntu/oneiric/nux/oneiric

« back to all changes in this revision

Viewing changes to NuxGraphics/GfxSetupX11.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2010-11-18 19:17:32 UTC
  • Revision ID: james.westby@ubuntu.com-20101118191732-rn35790vekj6o4my
Tags: upstream-0.9.4
ImportĀ upstreamĀ versionĀ 0.9.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2010 Inalogic Inc.
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify it
 
5
 * under the terms of the GNU Lesser General Public License version 3, as
 
6
 * published by the  Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful, but
 
9
 * WITHOUT ANY WARRANTY; without even the implied warranties of
 
10
 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
 
11
 * PURPOSE.  See the applicable version of the GNU Lesser General Public
 
12
 * License for more details.
 
13
 *
 
14
 * You should have received a copy of both the GNU Lesser General Public
 
15
 * License version 3 along with this program.  If not, see
 
16
 * <http://www.gnu.org/licenses/>
 
17
 *
 
18
 * Authored by: Jay Taoko <jay.taoko_AT_gmail_DOT_com>
 
19
 *
 
20
 */
 
21
 
 
22
 
 
23
#include "GLResource.h"
 
24
#include "GpuDevice.h"
 
25
#include "GLDeviceObjects.h"
 
26
#include "GLResourceManager.h"
 
27
 
 
28
#include "GLTextureResourceManager.h"
 
29
#include "GLVertexResourceManager.h"
 
30
#include "GraphicsEngine.h"
 
31
#include "GLWindowManager.h"
 
32
#include "Events.h"
 
33
#include "IniFile.h"
 
34
 
 
35
#include "GfxSetupX11.h"
 
36
 
 
37
namespace nux
 
38
{
 
39
 
 
40
  unsigned int gVirtualKeycodeState[NUX_MAX_VK];
 
41
 
 
42
// Attributes for a single buffered visual in RGBA format
 
43
  static int g_DoubleBufferVisual[] =
 
44
  {
 
45
    GLX_RGBA,
 
46
    GLX_DOUBLEBUFFER,
 
47
    GLX_RED_SIZE,       8,
 
48
    GLX_GREEN_SIZE,     8,
 
49
    GLX_BLUE_SIZE,      8,
 
50
    GLX_ALPHA_SIZE,     8,
 
51
    GLX_DEPTH_SIZE,     24,
 
52
    GLX_STENCIL_SIZE,   8,
 
53
    None
 
54
  };
 
55
 
 
56
// Attributes for a single buffered visual in RGBA format
 
57
// static int g_SingleBufferVisual[] = {
 
58
//     GLX_RGBA,
 
59
//     GLX_RED_SIZE,       8,
 
60
//     GLX_GREEN_SIZE,     8,
 
61
//     GLX_BLUE_SIZE,      8,
 
62
//     GLX_ALPHA_SIZE,     8,
 
63
//     GLX_DEPTH_SIZE,     24,
 
64
//     GLX_STENCIL_SIZE,   8,
 
65
//     None };
 
66
 
 
67
// Compute the frame rate every FRAME_RATE_PERIODE;
 
68
#define FRAME_RATE_PERIODE    10
 
69
 
 
70
#define NUX_MISSING_GL_EXTENSION_MESSAGE_BOX(message) {MessageBox(NULL, TEXT("Missing extension: " #message), TEXT("ERROR"), MB_OK|MB_ICONERROR); exit(-1);}
 
71
#define NUX_ERROR_EXIT_MESSAGE(message) inlWin32MessageBox(NULL, TEXT("Error"), MBTYPE_Ok, MBICON_Error, MBMODAL_ApplicationModal, #message " The program will exit.")); exit(-1);
 
72
 
 
73
  EventToNameStruct EventToName[] =
 
74
  {
 
75
    {NUX_NO_EVENT,               TEXT ("NUX_NO_EVENT") },
 
76
    {NUX_MOUSE_PRESSED,          TEXT ("NUX_MOUSE_PRESSED") },
 
77
    {NUX_MOUSE_RELEASED,         TEXT ("NUX_MOUSE_RELEASED") },
 
78
    {NUX_KEYDOWN,                TEXT ("NUX_KEYDOWN") },
 
79
    {NUX_KEYUP,                  TEXT ("NUX_KEYUP") },
 
80
    {NUX_MOUSE_MOVE,             TEXT ("NUX_MOUSE_MOVE") },
 
81
    {NUX_SIZE_CONFIGURATION,     TEXT ("NUX_SIZE_CONFIGURATION") },
 
82
    {NUX_WINDOW_CONFIGURATION,   TEXT ("NUX_WINDOW_CONFIGURATION") },
 
83
    {NUX_WINDOW_ENTER_FOCUS,     TEXT ("NUX_WINDOW_ENTER_FOCUS") },
 
84
    {NUX_WINDOW_EXIT_FOCUS,      TEXT ("NUX_WINDOW_EXIT_FOCUS") },
 
85
    {NUX_WINDOW_DIRTY,           TEXT ("NUX_WINDOW_DIRTY") },
 
86
    {NUX_WINDOW_MOUSELEAVE,      TEXT ("NUX_WINDOW_MOUSELEAVE") },
 
87
    {NUX_TERMINATE_APP,          TEXT ("NUX_TERMINATE_APP") }
 
88
  };
 
89
 
 
90
//---------------------------------------------------------------------------------------------------------
 
91
 
 
92
  GLWindowImpl::GLWindowImpl()
 
93
  {
 
94
    m_ParentWindow                  = 0;
 
95
    m_GLCtx                         = 0;
 
96
    m_Fullscreen                    = false;
 
97
    m_GfxInterfaceCreated           = false;
 
98
    m_pEvent                        = NULL;
 
99
    m_ScreenBitDepth                = 32;
 
100
    m_BestMode                      = -1;
 
101
    m_num_device_modes              = 0;
 
102
    m_DeviceFactory                 = 0;
 
103
    m_GraphicsContext               = 0;
 
104
    m_Style                         = WINDOWSTYLE_NORMAL;
 
105
    m_PauseGraphicsRendering        = false;
 
106
 
 
107
    inlSetThreadLocalStorage (ThreadLocal_GLWindowImpl, this);
 
108
 
 
109
    m_X11LastEvent.type = -1;
 
110
    m_X11RepeatKey = true;
 
111
 
 
112
    m_GfxInterfaceCreated = false;
 
113
    m_pEvent = new IEvent();
 
114
 
 
115
    m_WindowSize.SetWidth (0);
 
116
    m_WindowSize.SetHeight (0);
 
117
 
 
118
    // A window never starts in a minimized state.
 
119
    m_is_window_minimized = false;
 
120
  }
 
121
 
 
122
//---------------------------------------------------------------------------------------------------------
 
123
  GLWindowImpl::~GLWindowImpl()
 
124
  {
 
125
    NUX_SAFE_DELETE ( m_GraphicsContext );
 
126
    NUX_SAFE_DELETE ( m_DeviceFactory );
 
127
 
 
128
    DestroyOpenGLWindow();
 
129
    NUX_SAFE_DELETE ( m_pEvent );
 
130
 
 
131
    inlSetThreadLocalStorage (ThreadLocal_GLWindowImpl, 0);
 
132
  }
 
133
 
 
134
//---------------------------------------------------------------------------------------------------------
 
135
  NString GLWindowImpl::FindResourceLocation (const TCHAR *ResourceFileName, bool ErrorOnFail)
 
136
  {
 
137
    NString path = m_ResourcePathLocation.GetFile (ResourceFileName);
 
138
 
 
139
    if (path == TEXT ("") && ErrorOnFail)
 
140
    {
 
141
      nuxDebugMsg (TEXT ("[GLWindowImpl::FindResourceLocation] Failed to locate resource file: %s."), ResourceFileName);
 
142
      /*inlWin32MessageBox(NULL, TEXT("Error"), MBTYPE_Ok, MBICON_Error, MBMODAL_ApplicationModal,
 
143
          TEXT("Failed to locate resource file %s.\nThe program will exit."), ResourceFileName);*/
 
144
      exit (1);
 
145
    }
 
146
 
 
147
    return path;
 
148
  }
 
149
 
 
150
  NString GLWindowImpl::FindUITextureLocation (const TCHAR *ResourceFileName, bool ErrorOnFail)
 
151
  {
 
152
    FilePath searchpath;
 
153
    searchpath.AddSearchPath (m_UITextureSearchPath);
 
154
    NString path = searchpath.GetFile (ResourceFileName);
 
155
 
 
156
    if ( (path == TEXT ("") ) && ErrorOnFail)
 
157
    {
 
158
      nuxDebugMsg (TEXT ("[GLWindowImpl::FindResourceLocation] Failed to locate ui texture file: %s."), ResourceFileName);
 
159
      /*inlWin32MessageBox(NULL, TEXT("Error"), MBTYPE_Ok, MBICON_Error, MBMODAL_ApplicationModal,
 
160
          TEXT("Failed to locate ui texture file %s.\nThe program will exit."), ResourceFileName);*/
 
161
      exit (1);
 
162
    }
 
163
 
 
164
    return path;
 
165
  }
 
166
 
 
167
  NString GLWindowImpl::FindShaderLocation (const TCHAR *ResourceFileName, bool ErrorOnFail)
 
168
  {
 
169
    FilePath searchpath;
 
170
    searchpath.AddSearchPath (m_ShaderSearchPath);
 
171
    NString path = searchpath.GetFile (ResourceFileName);
 
172
 
 
173
    if ( (path == TEXT ("") ) && ErrorOnFail)
 
174
    {
 
175
      nuxDebugMsg (TEXT ("[GLWindowImpl::FindResourceLocation] Failed to locate shader file: %s."), ResourceFileName);
 
176
      /*inlWin32MessageBox(NULL, TEXT("Error"), MBTYPE_Ok, MBICON_Error, MBMODAL_ApplicationModal,
 
177
          TEXT("Failed to locate shader file %s.\nThe program will exit."), ResourceFileName);*/
 
178
      exit (1);
 
179
    }
 
180
 
 
181
    return path;
 
182
  }
 
183
 
 
184
  NString GLWindowImpl::FindFontLocation (const TCHAR *ResourceFileName, bool ErrorOnFail)
 
185
  {
 
186
    FilePath searchpath;
 
187
    searchpath.AddSearchPath (m_FontSearchPath);
 
188
    NString path = searchpath.GetFile (ResourceFileName);
 
189
 
 
190
    if ( (path == TEXT ("") ) && ErrorOnFail)
 
191
    {
 
192
      nuxDebugMsg (TEXT ("[GLWindowImpl::FindResourceLocation] Failed to locate font file file: %s."), ResourceFileName);
 
193
      /*inlWin32MessageBox(NULL, TEXT("Error"), MBTYPE_Ok, MBICON_Error, MBMODAL_ApplicationModal,
 
194
          TEXT("Failed to locate font file %s.\nThe program will exit."), ResourceFileName);*/
 
195
      exit (1);
 
196
    }
 
197
 
 
198
    return path;
 
199
  }
 
200
 
 
201
 
 
202
//---------------------------------------------------------------------------------------------------------
 
203
  bool GLWindowImpl::IsGfxInterfaceCreated()
 
204
  {
 
205
    return m_GfxInterfaceCreated;
 
206
  }
 
207
 
 
208
//---------------------------------------------------------------------------------------------------------
 
209
  static NCriticalSection CreateOpenGLWindow_CriticalSection;
 
210
  bool GLWindowImpl::CreateOpenGLWindow (const TCHAR *WindowTitle,
 
211
                                         unsigned int WindowWidth,
 
212
                                         unsigned int WindowHeight,
 
213
                                         WindowStyle Style,
 
214
                                         const GLWindowImpl *Parent,
 
215
                                         bool FullscreenFlag)
 
216
  {
 
217
    NScopeLock Scope (&CreateOpenGLWindow_CriticalSection);
 
218
 
 
219
    m_GfxInterfaceCreated = false;
 
220
 
 
221
    // FIXME : put at the end
 
222
    m_ViewportSize.SetWidth (WindowWidth);
 
223
    m_ViewportSize.SetHeight (WindowHeight);
 
224
    m_WindowSize.SetWidth (WindowWidth);
 
225
    m_WindowSize.SetHeight (WindowHeight);
 
226
    // end of fixme
 
227
 
 
228
    m_Fullscreen = FullscreenFlag;  // Set The Global Fullscreen Flag
 
229
    m_BestMode = -1;                // assume -1 if the mode is not fullscreen
 
230
 
 
231
    m_X11Display = XOpenDisplay (0);
 
232
 
 
233
    if (m_X11Display == 0)
 
234
    {
 
235
      nuxDebugMsg (TEXT ("[GLWindowImpl::CreateOpenGLWindow] XOpenDisplay has failed. The window cannot be created.") );
 
236
      return false;
 
237
    }
 
238
 
 
239
    m_X11Screen = DefaultScreen (m_X11Display);
 
240
    XF86VidModeQueryVersion (m_X11Display, &m_X11VerMajor, &m_X11VerMinor);
 
241
 
 
242
    XF86VidModeGetAllModeLines (m_X11Display, m_X11Screen, &m_NumVideoModes, &m_X11VideoModes);
 
243
    m_X11OriginalVideoMode = *m_X11VideoModes[0];
 
244
 
 
245
    if (m_Fullscreen)               // Attempt Fullscreen Mode?
 
246
    {
 
247
      // check if resolution is supported
 
248
      bool mode_supported = false;
 
249
 
 
250
      for (int num_modes = 0 ; num_modes < m_NumVideoModes; num_modes++)
 
251
      {
 
252
        if ( (m_X11VideoModes[num_modes]->hdisplay == m_ViewportSize.GetWidth() )
 
253
             && (m_X11VideoModes[num_modes]->vdisplay == m_ViewportSize.GetHeight() ) )
 
254
        {
 
255
          mode_supported = true;
 
256
          m_BestMode = num_modes;
 
257
          break;
 
258
        }
 
259
      }
 
260
 
 
261
      if (mode_supported == false)
 
262
      {
 
263
        m_Fullscreen = false;
 
264
      }
 
265
    }
 
266
 
 
267
    glXQueryVersion (m_X11Display, &m_GLXVerMajor, &m_GLXVerMinor);
 
268
 
 
269
    // Get an appropriate visual
 
270
    m_X11VisualInfo = glXChooseVisual (m_X11Display, m_X11Screen, g_DoubleBufferVisual);
 
271
 
 
272
    if (m_X11VisualInfo == NULL)
 
273
    {
 
274
      nuxDebugMsg (TEXT ("[GLWindowImpl::CreateOpenGLWindow] Cannot get appropriate visual.") );
 
275
      return false;
 
276
    }
 
277
 
 
278
    m_GLCtx = glXCreateContext (m_X11Display, m_X11VisualInfo, 0, GL_TRUE);
 
279
 
 
280
    m_X11Colormap = XCreateColormap (m_X11Display,
 
281
                                     RootWindow (m_X11Display, m_X11VisualInfo->screen),
 
282
                                     m_X11VisualInfo->visual,
 
283
                                     AllocNone);
 
284
 
 
285
    m_X11Attr.border_pixel = 0;
 
286
    m_X11Attr.colormap = m_X11Colormap;
 
287
    m_X11Attr.override_redirect = m_Fullscreen;
 
288
    m_X11Attr.event_mask =
 
289
      // Mouse
 
290
      /*Button1MotionMask |
 
291
      Button2MotionMask |
 
292
      Button3MotionMask |
 
293
      Button4MotionMask |
 
294
      Button5MotionMask |
 
295
      ButtonMotionMask |*/
 
296
      ButtonPressMask |
 
297
      ButtonReleaseMask |
 
298
      // Mouse motion
 
299
      //-OwnerGrabButtonMask |
 
300
      //PointerMotionHintMask |
 
301
      PointerMotionMask |
 
302
      // Keyboard
 
303
      //--KeymapStateMask |
 
304
      KeyPressMask    |
 
305
      KeyReleaseMask  |
 
306
      // Window enter/exit
 
307
      LeaveWindowMask |
 
308
      EnterWindowMask |
 
309
      // Exposure Focus
 
310
      ExposureMask |
 
311
      FocusChangeMask |
 
312
      // Structure notify
 
313
      //--ResizeRedirectMask |
 
314
      StructureNotifyMask;// |
 
315
    //--SubstructureNotifyMask |
 
316
    //--SubstructureRedirectMask |
 
317
    // Visibility
 
318
    //--VisibilityChangeMask |
 
319
    // Property
 
320
    //--PropertyChangeMask |
 
321
    // Colormap
 
322
    //--ColormapChangeMask |
 
323
    // No event
 
324
    //--NoEventMask;
 
325
 
 
326
 
 
327
    if (m_Fullscreen)
 
328
    {
 
329
      XF86VidModeSwitchToMode (m_X11Display, m_X11Screen, m_X11VideoModes[m_BestMode]);
 
330
      XF86VidModeSetViewPort (m_X11Display, m_X11Screen, 0, 0);
 
331
      //Width = m_X11VideoModes[m_BestMode]->hdisplay;
 
332
      //Height = m_X11VideoModes[m_BestMode]->vdisplay;
 
333
      XFree (m_X11VideoModes);
 
334
 
 
335
      /* create a fullscreen window */
 
336
 
 
337
      m_X11Window = XCreateWindow (m_X11Display,
 
338
                                   RootWindow (m_X11Display, m_X11VisualInfo->screen),
 
339
                                   0, 0,                           // X, Y
 
340
                                   m_WindowSize.GetWidth(), m_WindowSize.GetHeight(),
 
341
                                   0,                              // Border
 
342
                                   m_X11VisualInfo->depth,         // Depth
 
343
                                   InputOutput,                    // Class
 
344
                                   m_X11VisualInfo->visual,        // Visual
 
345
                                   CWBorderPixel |
 
346
                                   CWColormap |
 
347
                                   CWEventMask |
 
348
                                   CWOverrideRedirect,
 
349
                                   &m_X11Attr);
 
350
 
 
351
      XWarpPointer (m_X11Display, None, m_X11Window, 0, 0, 0, 0, 0, 0);
 
352
      XMapRaised (m_X11Display, m_X11Window);
 
353
      XGrabKeyboard (m_X11Display, m_X11Window, True,
 
354
                     GrabModeAsync,
 
355
                     GrabModeAsync,
 
356
                     CurrentTime);
 
357
      XGrabPointer (m_X11Display, m_X11Window, True,
 
358
                    ButtonPressMask,
 
359
                    GrabModeAsync, GrabModeAsync, m_X11Window, None, CurrentTime);
 
360
    }
 
361
    else
 
362
    {
 
363
      m_X11Window = XCreateWindow (m_X11Display,
 
364
                                   RootWindow (m_X11Display, m_X11VisualInfo->screen),
 
365
                                   0, 0,
 
366
                                   m_WindowSize.GetWidth(), m_WindowSize.GetHeight(),
 
367
                                   0,
 
368
                                   m_X11VisualInfo->depth,
 
369
                                   InputOutput,
 
370
                                   m_X11VisualInfo->visual,
 
371
                                   CWBorderPixel |
 
372
                                   CWColormap |
 
373
                                   CWEventMask |
 
374
                                   CWOverrideRedirect,
 
375
                                   &m_X11Attr);
 
376
 
 
377
      /* only set window title and handle wm_delete_events if in windowed mode */
 
378
      m_WMDeleteWindow = XInternAtom (m_X11Display, "WM_DELETE_WINDOW", True);
 
379
      XSetWMProtocols (m_X11Display, m_X11Window, &m_WMDeleteWindow, 1);
 
380
 
 
381
      XSetStandardProperties (m_X11Display, m_X11Window, WindowTitle, WindowTitle, None, NULL, 0, NULL);
 
382
      XMapRaised (m_X11Display, m_X11Window);
 
383
    }
 
384
 
 
385
    MakeGLContextCurrent();
 
386
    glClearColor (0.0, 0.0, 0.0, 0.0);
 
387
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
 
388
    SwapBuffer();
 
389
 
 
390
    m_GfxInterfaceCreated = true;
 
391
 
 
392
    m_DeviceFactory = new GpuDevice (m_ViewportSize.GetWidth(), m_ViewportSize.GetHeight(), BITFMT_R8G8B8A8);
 
393
    m_GraphicsContext = new GraphicsEngine (*this);
 
394
 
 
395
    EnableVSyncSwapControl();
 
396
    //DisableVSyncSwapControl();
 
397
 
 
398
    return TRUE;
 
399
  }
 
400
 
 
401
  bool GLWindowImpl::CreateFromOpenGLWindow (Display *X11Display, Window X11Window, GLXContext OpenGLContext)
 
402
  {
 
403
    // Do not make the opengl context current
 
404
    // Do not swap the framebuffer
 
405
    // Do not clear the depth or color buffer
 
406
    // Do not enable/disbale VSync
 
407
 
 
408
    m_X11Display = X11Display;
 
409
    m_X11Window = X11Window;
 
410
    m_GLCtx = OpenGLContext;
 
411
 
 
412
    Window root_return;
 
413
    int x_return, y_return;
 
414
    unsigned int width_return, height_return;
 
415
    unsigned int border_width_return;
 
416
    unsigned int depth_return;
 
417
 
 
418
    XGetGeometry (X11Display, X11Window, &root_return, &x_return, &y_return, &width_return, &height_return, &border_width_return, &depth_return);
 
419
    m_WindowSize = Size (width_return, height_return);
 
420
    m_WindowPosition = Point (x_return, y_return);
 
421
 
 
422
    m_ViewportSize = Size (width_return, height_return);
 
423
 
 
424
    m_GfxInterfaceCreated = true;
 
425
 
 
426
    m_DeviceFactory = new GpuDevice (m_ViewportSize.GetWidth(), m_ViewportSize.GetHeight(), BITFMT_R8G8B8A8);
 
427
    m_GraphicsContext = new GraphicsEngine (*this);
 
428
 
 
429
    return true;
 
430
  }
 
431
 
 
432
// bool GLWindowImpl::CreateVisual(unsigned int WindowWidth, unsigned int WindowHeight, XVisualInfo& ChosenVisual, XVisualInfo& Template, unsigned long Mask)
 
433
// {
 
434
//     // Get all the visuals matching the template
 
435
//     Template.screen = m_X11Screen;
 
436
//     int NunberOfVisuals = 0;
 
437
//     XVisualInfo* VisualsArray = XGetVisualInfo(m_X11Display, Mask | VisualScreenMask, &Template, &NunberOfVisuals);
 
438
//
 
439
//     if(!VisualsArray || (NunberOfVisuals == 0))
 
440
//     {
 
441
//         if(VisualsArray)
 
442
//             XFree(VisualsArray);
 
443
//         nuxDebugMsg(TEXT("[GLWindowImpl::CreateVisual] There is no matching visuals."));
 
444
//         return false;
 
445
//     }
 
446
//
 
447
//     // Find the best visual
 
448
//     int          BestScore  = 0xFFFF;
 
449
//     XVisualInfo* BestVisual = NULL;
 
450
//     while (!BestVisual)
 
451
//     {
 
452
//         for (int i = 0; i < NunberOfVisuals; ++i)
 
453
//         {
 
454
//             // Get the current visual attributes
 
455
//             int RGBA, DoubleBuffer, Red, Green, Blue, Alpha, Depth, Stencil, MultiSampling, Samples;
 
456
//             glXGetConfig(ourDisplay, &Visuals[i], GLX_RGBA,               &RGBA);
 
457
//             glXGetConfig(ourDisplay, &Visuals[i], GLX_DOUBLEBUFFER,       &DoubleBuffer);
 
458
//             glXGetConfig(ourDisplay, &Visuals[i], GLX_RED_SIZE,           &Red);
 
459
//             glXGetConfig(ourDisplay, &Visuals[i], GLX_GREEN_SIZE,         &Green);
 
460
//             glXGetConfig(ourDisplay, &Visuals[i], GLX_BLUE_SIZE,          &Blue);
 
461
//             glXGetConfig(ourDisplay, &Visuals[i], GLX_ALPHA_SIZE,         &Alpha);
 
462
//             glXGetConfig(ourDisplay, &Visuals[i], GLX_DEPTH_SIZE,         &Depth);
 
463
//             glXGetConfig(ourDisplay, &Visuals[i], GLX_STENCIL_SIZE,       &Stencil);
 
464
//             glXGetConfig(ourDisplay, &Visuals[i], GLX_SAMPLE_BUFFERS_ARB, &MultiSampling);
 
465
//             glXGetConfig(ourDisplay, &Visuals[i], GLX_SAMPLES_ARB,        &Samples);
 
466
//
 
467
//             // First check the mandatory parameters
 
468
//             if ((RGBA == 0) || (DoubleBuffer == 0))
 
469
//                 continue;
 
470
//
 
471
//             // Evaluate the current configuration
 
472
//             int Color = Red + Green + Blue + Alpha;
 
473
//             int Score = EvaluateConfig(Mode, Params, Color, Depth, Stencil, MultiSampling ? Samples : 0);
 
474
//
 
475
//             // Keep it if it's better than the current best
 
476
//             if (Score < BestScore)
 
477
//             {
 
478
//                 BestScore  = Score;
 
479
//                 BestVisual = &Visuals[i];
 
480
//             }
 
481
//         }
 
482
//
 
483
//         // If no visual has been found, try a lower level of antialiasing
 
484
//         if (!BestVisual)
 
485
//         {
 
486
//             if (Params.AntialiasingLevel > 2)
 
487
//             {
 
488
//                 std::cerr << "Failed to find a pixel format supporting "
 
489
//                     << Params.AntialiasingLevel << " antialiasing levels ; trying with 2 levels" << std::endl;
 
490
//                 Params.AntialiasingLevel = 2;
 
491
//             }
 
492
//             else if (Params.AntialiasingLevel > 0)
 
493
//             {
 
494
//                 std::cerr << "Failed to find a pixel format supporting antialiasing ; antialiasing will be disabled" << std::endl;
 
495
//                 Params.AntialiasingLevel = 0;
 
496
//             }
 
497
//             else
 
498
//             {
 
499
//                 std::cerr << "Failed to find a suitable pixel format for the window -- cannot create OpenGL context" << std::endl;
 
500
//                 return false;
 
501
//             }
 
502
//         }
 
503
//     }
 
504
//
 
505
//     // Create the OpenGL context
 
506
//     myGLContext = glXCreateContext(ourDisplay, BestVisual, glXGetCurrentContext(), true);
 
507
//     if (myGLContext == NULL)
 
508
//     {
 
509
//         std::cerr << "Failed to create an OpenGL context for this window" << std::endl;
 
510
//         return false;
 
511
//     }
 
512
//
 
513
//     // Update the creation settings from the chosen format
 
514
//     int Depth, Stencil;
 
515
//     glXGetConfig(ourDisplay, BestVisual, GLX_DEPTH_SIZE,   &Depth);
 
516
//     glXGetConfig(ourDisplay, BestVisual, GLX_STENCIL_SIZE, &Stencil);
 
517
//     Params.DepthBits   = static_cast<unsigned int>(Depth);
 
518
//     Params.StencilBits = static_cast<unsigned int>(Stencil);
 
519
//
 
520
//     // Assign the chosen visual, and free the temporary visuals array
 
521
//     ChosenVisual = *BestVisual;
 
522
//     XFree(Visuals);
 
523
//
 
524
//     // Activate the context
 
525
//     SetActive(true);
 
526
//
 
527
//     // Enable multisampling if needed
 
528
//     if (Params.AntialiasingLevel > 0)
 
529
//         glEnable(GL_MULTISAMPLE_ARB);
 
530
//
 
531
//     return true;
 
532
// }
 
533
 
 
534
//---------------------------------------------------------------------------------------------------------
 
535
  bool GLWindowImpl::HasFrameBufferSupport()
 
536
  {
 
537
    return m_DeviceFactory->SUPPORT_GL_EXT_FRAMEBUFFER_OBJECT();
 
538
  }
 
539
 
 
540
//---------------------------------------------------------------------------------------------------------
 
541
  void GLWindowImpl::GetWindowSize (int &w, int &h)
 
542
  {
 
543
    w = m_WindowSize.GetWidth();
 
544
    h = m_WindowSize.GetHeight();
 
545
  }
 
546
 
 
547
  void GLWindowImpl::GetDesktopSize (int &w, int &h)
 
548
  {
 
549
    Window root;
 
550
    int x, y;
 
551
    unsigned int width, height, depth, border_width;
 
552
    bool ret = XGetGeometry (m_X11Display, RootWindow (m_X11Display, m_X11Screen),
 
553
                             &root,
 
554
                             &x, &y,
 
555
                             &width, &height, &border_width, &depth);
 
556
 
 
557
    if (ret == false)
 
558
    {
 
559
      nuxAssert (TEXT ("[GetDesktopSize] Failed to get the desktop size") );
 
560
      w = 0;
 
561
      h = 0;
 
562
    }
 
563
  }
 
564
 
 
565
//---------------------------------------------------------------------------------------------------------
 
566
  void GLWindowImpl::SetWindowSize (int width, int height)
 
567
  {
 
568
    nuxDebugMsg (TEXT ("[GLWindowImpl::SetWindowSize] Setting window size to %dx%d"), width, height);
 
569
    // Resize window client area
 
570
    XResizeWindow (m_X11Display, m_X11Window, width, height);
 
571
    XFlush (m_X11Display);
 
572
  }
 
573
 
 
574
//---------------------------------------------------------------------------------------------------------
 
575
  void GLWindowImpl::SetWindowPosition (int x, int y)
 
576
  {
 
577
    nuxDebugMsg (TEXT ("[GLWindowImpl::SetWindowPosition] Setting window position to %dx%d"), x, y);
 
578
    // Resize window client area
 
579
    XMoveWindow (m_X11Display, m_X11Window, x, y);
 
580
    XFlush (m_X11Display);
 
581
  }
 
582
 
 
583
//---------------------------------------------------------------------------------------------------------
 
584
  unsigned int GLWindowImpl::GetWindowWidth()
 
585
  {
 
586
    return m_WindowSize.GetWidth();
 
587
  }
 
588
 
 
589
//---------------------------------------------------------------------------------------------------------
 
590
  unsigned int GLWindowImpl::GetWindowHeight()
 
591
  {
 
592
    return m_WindowSize.GetHeight();
 
593
  }
 
594
 
 
595
//---------------------------------------------------------------------------------------------------------
 
596
  void GLWindowImpl::SetViewPort (int x, int y, int width, int height)
 
597
  {
 
598
 
 
599
    if (IsGfxInterfaceCreated() )
 
600
    {
 
601
      //do not rely on m_ViewportSize: glViewport can be called directly
 
602
      m_ViewportSize.SetWidth (width);
 
603
      m_ViewportSize.SetHeight (height);
 
604
 
 
605
      m_GraphicsContext->SetViewport (x, y, m_ViewportSize.GetWidth(), m_ViewportSize.GetHeight() );
 
606
      m_GraphicsContext->SetScissor (0, 0, width, height);
 
607
    }
 
608
  }
 
609
 
 
610
  Point GLWindowImpl::GetMouseScreenCoord()
 
611
  {
 
612
    Window root_return;
 
613
    Window child_return;
 
614
    int root_x_return;
 
615
    int root_y_return;
 
616
    int win_x_return;
 
617
    int win_y_return;
 
618
    unsigned int mask_return;
 
619
 
 
620
 
 
621
    XQueryPointer (m_X11Display,
 
622
                   RootWindow (m_X11Display, m_X11Screen),
 
623
                   &root_return,
 
624
                   &child_return,
 
625
                   &root_x_return,
 
626
                   &root_y_return,
 
627
                   &win_x_return,
 
628
                   &win_y_return,
 
629
                   &mask_return);
 
630
    XFlush (m_X11Display);
 
631
 
 
632
    return Point (root_x_return, root_y_return);
 
633
  }
 
634
 
 
635
  Point GLWindowImpl::GetMouseWindowCoord()
 
636
  {
 
637
    Window root_return;
 
638
    Window child_return;
 
639
    int root_x_return;
 
640
    int root_y_return;
 
641
    int win_x_return;
 
642
    int win_y_return;
 
643
    unsigned int mask_return;
 
644
 
 
645
    XQueryPointer (m_X11Display,
 
646
                   RootWindow (m_X11Display, m_X11Screen),
 
647
                   &root_return,
 
648
                   &child_return,
 
649
                   &root_x_return,
 
650
                   &root_y_return,
 
651
                   &win_x_return,
 
652
                   &win_y_return,
 
653
                   &mask_return);
 
654
    XFlush (m_X11Display);
 
655
 
 
656
    return Point (win_x_return, win_y_return);
 
657
  }
 
658
 
 
659
  Point GLWindowImpl::GetWindowCoord()
 
660
  {
 
661
    XWindowAttributes attrib;
 
662
    int status = XGetWindowAttributes (m_X11Display, m_X11Window, &attrib);
 
663
 
 
664
    if (status == 0)
 
665
    {
 
666
      nuxAssert (TEXT ("[GLWindowImpl::GetWindowCoord] Failed to get the window attributes.") );
 
667
      return Point (0, 0);
 
668
    }
 
669
 
 
670
    return Point (attrib.x, attrib.y);
 
671
  }
 
672
 
 
673
  Rect GLWindowImpl::GetWindowGeometry()
 
674
  {
 
675
    XWindowAttributes attrib;
 
676
    int status = XGetWindowAttributes (m_X11Display, m_X11Window, &attrib);
 
677
 
 
678
    if (status == 0)
 
679
    {
 
680
      nuxAssert (TEXT ("[GLWindowImpl::GetWindowGeometry] Failed to get the window attributes.") );
 
681
      return Rect (0, 0, 0, 0);
 
682
    }
 
683
 
 
684
    return Rect (attrib.x, attrib.y, attrib.width, attrib.height);
 
685
  }
 
686
 
 
687
  Rect GLWindowImpl::GetNCWindowGeometry()
 
688
  {
 
689
    XWindowAttributes attrib;
 
690
    int status = XGetWindowAttributes (m_X11Display, m_X11Window, &attrib);
 
691
 
 
692
    if (status == 0)
 
693
    {
 
694
      nuxAssert (TEXT ("[GLWindowImpl::GetWindowGeometry] Failed to get the window attributes.") );
 
695
      return Rect (0, 0, 0, 0);
 
696
    }
 
697
 
 
698
    return Rect (attrib.x, attrib.y, attrib.width, attrib.height);
 
699
  }
 
700
 
 
701
  void GLWindowImpl::MakeGLContextCurrent()
 
702
  {
 
703
    if (!glXMakeCurrent (m_X11Display, m_X11Window, m_GLCtx) )
 
704
    {
 
705
      DestroyOpenGLWindow();
 
706
    }
 
707
  }
 
708
 
 
709
  void GLWindowImpl::SwapBuffer (bool glswap)
 
710
  {
 
711
    // There are a lot of mouse motion events coming from X11. The system processes one event at a time and sleeps
 
712
    // if necessary to cap the frame rate to 60 frames per seconds. But while the thread sleeping, there are accumulated
 
713
    // motion events waiting to be processed. This creates an increasing backlog of motion events. It translate into a slow
 
714
    // motion of elements that moves in response to the mouse.
 
715
    // Solution: if the the current event is a motion event, changes are, it is followed many more motion events.
 
716
    // In this case, don't sleep the thread... Swap the framebuffer to see the result of the current single motion event.
 
717
    // It maybe worth investigating how to properly balance event processing and drawing in order to keep the
 
718
    // frame rate and the responsiveness at acceptable levels.
 
719
    // As a consequence, when the mouse is moving, the frame rate goes beyong 60fps.
 
720
 
 
721
    /*bool bsleep = true;
 
722
    if(XPending(m_X11Display) > 0)
 
723
    {
 
724
        XEvent xevent;
 
725
        XPeekEvent(m_X11Display, &xevent);
 
726
        if(xevent.type == MotionNotify)
 
727
        {
 
728
            //nuxDebugMsg(TEXT("[GLWindowImpl::SwapBuffer]: MotionNotify event."));
 
729
            bsleep = false;
 
730
        }
 
731
    }*/
 
732
 
 
733
    if (IsPauseThreadGraphicsRendering() )
 
734
      return;
 
735
 
 
736
    if (glswap)
 
737
    {
 
738
      glXSwapBuffers (m_X11Display, m_X11Window);
 
739
    }
 
740
 
 
741
    m_FrameTime = m_Timer.PassedMilliseconds();
 
742
 
 
743
//     if(16.6f - m_FrameTime > 0)
 
744
//     {
 
745
//         SleepForMilliseconds(16.6f - m_FrameTime);
 
746
//         m_FrameTime = m_Timer.PassedMilliseconds();
 
747
//     }
 
748
//
 
749
//     m_Timer.Reset();
 
750
//     m_PeriodeTime += m_FrameTime;
 
751
//
 
752
//     m_FrameCounter++;
 
753
//     m_FramePeriodeCounter++;
 
754
//     if(m_FramePeriodeCounter >= FRAME_RATE_PERIODE)
 
755
//     {
 
756
//         //nuxDebugMsg(TEXT("[GLWindowImpl::SwapBuffer] Frametime: %f"), m_FrameTime);
 
757
//         m_FrameRate = m_FramePeriodeCounter / (m_PeriodeTime / 1000.0f);
 
758
//         m_PeriodeTime = 0.0f;
 
759
//         m_FramePeriodeCounter = 0;
 
760
//     }
 
761
  }
 
762
//---------------------------------------------------------------------------------------------------------
 
763
  void GLWindowImpl::DestroyOpenGLWindow()
 
764
  {
 
765
    if (m_GfxInterfaceCreated == true)
 
766
    {
 
767
      if (m_GLCtx)
 
768
      {
 
769
        if (!glXMakeCurrent (m_X11Display, None, NULL) )
 
770
        {
 
771
          nuxAssert (TEXT ("[GLWindowImpl::DestroyOpenGLWindow] glXMakeCurrent failed.") );
 
772
        }
 
773
 
 
774
        glXDestroyContext (m_X11Display, m_GLCtx);
 
775
        m_GLCtx = NULL;
 
776
      }
 
777
 
 
778
      /* switch back to original desktop resolution if we were in fs */
 
779
      if (m_Fullscreen)
 
780
      {
 
781
        XF86VidModeSwitchToMode (m_X11Display, m_X11Screen, &m_X11OriginalVideoMode);
 
782
        XF86VidModeSetViewPort (m_X11Display, m_X11Screen, 0, 0);
 
783
      }
 
784
 
 
785
      XCloseDisplay (m_X11Display);
 
786
    }
 
787
 
 
788
    m_GfxInterfaceCreated = false;
 
789
  }
 
790
 
 
791
// //---------------------------------------------------------------------------------------------------------
 
792
// // convert a MSWindows VK_x to an INL keysym or and extended INL keysym:
 
793
// static const struct {unsigned short vk, fltk, extended;} vktab[] = {
 
794
//     {NUX_VK_BACK,        NUX_BackSpace},
 
795
//     {NUX_VK_TAB,         NUX_Tab},
 
796
//     {NUX_VK_CLEAR,       NUX_Clear,      0xff0b/*XK_Clear*/},
 
797
//     {NUX_VK_ENTER,       NUX_Enter,      NUX_KP_ENTER},
 
798
//     {NUX_VK_SHIFT,       NUX_Shift_L,        NUX_EXT_Shift_R},
 
799
//     {NUX_VK_CONTROL, NUX_Control_L,  NUX_EXT_Control_R},
 
800
//     {NUX_VK_MENU,        NUX_Alt_L,      NUX_EXT_Alt_R},
 
801
//     {NUX_VK_PAUSE,       NUX_Pause},
 
802
//     {NUX_VK_CAPITAL, NUX_Caps_Lock},
 
803
//     {NUX_VK_ESCAPE,      NUX_Escape},
 
804
//     {NUX_VK_SPACE,       ' '},
 
805
//     {NUX_VK_PAGE_UP, NUX_Page_Up     /*KP+'9'*/,         NUX_KP_PAGE_UP},
 
806
//     {NUX_VK_PAGE_DOWN,  NUX_Page_Down   /*KP+'3'*/,      NUX_KP_PAGE_DOWN},
 
807
//     {NUX_VK_END,         NUX_End         /*KP+'1'*/,     NUX_KP_END},
 
808
//     {NUX_VK_HOME,        NUX_Home        /*KP+'7'*/,     NUX_KP_HOME},
 
809
//     {NUX_VK_LEFT,        NUX_Left        /*KP+'4'*/,     NUX_KP_LEFT},
 
810
//     {NUX_VK_UP,              NUX_Up          /*KP+'8'*/,         NUX_KP_UP},
 
811
//     {NUX_VK_RIGHT,       NUX_Right       /*KP+'6'*/,     NUX_KP_RIGHT},
 
812
//     {NUX_VK_DOWN,        NUX_Down        /*KP+'2'*/,     NUX_KP_DOWN},
 
813
//     {NUX_VK_SNAPSHOT,        NUX_Print},         // does not work on NT
 
814
//     {NUX_VK_INSERT,      NUX_Insert      /*KP+'0'*/,     NUX_KP_INSERT},
 
815
//     {NUX_VK_DELETE,      NUX_Delete      /*KP+'.'*/,     NUX_KP_DELETE},
 
816
//     {NUX_VK_LWIN,        NUX_LWin        /*Meta_L*/},
 
817
//     {NUX_VK_RWIN,        NUX_RWin        /*Meta_R*/},
 
818
//     {NUX_VK_APPS,        NUX_VK_APPS     /*Menu*/},
 
819
//     {NUX_VK_MULTIPLY,        NUX_Multiply    /*KP+'*'*/},
 
820
//     {NUX_VK_ADD,         NUX_Add         /*KP+'+'*/},
 
821
//     {NUX_VK_SUBTRACT,        NUX_Subtract    /*KP+'-'*/},
 
822
//     {NUX_VK_DECIMAL, NUX_Decimal     /*KP+'.'*/},
 
823
//     {NUX_VK_DIVIDE,      NUX_Divide      /*KP+'/'*/},
 
824
//     {NUX_VK_NUMLOCK, NUX_Numlock     /*Num_Lock*/},
 
825
//     {NUX_VK_SCROLL,      NUX_Scroll      /*Scroll_Lock*/},
 
826
//     {0xba,   ';'},
 
827
//     {0xbb,   '='},
 
828
//     {0xbc,   ','},
 
829
//     {0xbd,   '-'},
 
830
//     {0xbe,   '.'},
 
831
//     {0xbf,   '/'},
 
832
//     {0xc0,   '`'},
 
833
//     {0xdb,   '['},
 
834
//     {0xdc,   '\\'},
 
835
//     {0xdd,   ']'},
 
836
//     {0xde,   '\''}
 
837
// };
 
838
// //---------------------------------------------------------------------------------------------------------
 
839
// static int ms2fltk(int vk, int extended)
 
840
// {
 
841
//     static unsigned short vklut[256];
 
842
//     static unsigned short extendedlut[256];
 
843
//     if (!vklut[1])
 
844
//     {
 
845
//         // init the table
 
846
//         unsigned int i;
 
847
//         for (i = 0; i < 256; i++)
 
848
//         {
 
849
//             vklut[i] = i; //tolower(i);
 
850
//         }
 
851
// //        for (i=VK_F1; i<=VK_F16; i++)
 
852
// //        {
 
853
// //            vklut[i] = i+(FL_F-(VK_F1-1));   // (FL_F + 1 -> VK_F1) ... (FL_F + 16 -> VK_F16)
 
854
// //        }
 
855
// //        for (i=VK_NUMPAD0; i<=VK_NUMPAD9; i++)
 
856
// //        {
 
857
// //            vklut[i] = i+(FL_KP+'0'-VK_NUMPAD0);    // (FL_KP + '0' -> VK_NUMPAD0) ... (FL_KP + '9' = VK_NUMPAD9)
 
858
// //        }
 
859
//         for (i = 0; i < sizeof(vktab)/sizeof(*vktab); i++)
 
860
//         {
 
861
//             vklut[vktab[i].vk] = vktab[i].fltk;
 
862
//             extendedlut[vktab[i].vk] = vktab[i].extended;
 
863
//         }
 
864
//         for (i = 0; i < 256; i++)
 
865
//         {
 
866
//             if (!extendedlut[i])
 
867
//                 extendedlut[i] = vklut[i];
 
868
//         }
 
869
//     }
 
870
//
 
871
//     return extended ? extendedlut[vk] : vklut[vk];
 
872
// }
 
873
//---------------------------------------------------------------------------------------------------------
 
874
  static int mouse_move (XEvent xevent, IEvent *m_pEvent)
 
875
  {
 
876
//     m_pEvent->e_x = xevent.xmotion.x;
 
877
//     m_pEvent->e_y = xevent.xmotion.y;
 
878
//     m_pEvent->e_x_root = 0;
 
879
//     m_pEvent->e_y_root = 0;
 
880
 
 
881
    // Erase mouse event and mouse doubleclick events. Keep the mouse states.
 
882
    t_uint32 _mouse_state = m_pEvent->e_mouse_state & 0x0F000000;
 
883
 
 
884
    m_pEvent->e_event = NUX_MOUSE_MOVE;
 
885
 
 
886
    _mouse_state |= (xevent.xmotion.state & Button1Mask) ? NUX_STATE_BUTTON1_DOWN : 0;
 
887
    _mouse_state |= (xevent.xmotion.state & Button2Mask) ? NUX_STATE_BUTTON2_DOWN : 0;
 
888
    _mouse_state |= (xevent.xmotion.state & Button3Mask) ? NUX_STATE_BUTTON3_DOWN : 0;
 
889
 
 
890
    m_pEvent->e_mouse_state = _mouse_state;
 
891
 
 
892
    return 0;
 
893
  }
 
894
 
 
895
  static int mouse_press (XEvent xevent, IEvent *m_pEvent)
 
896
  {
 
897
//     m_pEvent->e_x = xevent.xbutton.x;
 
898
//     m_pEvent->e_y = xevent.xbutton.y;
 
899
//     m_pEvent->e_x_root = 0;
 
900
//     m_pEvent->e_y_root = 0;
 
901
 
 
902
    // Erase mouse event and mouse double-click events. Keep the mouse states.
 
903
    ulong _mouse_state = m_pEvent->e_mouse_state & 0x0F000000;
 
904
 
 
905
    m_pEvent->e_event = NUX_MOUSE_PRESSED;
 
906
 
 
907
    // State of the button before the event
 
908
    _mouse_state |= (xevent.xbutton.state & Button1Mask) ? NUX_STATE_BUTTON1_DOWN : 0;
 
909
    _mouse_state |= (xevent.xbutton.state & Button2Mask) ? NUX_STATE_BUTTON2_DOWN : 0;
 
910
    _mouse_state |= (xevent.xbutton.state & Button3Mask) ? NUX_STATE_BUTTON3_DOWN : 0;
 
911
 
 
912
    if (xevent.xbutton.type == ButtonPress)
 
913
    {
 
914
      if (xevent.xbutton.button == Button1)
 
915
      {
 
916
        _mouse_state |= NUX_EVENT_BUTTON1_DOWN;
 
917
        _mouse_state |= NUX_STATE_BUTTON1_DOWN;
 
918
      }
 
919
 
 
920
      if (xevent.xbutton.button == Button2)
 
921
      {
 
922
        _mouse_state |= NUX_EVENT_BUTTON2_DOWN;
 
923
        _mouse_state |= NUX_STATE_BUTTON2_DOWN;
 
924
      }
 
925
 
 
926
      if (xevent.xbutton.button == Button3)
 
927
      {
 
928
        _mouse_state |= NUX_EVENT_BUTTON3_DOWN;
 
929
        _mouse_state |= NUX_STATE_BUTTON3_DOWN;
 
930
      }
 
931
 
 
932
      if (xevent.xbutton.button == Button4)
 
933
      {
 
934
        _mouse_state |= NUX_EVENT_MOUSEWHEEL;
 
935
        m_pEvent->e_event = NUX_MOUSEWHEEL;
 
936
        m_pEvent->e_wheeldelta = -NUX_MOUSEWHEEL_DELTA;
 
937
        return 1;
 
938
      }
 
939
 
 
940
      if (xevent.xbutton.button == Button5)
 
941
      {
 
942
        _mouse_state |= NUX_EVENT_MOUSEWHEEL;
 
943
        m_pEvent->e_event = NUX_MOUSEWHEEL;
 
944
        m_pEvent->e_wheeldelta = +NUX_MOUSEWHEEL_DELTA;
 
945
        return 1;
 
946
      }
 
947
 
 
948
    }
 
949
 
 
950
    m_pEvent->e_mouse_state = _mouse_state;
 
951
 
 
952
    return 0;
 
953
  }
 
954
 
 
955
  static int mouse_release (XEvent xevent, IEvent *m_pEvent)
 
956
  {
 
957
//     m_pEvent->e_x = xevent.xbutton.x;
 
958
//     m_pEvent->e_y = xevent.xbutton.y;
 
959
//     m_pEvent->e_x_root = 0;
 
960
//     m_pEvent->e_y_root = 0;
 
961
 
 
962
    // Erase mouse event and mouse double-click events. Keep the mouse states.
 
963
    ulong _mouse_state = m_pEvent->e_mouse_state & 0x0F000000;
 
964
 
 
965
    m_pEvent->e_event = NUX_MOUSE_RELEASED;
 
966
 
 
967
    // State of the button before the event
 
968
    _mouse_state |= (xevent.xbutton.state & Button1Mask) ? NUX_STATE_BUTTON1_DOWN : 0;
 
969
    _mouse_state |= (xevent.xbutton.state & Button2Mask) ? NUX_STATE_BUTTON2_DOWN : 0;
 
970
    _mouse_state |= (xevent.xbutton.state & Button3Mask) ? NUX_STATE_BUTTON3_DOWN : 0;
 
971
 
 
972
    if (xevent.xbutton.type == ButtonRelease)
 
973
    {
 
974
      if (xevent.xbutton.button == Button1)
 
975
      {
 
976
        _mouse_state |= NUX_EVENT_BUTTON1_UP;
 
977
        _mouse_state &= ~NUX_STATE_BUTTON1_DOWN;
 
978
      }
 
979
 
 
980
      if (xevent.xbutton.button == Button2)
 
981
      {
 
982
        _mouse_state |= NUX_EVENT_BUTTON2_UP;
 
983
        _mouse_state &= ~NUX_STATE_BUTTON2_DOWN;
 
984
      }
 
985
 
 
986
      if (xevent.xbutton.button == Button3)
 
987
      {
 
988
        _mouse_state |= NUX_EVENT_BUTTON3_UP;
 
989
        _mouse_state &= ~NUX_STATE_BUTTON3_DOWN;
 
990
      }
 
991
    }
 
992
 
 
993
    m_pEvent->e_mouse_state = _mouse_state;
 
994
 
 
995
    return 0;
 
996
  }
 
997
 
 
998
  unsigned int GetModifierKeyState (unsigned int modifier_key_state)
 
999
  {
 
1000
    unsigned int state = 0;
 
1001
 
 
1002
    // For CapsLock, we don't want to know if the key is pressed Down or Up.
 
1003
    // We really want to know the state of the the CapsLock: on (keyboard light is on) or off?
 
1004
    if (modifier_key_state & LockMask)
 
1005
      state |= NUX_STATE_CAPS_LOCK;
 
1006
 
 
1007
    // For NumLock, we don't want to know if the key is pressed Down or Up.
 
1008
    // We really want to know the state of the the NumLock: on (keyboard light is on) or off?
 
1009
    if (modifier_key_state & Mod5Mask)
 
1010
      state |= NUX_STATE_NUMLOCK;
 
1011
 
 
1012
//     if (modifier_key_state & 0x8000)
 
1013
//         state |= NUX_STATE_SCROLLLOCK;
 
1014
 
 
1015
    if (modifier_key_state & ControlMask)
 
1016
      state |= NUX_STATE_CTRL;
 
1017
 
 
1018
    if (modifier_key_state & ShiftMask)
 
1019
      state |= NUX_STATE_SHIFT;
 
1020
 
 
1021
    if (modifier_key_state & Mod1Mask)
 
1022
      state |= NUX_STATE_ALT;
 
1023
 
 
1024
    return state;
 
1025
  }
 
1026
 
 
1027
  void GLWindowImpl::GetSystemEvent (IEvent *evt)
 
1028
  {
 
1029
    m_pEvent->Reset();
 
1030
    // Erase mouse event and mouse doubleclick states. Keep the mouse states.
 
1031
    m_pEvent->e_mouse_state &= 0x0F000000;
 
1032
    bool bProcessEvent = true;
 
1033
 
 
1034
    // Process event matching this window
 
1035
    XEvent xevent;
 
1036
 
 
1037
    if (XPending (m_X11Display))
 
1038
    {
 
1039
      XNextEvent (m_X11Display, &xevent);
 
1040
      // Detect auto repeat keys. X11 sends a combination of KeyRelease/KeyPress (at the same time) when a key auto repeats.
 
1041
      // Here, we make sure we process only the keyRelease when the key is effectively released.
 
1042
      if ( (xevent.type == KeyPress) || (xevent.type == KeyRelease) )
 
1043
      {
 
1044
        if (xevent.xkey.keycode < 256)
 
1045
        {
 
1046
          // Detect if a key is repeated
 
1047
          char Keys[32];
 
1048
          // The XQueryKeymap function returns a bit vector for the logical state of the keyboard, where each bit set
 
1049
          // to 1 indicates that the corresponding key is currently pressed down. The vector is represented as 32 bytes.
 
1050
          // Byte N (from 0) contains the bits for keys 8N to 8N + 7 with the least significant bit in the byte representing
 
1051
          // key 8N.
 
1052
          // Note that the logical state of a device (as seen by client applications) may lag the physical state if device
 
1053
          // event processing is frozen.
 
1054
 
 
1055
          XQueryKeymap (m_X11Display, Keys);
 
1056
 
 
1057
          if (Keys[xevent.xkey.keycode >> 3] & (1 << (xevent.xkey.keycode % 8) ) )
 
1058
          {
 
1059
            // KeyRelease event + KeyDown = discard repeated event
 
1060
            if (xevent.type == KeyRelease)
 
1061
            {
 
1062
              m_X11LastEvent = xevent;
 
1063
              bProcessEvent = false;
 
1064
            }
 
1065
 
 
1066
            // KeyPress event + key repeat disabled + matching KeyRelease event = discard repeated event
 
1067
            if ( (xevent.type == KeyPress) && (!m_X11RepeatKey) &&
 
1068
                 (m_X11LastEvent.xkey.keycode == xevent.xkey.keycode) &&
 
1069
                 (m_X11LastEvent.xkey.time == xevent.xkey.time) )
 
1070
            {
 
1071
              bProcessEvent = false;;
 
1072
            }
 
1073
          }
 
1074
        }
 
1075
      }
 
1076
 
 
1077
      if (xevent.type == MotionNotify)
 
1078
      {
 
1079
        while (XCheckTypedEvent (m_X11Display, MotionNotify, &xevent) );
 
1080
      }
 
1081
 
 
1082
      /*if(previous_event_motion == true)
 
1083
      {
 
1084
          if(xevent.type == MotionNotify)
 
1085
          {
 
1086
 
 
1087
              if((motion_x == xevent.xmotion.x) && (motion_y == xevent.xmotion.y))
 
1088
              {
 
1089
                  //printf("skipmotion\n");
 
1090
                  bProcessEvent = false;
 
1091
              }
 
1092
              else
 
1093
              {
 
1094
                  motion_x = xevent.xmotion.x;
 
1095
                  motion_y = xevent.xmotion.y;
 
1096
              }
 
1097
          }
 
1098
          else
 
1099
          {
 
1100
              previous_event_motion = false;
 
1101
          }
 
1102
      }
 
1103
      else if(xevent.type == MotionNotify)
 
1104
      {
 
1105
          //printf("motion\n");
 
1106
          previous_event_motion = true;
 
1107
          motion_x = xevent.xmotion.x;
 
1108
          motion_y = xevent.xmotion.y;
 
1109
      }*/
 
1110
 
 
1111
      if (bProcessEvent)
 
1112
        ProcessXEvent (xevent, false);
 
1113
 
 
1114
      memcpy (evt, m_pEvent, sizeof (IEvent) );
 
1115
 
 
1116
    }
 
1117
    else
 
1118
    {
 
1119
      memcpy (evt, m_pEvent, sizeof (IEvent) );
 
1120
    }
 
1121
  }
 
1122
 
 
1123
  void GLWindowImpl::ProcessForeignX11Event (XEvent *xevent, IEvent *nux_event)
 
1124
  {
 
1125
    m_pEvent->Reset();
 
1126
    // Erase mouse event and mouse doubleclick states. Keep the mouse states.
 
1127
    m_pEvent->e_mouse_state &= 0x0F000000;
 
1128
    bool bProcessEvent = true;
 
1129
 
 
1130
    // Process event matching this window
 
1131
    if (true /*(NUX_REINTERPRET_CAST(XAnyEvent*, xevent))->window == m_X11Window*/)
 
1132
    {
 
1133
      // Detect auto repeat keys. X11 sends a combination of KeyRelease/KeyPress (at the same time) when a key auto repeats.
 
1134
      // Here, we make sure we process only the keyRelease when the key is effectively released.
 
1135
      if ( (xevent->type == KeyPress) || (xevent->type == KeyRelease) )
 
1136
      {
 
1137
        if (xevent->xkey.keycode < 256)
 
1138
        {
 
1139
          // Detect if a key is repeated
 
1140
          char Keys[32];
 
1141
          // The XQueryKeymap function returns a bit vector for the logical state of the keyboard, where each bit set
 
1142
          // to 1 indicates that the corresponding key is currently pressed down. The vector is represented as 32 bytes.
 
1143
          // Byte N (from 0) contains the bits for keys 8N to 8N + 7 with the least significant bit in the byte representing
 
1144
          // key 8N.
 
1145
          // Note that the logical state of a device (as seen by client applications) may lag the physical state if device
 
1146
          // event processing is frozen.
 
1147
 
 
1148
          XQueryKeymap (m_X11Display, Keys);
 
1149
 
 
1150
          if (Keys[xevent->xkey.keycode >> 3] & (1 << (xevent->xkey.keycode % 8) ) )
 
1151
          {
 
1152
            // KeyRelease event + KeyDown = discard repeated event
 
1153
            if (xevent->type == KeyRelease)
 
1154
            {
 
1155
              m_X11LastEvent = *xevent;
 
1156
              bProcessEvent = false;
 
1157
            }
 
1158
 
 
1159
            // KeyPress event + key repeat disabled + matching KeyRelease event = discard repeated event
 
1160
            if ( (xevent->type == KeyPress) && (!m_X11RepeatKey) &&
 
1161
                 (m_X11LastEvent.xkey.keycode == xevent->xkey.keycode) &&
 
1162
                 (m_X11LastEvent.xkey.time == xevent->xkey.time) )
 
1163
            {
 
1164
              bProcessEvent = false;;
 
1165
            }
 
1166
          }
 
1167
        }
 
1168
      }
 
1169
 
 
1170
      if (xevent->type == MotionNotify)
 
1171
      {
 
1172
        while (XCheckTypedEvent (m_X11Display, MotionNotify, xevent) );
 
1173
      }
 
1174
 
 
1175
      if (bProcessEvent)
 
1176
        ProcessXEvent (*xevent, true);
 
1177
 
 
1178
      memcpy (nux_event, m_pEvent, sizeof (IEvent) );
 
1179
    }
 
1180
    else
 
1181
    {
 
1182
      memcpy (nux_event, m_pEvent, sizeof (IEvent) );
 
1183
    }
 
1184
  }
 
1185
 
 
1186
  IEvent &GLWindowImpl::GetCurrentEvent()
 
1187
  {
 
1188
    return *m_pEvent;
 
1189
  }
 
1190
 
 
1191
  bool GLWindowImpl::HasXPendingEvent() const
 
1192
  {
 
1193
    return XPending (m_X11Display) ? true : false;
 
1194
  }
 
1195
 
 
1196
  void GLWindowImpl::RecalcXYPosition (Window TheMainWindow, XEvent xevent, int &x_recalc, int &y_recalc)
 
1197
  {
 
1198
    int main_window_x = m_WindowPosition.x;
 
1199
    int main_window_y = m_WindowPosition.y;
 
1200
    bool same = (TheMainWindow == xevent.xany.window);
 
1201
    
 
1202
    switch (xevent.type)
 
1203
    {
 
1204
      case ButtonPress:
 
1205
      case ButtonRelease:
 
1206
      {
 
1207
        if (same)
 
1208
        {
 
1209
          x_recalc = xevent.xbutton.x;
 
1210
          y_recalc = xevent.xbutton.y;
 
1211
        }
 
1212
        else
 
1213
        {
 
1214
          x_recalc = xevent.xbutton.x_root - main_window_x;
 
1215
          y_recalc = xevent.xbutton.y_root - main_window_y;
 
1216
        }
 
1217
        break;
 
1218
      }
 
1219
 
 
1220
      case MotionNotify:
 
1221
      {
 
1222
        if (same)
 
1223
        {
 
1224
          x_recalc = xevent.xmotion.x;
 
1225
          y_recalc = xevent.xmotion.y;
 
1226
        }
 
1227
        else
 
1228
        {
 
1229
          x_recalc = xevent.xmotion.x_root - main_window_x;
 
1230
          y_recalc = xevent.xmotion.y_root - main_window_y;
 
1231
        }
 
1232
        break;
 
1233
      }
 
1234
 
 
1235
      case LeaveNotify:
 
1236
      case EnterNotify:
 
1237
      {
 
1238
        if (same)
 
1239
        {
 
1240
          x_recalc = xevent.xcrossing.x;
 
1241
          y_recalc = xevent.xcrossing.y;
 
1242
        }
 
1243
        else
 
1244
        {
 
1245
          x_recalc = xevent.xcrossing.x_root - main_window_x;
 
1246
          y_recalc = xevent.xcrossing.y_root - main_window_y;
 
1247
        }
 
1248
        break;
 
1249
      }
 
1250
      
 
1251
      default:
 
1252
      {
 
1253
        x_recalc = y_recalc = 0;
 
1254
      }
 
1255
    }
 
1256
  }
 
1257
 
 
1258
  void GLWindowImpl::ProcessXEvent (XEvent xevent, bool foreign)
 
1259
  {
 
1260
    int x_recalc = 0;
 
1261
    int y_recalc = 0;
 
1262
    
 
1263
    RecalcXYPosition (m_X11Window, xevent, x_recalc, y_recalc);
 
1264
    
 
1265
    foreign = foreign || xevent.xany.window != m_X11Window;
 
1266
 
 
1267
    m_pEvent->e_event = NUX_NO_EVENT;
 
1268
 
 
1269
    switch (xevent.type)
 
1270
    {
 
1271
      case DestroyNotify:
 
1272
      {
 
1273
        if (foreign)
 
1274
          break;
 
1275
          
 
1276
        m_pEvent->e_event = NUX_DESTROY_WINDOW;
 
1277
        //nuxDebugMsg(TEXT("[GLWindowImpl::ProcessXEvents]: DestroyNotify event."));
 
1278
        break;
 
1279
      }
 
1280
 
 
1281
      case Expose:
 
1282
      {
 
1283
        if (foreign)
 
1284
          break;
 
1285
        
 
1286
        m_pEvent->e_event = NUX_WINDOW_DIRTY;
 
1287
        //nuxDebugMsg(TEXT("[GLWindowImpl::ProcessXEvents]: Expose event."));
 
1288
        break;
 
1289
      }
 
1290
 
 
1291
 
 
1292
      case ConfigureNotify:
 
1293
      {
 
1294
        if (foreign)
 
1295
          break;
 
1296
        
 
1297
        m_pEvent->e_event = NUX_SIZE_CONFIGURATION;
 
1298
        m_pEvent->width =  xevent.xconfigure.width;
 
1299
        m_pEvent->height = xevent.xconfigure.height;
 
1300
        m_WindowSize.SetWidth (xevent.xconfigure.width);
 
1301
        m_WindowSize.SetHeight (xevent.xconfigure.height);
 
1302
        m_WindowPosition.Set (xevent.xconfigure.x, xevent.xconfigure.y);
 
1303
 
 
1304
        //nuxDebugMsg(TEXT("[GLWindowImpl::ProcessXEvents]: ConfigureNotify event."));
 
1305
        break;
 
1306
      }
 
1307
 
 
1308
      case FocusIn:
 
1309
      {
 
1310
        if (foreign)
 
1311
          break;
 
1312
        
 
1313
        m_pEvent->e_event = NUX_WINDOW_ENTER_FOCUS;
 
1314
        m_pEvent->e_mouse_state = 0;
 
1315
 
 
1316
        // This causes the mouse to be outside of all widgets when it is tested in m_EventHandler.Process().
 
1317
        // Because WM_SETFOCUS can happen with the mouse outside of the client area, we set e_x and e_y so that the mouse will be
 
1318
        // outside of all widgets. A subsequent mouse down or mouse move event will set the correct values for e_x and e_y.
 
1319
        m_pEvent->e_x = 0xFFFFFFFF;
 
1320
        m_pEvent->e_y = 0xFFFFFFFF;
 
1321
        m_pEvent->e_dx = 0;
 
1322
        m_pEvent->e_dy = 0;
 
1323
        m_pEvent->virtual_code = 0;
 
1324
        //nuxDebugMsg(TEXT("[GLWindowImpl::ProcessXEvents]: FocusIn event."));
 
1325
        break;
 
1326
      }
 
1327
 
 
1328
      case FocusOut:
 
1329
      {
 
1330
        if (foreign)
 
1331
          break;
 
1332
        
 
1333
        m_pEvent->e_event = NUX_WINDOW_EXIT_FOCUS;
 
1334
        m_pEvent->e_mouse_state = 0;
 
1335
 
 
1336
        // This causes the mouse to be outside of all widgets when it is tested in m_EventHandler.Process()
 
1337
        m_pEvent->e_x = 0xFFFFFFFF;
 
1338
        m_pEvent->e_y = 0xFFFFFFFF;
 
1339
        m_pEvent->e_dx = 0;
 
1340
        m_pEvent->e_dy = 0;
 
1341
        m_pEvent->virtual_code = 0;
 
1342
        //nuxDebugMsg(TEXT("[GLWindowImpl::ProcessXEvents]: FocusOut event."));
 
1343
        break;
 
1344
      }
 
1345
 
 
1346
      case KeyPress:
 
1347
      {
 
1348
        //nuxDebugMsg(TEXT("[GLWindowImpl::ProcessXEvents]: KeyPress event."));
 
1349
        KeyCode keycode = xevent.xkey.keycode;
 
1350
        KeySym keysym = NoSymbol;
 
1351
        keysym = XKeycodeToKeysym (m_X11Display, keycode, 0);
 
1352
        unsigned int inlKeysym = GLWindowImpl::X11KeySymToINL (keysym);
 
1353
        m_pEvent->VirtualKeycodeState[inlKeysym] = 1;
 
1354
 
 
1355
        m_pEvent->e_key_modifiers = GetModifierKeyState (xevent.xkey.state);
 
1356
 
 
1357
        m_pEvent->e_key_repeat_count = 0;
 
1358
        m_pEvent->e_keysym = inlKeysym;
 
1359
        m_pEvent->e_event = NUX_KEYDOWN;
 
1360
 
 
1361
        static XComposeStatus ComposeStatus;
 
1362
        static char buffer[16];
 
1363
        m_pEvent->e_text[0] = 0;
 
1364
 
 
1365
        //nuxDebugMsg(TEXT("[GLWindowImpl::ProcessXEvents]: Keysym: %d - %x."), keysym, keysym);
 
1366
        if (XLookupString (&xevent.xkey, buffer, sizeof (buffer), NULL, &ComposeStatus) )
 
1367
        {
 
1368
          m_pEvent->e_text[0] = buffer[0];
 
1369
        }
 
1370
 
 
1371
        break;
 
1372
      }
 
1373
 
 
1374
      case KeyRelease:
 
1375
      {
 
1376
        //nuxDebugMsg(TEXT("[GLWindowImpl::ProcessXEvents]: KeyRelease event."));
 
1377
        KeyCode keycode = xevent.xkey.keycode;
 
1378
        KeySym keysym = NoSymbol;
 
1379
        keysym = XKeycodeToKeysym (m_X11Display, keycode, 0);
 
1380
        unsigned int inlKeysym = GLWindowImpl::X11KeySymToINL (keysym);
 
1381
        m_pEvent->VirtualKeycodeState[inlKeysym] = 0;
 
1382
 
 
1383
        m_pEvent->e_key_modifiers = GetModifierKeyState (xevent.xkey.state);
 
1384
 
 
1385
        m_pEvent->e_key_repeat_count = 0;
 
1386
        m_pEvent->e_keysym = inlKeysym;
 
1387
        m_pEvent->e_event = NUX_KEYUP;
 
1388
        break;
 
1389
      }
 
1390
 
 
1391
      case ButtonPress:
 
1392
      {
 
1393
        m_pEvent->e_x = x_recalc;
 
1394
        m_pEvent->e_y = y_recalc;
 
1395
        m_pEvent->e_x_root = 0;
 
1396
        m_pEvent->e_y_root = 0;
 
1397
        mouse_press (xevent, m_pEvent);
 
1398
        //nuxDebugMsg(TEXT("[GLWindowImpl::ProcessXEvents]: ButtonPress event."));
 
1399
        break;
 
1400
      }
 
1401
 
 
1402
      case ButtonRelease:
 
1403
      {
 
1404
        m_pEvent->e_x = x_recalc;
 
1405
        m_pEvent->e_y = y_recalc;
 
1406
        m_pEvent->e_x_root = 0;
 
1407
        m_pEvent->e_y_root = 0;
 
1408
        mouse_release (xevent, m_pEvent);
 
1409
        //nuxDebugMsg(TEXT("[GLWindowImpl::ProcessXEvents]: ButtonRelease event."));
 
1410
        break;
 
1411
      }
 
1412
 
 
1413
      case MotionNotify:
 
1414
      {
 
1415
        m_pEvent->e_x = x_recalc;
 
1416
        m_pEvent->e_y = y_recalc;
 
1417
        m_pEvent->e_x_root = 0;
 
1418
        m_pEvent->e_y_root = 0;
 
1419
        mouse_move (xevent, m_pEvent);
 
1420
        //nuxDebugMsg(TEXT("[GLWindowImpl::ProcessXEvents]: MotionNotify event."));
 
1421
        break;
 
1422
      }
 
1423
 
 
1424
      // Note: there is no WM_MOUSEENTER. WM_MOUSEENTER is equivalent to WM_MOUSEMOVE after a WM_MOUSELEAVE.
 
1425
      case LeaveNotify:
 
1426
      {
 
1427
        m_pEvent->e_event = NUX_WINDOW_MOUSELEAVE;
 
1428
        m_pEvent->e_x = x_recalc;
 
1429
        m_pEvent->e_y = y_recalc;
 
1430
        //nuxDebugMsg(TEXT("[GLWindowImpl::ProcessXEvents]: LeaveNotify event."));
 
1431
        break;
 
1432
      }
 
1433
 
 
1434
      case EnterNotify:
 
1435
      {
 
1436
        m_pEvent->e_event = NUX_WINDOW_MOUSELEAVE;
 
1437
        m_pEvent->e_x = x_recalc;
 
1438
        m_pEvent->e_y = y_recalc;
 
1439
        //nuxDebugMsg(TEXT("[GLWindowImpl::ProcessXEvents]: EnterNotify event."));
 
1440
        break;
 
1441
      }
 
1442
 
 
1443
      case ClientMessage:
 
1444
      {
 
1445
        if (foreign)
 
1446
          break;
 
1447
        
 
1448
        if ( (xevent.xclient.format == 32) && ( (xevent.xclient.data.l[0]) == static_cast<long> (m_WMDeleteWindow) ) )
 
1449
        {
 
1450
          m_pEvent->e_event = NUX_TERMINATE_APP;
 
1451
          //nuxDebugMsg(TEXT("[GLWindowImpl::ProcessXEvents]: ClientMessage event: Close Application."));
 
1452
        }
 
1453
 
 
1454
        break;
 
1455
      }
 
1456
    }
 
1457
  }
 
1458
 
 
1459
  int GLWindowImpl::X11KeySymToINL (int Keysym)
 
1460
  {
 
1461
    switch (Keysym)
 
1462
    {
 
1463
      case XK_Cancel:
 
1464
        return NUX_VK_CANCEL;
 
1465
      case XK_BackSpace:
 
1466
        return NUX_VK_BACKSPACE;
 
1467
      case XK_Tab:
 
1468
        return NUX_VK_TAB;
 
1469
      case XK_Clear:
 
1470
        return NUX_VK_CLEAR;
 
1471
      case XK_Return:
 
1472
        return NUX_VK_ENTER;
 
1473
      case XK_Shift_L:
 
1474
        return NUX_VK_SHIFT;
 
1475
      case XK_Control_L:
 
1476
        return NUX_VK_CONTROL;
 
1477
      case XK_Alt_L:
 
1478
        return NUX_VK_MENU;
 
1479
      case XK_Pause:
 
1480
        return NUX_VK_PAUSE;
 
1481
      case XK_Caps_Lock:
 
1482
        return NUX_VK_CAPITAL;
 
1483
      case XK_Escape:
 
1484
        return NUX_VK_ESCAPE;
 
1485
      case XK_space:
 
1486
        return NUX_VK_SPACE;
 
1487
      case XK_Page_Up:
 
1488
        return NUX_VK_PAGE_UP;
 
1489
      case XK_Page_Down:
 
1490
        return NUX_VK_PAGE_DOWN;
 
1491
      case XK_End:
 
1492
        return NUX_VK_END;
 
1493
      case XK_Home:
 
1494
        return NUX_VK_HOME;
 
1495
      case XK_Left:
 
1496
        return NUX_VK_LEFT;
 
1497
      case XK_Up:
 
1498
        return NUX_VK_UP;
 
1499
      case XK_Right:
 
1500
        return NUX_VK_RIGHT;
 
1501
      case XK_Down:
 
1502
        return NUX_VK_DOWN;
 
1503
      case XK_Select:
 
1504
        return NUX_VK_SELECT;
 
1505
      case XK_Print:
 
1506
        return NUX_VK_PRINT;
 
1507
      case XK_Execute:
 
1508
        return NUX_VK_EXECUTE;
 
1509
      case XK_Insert:
 
1510
        return NUX_VK_INSERT;
 
1511
      case XK_Delete:
 
1512
        return NUX_VK_DELETE;
 
1513
      case XK_Help:
 
1514
        return NUX_VK_HELP;
 
1515
      case XK_0:
 
1516
        return NUX_VK_0;
 
1517
      case XK_1:
 
1518
        return NUX_VK_1;
 
1519
      case XK_2:
 
1520
        return NUX_VK_2;
 
1521
      case XK_3:
 
1522
        return NUX_VK_3;
 
1523
      case XK_4:
 
1524
        return NUX_VK_4;
 
1525
      case XK_5:
 
1526
        return NUX_VK_5;
 
1527
      case XK_6:
 
1528
        return NUX_VK_6;
 
1529
      case XK_7:
 
1530
        return NUX_VK_7;
 
1531
      case XK_8:
 
1532
        return NUX_VK_8;
 
1533
      case XK_9:
 
1534
        return NUX_VK_9;
 
1535
      case XK_A:
 
1536
        return NUX_VK_A;
 
1537
      case XK_B:
 
1538
        return NUX_VK_B;
 
1539
      case XK_C:
 
1540
        return NUX_VK_C;
 
1541
      case XK_D:
 
1542
        return NUX_VK_D;
 
1543
      case XK_E:
 
1544
        return NUX_VK_E;
 
1545
      case XK_F:
 
1546
        return NUX_VK_F;
 
1547
      case XK_G:
 
1548
        return NUX_VK_G;
 
1549
      case XK_H:
 
1550
        return NUX_VK_H;
 
1551
      case XK_I:
 
1552
        return NUX_VK_I;
 
1553
      case XK_J:
 
1554
        return NUX_VK_J;
 
1555
      case XK_K:
 
1556
        return NUX_VK_K;
 
1557
      case XK_L:
 
1558
        return NUX_VK_L;
 
1559
      case XK_M:
 
1560
        return NUX_VK_M;
 
1561
      case XK_N:
 
1562
        return NUX_VK_N;
 
1563
      case XK_O:
 
1564
        return NUX_VK_O;
 
1565
      case XK_P:
 
1566
        return NUX_VK_P;
 
1567
      case XK_Q:
 
1568
        return NUX_VK_Q;
 
1569
      case XK_R:
 
1570
        return NUX_VK_R;
 
1571
      case XK_S:
 
1572
        return NUX_VK_S;
 
1573
      case XK_T:
 
1574
        return NUX_VK_T;
 
1575
      case XK_U:
 
1576
        return NUX_VK_U;
 
1577
      case XK_V:
 
1578
        return NUX_VK_V;
 
1579
      case XK_W:
 
1580
        return NUX_VK_W;
 
1581
      case XK_X:
 
1582
        return NUX_VK_X;
 
1583
      case XK_Y:
 
1584
        return NUX_VK_Y;
 
1585
      case XK_Z:
 
1586
        return NUX_VK_Z;
 
1587
      case XK_Super_L:
 
1588
        return NUX_VK_LWIN;
 
1589
      case XK_Super_R:
 
1590
        return NUX_VK_RWIN;
 
1591
      case XK_KP_0:
 
1592
        return NUX_VK_NUMPAD0;
 
1593
      case XK_KP_1:
 
1594
        return NUX_VK_NUMPAD1;
 
1595
      case XK_KP_2:
 
1596
        return NUX_VK_NUMPAD2;
 
1597
      case XK_KP_3:
 
1598
        return NUX_VK_NUMPAD3;
 
1599
      case XK_KP_4:
 
1600
        return NUX_VK_NUMPAD4;
 
1601
      case XK_KP_5:
 
1602
        return NUX_VK_NUMPAD5;
 
1603
      case XK_KP_6:
 
1604
        return NUX_VK_NUMPAD6;
 
1605
      case XK_KP_7:
 
1606
        return NUX_VK_NUMPAD7;
 
1607
      case XK_KP_8:
 
1608
        return NUX_VK_NUMPAD8;
 
1609
      case XK_KP_9:
 
1610
        return NUX_VK_NUMPAD9;
 
1611
      case XK_KP_Multiply:
 
1612
        return NUX_VK_MULTIPLY;
 
1613
      case XK_KP_Add:
 
1614
        return NUX_VK_ADD;
 
1615
      case XK_KP_Separator:
 
1616
        return NUX_VK_SEPARATOR;
 
1617
      case XK_KP_Subtract:
 
1618
        return NUX_VK_SUBTRACT;
 
1619
      case XK_KP_Decimal:
 
1620
        return NUX_VK_DECIMAL;
 
1621
      case XK_KP_Divide:
 
1622
        return NUX_VK_DIVIDE;
 
1623
      case XK_F1:
 
1624
        return NUX_VK_F1;
 
1625
      case XK_F2:
 
1626
        return NUX_VK_F2;
 
1627
      case XK_F3:
 
1628
        return NUX_VK_F3;
 
1629
      case XK_F4:
 
1630
        return NUX_VK_F4;
 
1631
      case XK_F5:
 
1632
        return NUX_VK_F5;
 
1633
      case XK_F6:
 
1634
        return NUX_VK_F6;
 
1635
      case XK_F7:
 
1636
        return NUX_VK_F7;
 
1637
      case XK_F8:
 
1638
        return NUX_VK_F8;
 
1639
      case XK_F9:
 
1640
        return NUX_VK_F9;
 
1641
      case XK_F10:
 
1642
        return NUX_VK_F10;
 
1643
      case XK_F11:
 
1644
        return NUX_VK_F11;
 
1645
      case XK_F12:
 
1646
        return NUX_VK_F12;
 
1647
      case XK_F13:
 
1648
        return NUX_VK_F13;
 
1649
      case XK_F14:
 
1650
        return NUX_VK_F14;
 
1651
      case XK_F15:
 
1652
        return NUX_VK_F15;
 
1653
      case XK_F16:
 
1654
        return NUX_VK_F16;
 
1655
      case XK_F17:
 
1656
        return NUX_VK_F17;
 
1657
      case XK_F18:
 
1658
        return NUX_VK_F18;
 
1659
      case XK_F19:
 
1660
        return NUX_VK_F19;
 
1661
      case XK_F20:
 
1662
        return NUX_VK_F20;
 
1663
      case XK_F21:
 
1664
        return NUX_VK_F21;
 
1665
      case XK_F22:
 
1666
        return NUX_VK_F22;
 
1667
      case XK_F23:
 
1668
        return NUX_VK_F23;
 
1669
      case XK_F24:
 
1670
        return NUX_VK_F24;
 
1671
      case XK_Num_Lock:
 
1672
        return NUX_VK_NUMLOCK;
 
1673
      case XK_Scroll_Lock:
 
1674
        return NUX_VK_SCROLL;
 
1675
      case XK_Shift_R:
 
1676
        return NUX_VK_RSHIFT;
 
1677
      case XK_Control_R:
 
1678
        return NUX_VK_RCONTROL;
 
1679
      case XK_Alt_R:
 
1680
        return NUX_VK_RMENU;
 
1681
      default:
 
1682
        return 0x0;
 
1683
    }
 
1684
  };
 
1685
 
 
1686
//---------------------------------------------------------------------------------------------------------
 
1687
  void GLWindowImpl::ShowWindow()
 
1688
  {
 
1689
#if defined(_WIN32)
 
1690
    ::ShowWindow (hWnd, SW_RESTORE);
 
1691
#endif
 
1692
  }
 
1693
 
 
1694
//---------------------------------------------------------------------------------------------------------
 
1695
  void GLWindowImpl::HideWindow()
 
1696
  {
 
1697
#if defined(_WIN32)
 
1698
    ::ShowWindow (hWnd, SW_MINIMIZE);
 
1699
#endif
 
1700
  }
 
1701
 
 
1702
//---------------------------------------------------------------------------------------------------------
 
1703
  void GLWindowImpl::EnterMaximizeWindow()
 
1704
  {
 
1705
#if defined(_WIN32)
 
1706
    ::ShowWindow (hWnd, SW_MAXIMIZE);
 
1707
#endif
 
1708
  }
 
1709
 
 
1710
//---------------------------------------------------------------------------------------------------------
 
1711
  void GLWindowImpl::ExitMaximizeWindow()
 
1712
  {
 
1713
#if defined(_WIN32)
 
1714
    ::ShowWindow (hWnd, SW_RESTORE);
 
1715
#endif
 
1716
  }
 
1717
 
 
1718
//---------------------------------------------------------------------------------------------------------
 
1719
  void GLWindowImpl::SetWindowTitle (const TCHAR *Title)
 
1720
  {
 
1721
#if defined(_WIN32)
 
1722
    SetWindowText (hWnd, Title);
 
1723
#endif
 
1724
  }
 
1725
 
 
1726
//---------------------------------------------------------------------------------------------------------
 
1727
  bool GLWindowImpl::HasVSyncSwapControl() const
 
1728
  {
 
1729
    return GetThreadGLDeviceFactory()->SUPPORT_WGL_EXT_SWAP_CONTROL();
 
1730
  }
 
1731
 
 
1732
//---------------------------------------------------------------------------------------------------------
 
1733
  void GLWindowImpl::EnableVSyncSwapControl()
 
1734
  {
 
1735
#if _WIN32
 
1736
 
 
1737
    if (HasVSyncSwapControl() )
 
1738
    {
 
1739
      wglSwapIntervalEXT (1);
 
1740
    }
 
1741
 
 
1742
#endif
 
1743
  }
 
1744
 
 
1745
//---------------------------------------------------------------------------------------------------------
 
1746
  void GLWindowImpl::DisableVSyncSwapControl()
 
1747
  {
 
1748
#if _WIN32
 
1749
 
 
1750
    if (HasVSyncSwapControl() )
 
1751
    {
 
1752
      wglSwapIntervalEXT (0);
 
1753
    }
 
1754
 
 
1755
#endif
 
1756
  }
 
1757
 
 
1758
  float GLWindowImpl::GetFrameTime() const
 
1759
  {
 
1760
    return m_FrameTime;
 
1761
  }
 
1762
 
 
1763
  void GLWindowImpl::ResetFrameTime()
 
1764
  {
 
1765
    m_Timer.Reset();
 
1766
  }
 
1767
 
 
1768
  /*
 
1769
  //---------------------------------------------------------------------------------------------------------
 
1770
  bool GLWindowImpl::StartOpenFileDialog(FileDialogOption& fdo)
 
1771
  {
 
1772
      return Win32OpenFileDialog(GetWindowHandle(), fdo);
 
1773
  }
 
1774
 
 
1775
  //---------------------------------------------------------------------------------------------------------
 
1776
  bool GLWindowImpl::StartSaveFileDialog(FileDialogOption& fdo)
 
1777
  {
 
1778
      return Win32SaveFileDialog(GetWindowHandle(), fdo);
 
1779
  }
 
1780
 
 
1781
  //---------------------------------------------------------------------------------------------------------
 
1782
  bool GLWindowImpl::StartColorDialog(ColorDialogOption& cdo)
 
1783
  {
 
1784
      return Win32ColorDialog(GetWindowHandle(), cdo);
 
1785
  }
 
1786
  */
 
1787
//---------------------------------------------------------------------------------------------------------
 
1788
  /*void GLWindowImpl::SetWindowCursor(HCURSOR cursor)
 
1789
  {
 
1790
      m_Cursor = cursor;
 
1791
  }
 
1792
 
 
1793
  //---------------------------------------------------------------------------------------------------------
 
1794
  HCURSOR GLWindowImpl::GetWindowCursor() const
 
1795
  {
 
1796
      return m_Cursor;
 
1797
  }*/
 
1798
 
 
1799
//---------------------------------------------------------------------------------------------------------
 
1800
  void GLWindowImpl::PauseThreadGraphicsRendering()
 
1801
  {
 
1802
    m_PauseGraphicsRendering = true;
 
1803
    MakeGLContextCurrent();
 
1804
  }
 
1805
 
 
1806
//---------------------------------------------------------------------------------------------------------
 
1807
  bool GLWindowImpl::IsPauseThreadGraphicsRendering() const
 
1808
  {
 
1809
    return m_PauseGraphicsRendering;
 
1810
  }
 
1811
 
 
1812
}