2
* Copyright 2010 Inalogic Inc.
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.
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.
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/>
18
* Authored by: Jay Taoko <jay.taoko_AT_gmail_DOT_com>
23
#include "GLResource.h"
24
#include "GpuDevice.h"
25
#include "GLDeviceObjects.h"
26
#include "GLResourceManager.h"
28
#include "GLTextureResourceManager.h"
29
#include "GLVertexResourceManager.h"
30
#include "GraphicsEngine.h"
31
#include "GLWindowManager.h"
35
#include "GfxSetupX11.h"
40
unsigned int gVirtualKeycodeState[NUX_MAX_VK];
42
// Attributes for a single buffered visual in RGBA format
43
static int g_DoubleBufferVisual[] =
56
// Attributes for a single buffered visual in RGBA format
57
// static int g_SingleBufferVisual[] = {
63
// GLX_DEPTH_SIZE, 24,
64
// GLX_STENCIL_SIZE, 8,
67
// Compute the frame rate every FRAME_RATE_PERIODE;
68
#define FRAME_RATE_PERIODE 10
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);
73
EventToNameStruct EventToName[] =
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") }
90
//---------------------------------------------------------------------------------------------------------
92
GLWindowImpl::GLWindowImpl()
97
m_GfxInterfaceCreated = false;
99
m_ScreenBitDepth = 32;
101
m_num_device_modes = 0;
103
m_GraphicsContext = 0;
104
m_Style = WINDOWSTYLE_NORMAL;
105
m_PauseGraphicsRendering = false;
107
inlSetThreadLocalStorage (ThreadLocal_GLWindowImpl, this);
109
m_X11LastEvent.type = -1;
110
m_X11RepeatKey = true;
112
m_GfxInterfaceCreated = false;
113
m_pEvent = new IEvent();
115
m_WindowSize.SetWidth (0);
116
m_WindowSize.SetHeight (0);
118
// A window never starts in a minimized state.
119
m_is_window_minimized = false;
122
//---------------------------------------------------------------------------------------------------------
123
GLWindowImpl::~GLWindowImpl()
125
NUX_SAFE_DELETE ( m_GraphicsContext );
126
NUX_SAFE_DELETE ( m_DeviceFactory );
128
DestroyOpenGLWindow();
129
NUX_SAFE_DELETE ( m_pEvent );
131
inlSetThreadLocalStorage (ThreadLocal_GLWindowImpl, 0);
134
//---------------------------------------------------------------------------------------------------------
135
NString GLWindowImpl::FindResourceLocation (const TCHAR *ResourceFileName, bool ErrorOnFail)
137
NString path = m_ResourcePathLocation.GetFile (ResourceFileName);
139
if (path == TEXT ("") && ErrorOnFail)
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);*/
150
NString GLWindowImpl::FindUITextureLocation (const TCHAR *ResourceFileName, bool ErrorOnFail)
153
searchpath.AddSearchPath (m_UITextureSearchPath);
154
NString path = searchpath.GetFile (ResourceFileName);
156
if ( (path == TEXT ("") ) && ErrorOnFail)
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);*/
167
NString GLWindowImpl::FindShaderLocation (const TCHAR *ResourceFileName, bool ErrorOnFail)
170
searchpath.AddSearchPath (m_ShaderSearchPath);
171
NString path = searchpath.GetFile (ResourceFileName);
173
if ( (path == TEXT ("") ) && ErrorOnFail)
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);*/
184
NString GLWindowImpl::FindFontLocation (const TCHAR *ResourceFileName, bool ErrorOnFail)
187
searchpath.AddSearchPath (m_FontSearchPath);
188
NString path = searchpath.GetFile (ResourceFileName);
190
if ( (path == TEXT ("") ) && ErrorOnFail)
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);*/
202
//---------------------------------------------------------------------------------------------------------
203
bool GLWindowImpl::IsGfxInterfaceCreated()
205
return m_GfxInterfaceCreated;
208
//---------------------------------------------------------------------------------------------------------
209
static NCriticalSection CreateOpenGLWindow_CriticalSection;
210
bool GLWindowImpl::CreateOpenGLWindow (const TCHAR *WindowTitle,
211
unsigned int WindowWidth,
212
unsigned int WindowHeight,
214
const GLWindowImpl *Parent,
217
NScopeLock Scope (&CreateOpenGLWindow_CriticalSection);
219
m_GfxInterfaceCreated = false;
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);
228
m_Fullscreen = FullscreenFlag; // Set The Global Fullscreen Flag
229
m_BestMode = -1; // assume -1 if the mode is not fullscreen
231
m_X11Display = XOpenDisplay (0);
233
if (m_X11Display == 0)
235
nuxDebugMsg (TEXT ("[GLWindowImpl::CreateOpenGLWindow] XOpenDisplay has failed. The window cannot be created.") );
239
m_X11Screen = DefaultScreen (m_X11Display);
240
XF86VidModeQueryVersion (m_X11Display, &m_X11VerMajor, &m_X11VerMinor);
242
XF86VidModeGetAllModeLines (m_X11Display, m_X11Screen, &m_NumVideoModes, &m_X11VideoModes);
243
m_X11OriginalVideoMode = *m_X11VideoModes[0];
245
if (m_Fullscreen) // Attempt Fullscreen Mode?
247
// check if resolution is supported
248
bool mode_supported = false;
250
for (int num_modes = 0 ; num_modes < m_NumVideoModes; num_modes++)
252
if ( (m_X11VideoModes[num_modes]->hdisplay == m_ViewportSize.GetWidth() )
253
&& (m_X11VideoModes[num_modes]->vdisplay == m_ViewportSize.GetHeight() ) )
255
mode_supported = true;
256
m_BestMode = num_modes;
261
if (mode_supported == false)
263
m_Fullscreen = false;
267
glXQueryVersion (m_X11Display, &m_GLXVerMajor, &m_GLXVerMinor);
269
// Get an appropriate visual
270
m_X11VisualInfo = glXChooseVisual (m_X11Display, m_X11Screen, g_DoubleBufferVisual);
272
if (m_X11VisualInfo == NULL)
274
nuxDebugMsg (TEXT ("[GLWindowImpl::CreateOpenGLWindow] Cannot get appropriate visual.") );
278
m_GLCtx = glXCreateContext (m_X11Display, m_X11VisualInfo, 0, GL_TRUE);
280
m_X11Colormap = XCreateColormap (m_X11Display,
281
RootWindow (m_X11Display, m_X11VisualInfo->screen),
282
m_X11VisualInfo->visual,
285
m_X11Attr.border_pixel = 0;
286
m_X11Attr.colormap = m_X11Colormap;
287
m_X11Attr.override_redirect = m_Fullscreen;
288
m_X11Attr.event_mask =
290
/*Button1MotionMask |
299
//-OwnerGrabButtonMask |
300
//PointerMotionHintMask |
303
//--KeymapStateMask |
313
//--ResizeRedirectMask |
314
StructureNotifyMask;// |
315
//--SubstructureNotifyMask |
316
//--SubstructureRedirectMask |
318
//--VisibilityChangeMask |
320
//--PropertyChangeMask |
322
//--ColormapChangeMask |
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);
335
/* create a fullscreen window */
337
m_X11Window = XCreateWindow (m_X11Display,
338
RootWindow (m_X11Display, m_X11VisualInfo->screen),
340
m_WindowSize.GetWidth(), m_WindowSize.GetHeight(),
342
m_X11VisualInfo->depth, // Depth
343
InputOutput, // Class
344
m_X11VisualInfo->visual, // Visual
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,
357
XGrabPointer (m_X11Display, m_X11Window, True,
359
GrabModeAsync, GrabModeAsync, m_X11Window, None, CurrentTime);
363
m_X11Window = XCreateWindow (m_X11Display,
364
RootWindow (m_X11Display, m_X11VisualInfo->screen),
366
m_WindowSize.GetWidth(), m_WindowSize.GetHeight(),
368
m_X11VisualInfo->depth,
370
m_X11VisualInfo->visual,
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);
381
XSetStandardProperties (m_X11Display, m_X11Window, WindowTitle, WindowTitle, None, NULL, 0, NULL);
382
XMapRaised (m_X11Display, m_X11Window);
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);
390
m_GfxInterfaceCreated = true;
392
m_DeviceFactory = new GpuDevice (m_ViewportSize.GetWidth(), m_ViewportSize.GetHeight(), BITFMT_R8G8B8A8);
393
m_GraphicsContext = new GraphicsEngine (*this);
395
EnableVSyncSwapControl();
396
//DisableVSyncSwapControl();
401
bool GLWindowImpl::CreateFromOpenGLWindow (Display *X11Display, Window X11Window, GLXContext OpenGLContext)
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
408
m_X11Display = X11Display;
409
m_X11Window = X11Window;
410
m_GLCtx = OpenGLContext;
413
int x_return, y_return;
414
unsigned int width_return, height_return;
415
unsigned int border_width_return;
416
unsigned int depth_return;
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);
422
m_ViewportSize = Size (width_return, height_return);
424
m_GfxInterfaceCreated = true;
426
m_DeviceFactory = new GpuDevice (m_ViewportSize.GetWidth(), m_ViewportSize.GetHeight(), BITFMT_R8G8B8A8);
427
m_GraphicsContext = new GraphicsEngine (*this);
432
// bool GLWindowImpl::CreateVisual(unsigned int WindowWidth, unsigned int WindowHeight, XVisualInfo& ChosenVisual, XVisualInfo& Template, unsigned long Mask)
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);
439
// if(!VisualsArray || (NunberOfVisuals == 0))
442
// XFree(VisualsArray);
443
// nuxDebugMsg(TEXT("[GLWindowImpl::CreateVisual] There is no matching visuals."));
447
// // Find the best visual
448
// int BestScore = 0xFFFF;
449
// XVisualInfo* BestVisual = NULL;
450
// while (!BestVisual)
452
// for (int i = 0; i < NunberOfVisuals; ++i)
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);
467
// // First check the mandatory parameters
468
// if ((RGBA == 0) || (DoubleBuffer == 0))
471
// // Evaluate the current configuration
472
// int Color = Red + Green + Blue + Alpha;
473
// int Score = EvaluateConfig(Mode, Params, Color, Depth, Stencil, MultiSampling ? Samples : 0);
475
// // Keep it if it's better than the current best
476
// if (Score < BestScore)
478
// BestScore = Score;
479
// BestVisual = &Visuals[i];
483
// // If no visual has been found, try a lower level of antialiasing
486
// if (Params.AntialiasingLevel > 2)
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;
492
// else if (Params.AntialiasingLevel > 0)
494
// std::cerr << "Failed to find a pixel format supporting antialiasing ; antialiasing will be disabled" << std::endl;
495
// Params.AntialiasingLevel = 0;
499
// std::cerr << "Failed to find a suitable pixel format for the window -- cannot create OpenGL context" << std::endl;
505
// // Create the OpenGL context
506
// myGLContext = glXCreateContext(ourDisplay, BestVisual, glXGetCurrentContext(), true);
507
// if (myGLContext == NULL)
509
// std::cerr << "Failed to create an OpenGL context for this window" << std::endl;
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);
520
// // Assign the chosen visual, and free the temporary visuals array
521
// ChosenVisual = *BestVisual;
524
// // Activate the context
527
// // Enable multisampling if needed
528
// if (Params.AntialiasingLevel > 0)
529
// glEnable(GL_MULTISAMPLE_ARB);
534
//---------------------------------------------------------------------------------------------------------
535
bool GLWindowImpl::HasFrameBufferSupport()
537
return m_DeviceFactory->SUPPORT_GL_EXT_FRAMEBUFFER_OBJECT();
540
//---------------------------------------------------------------------------------------------------------
541
void GLWindowImpl::GetWindowSize (int &w, int &h)
543
w = m_WindowSize.GetWidth();
544
h = m_WindowSize.GetHeight();
547
void GLWindowImpl::GetDesktopSize (int &w, int &h)
551
unsigned int width, height, depth, border_width;
552
bool ret = XGetGeometry (m_X11Display, RootWindow (m_X11Display, m_X11Screen),
555
&width, &height, &border_width, &depth);
559
nuxAssert (TEXT ("[GetDesktopSize] Failed to get the desktop size") );
565
//---------------------------------------------------------------------------------------------------------
566
void GLWindowImpl::SetWindowSize (int width, int height)
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);
574
//---------------------------------------------------------------------------------------------------------
575
void GLWindowImpl::SetWindowPosition (int x, int y)
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);
583
//---------------------------------------------------------------------------------------------------------
584
unsigned int GLWindowImpl::GetWindowWidth()
586
return m_WindowSize.GetWidth();
589
//---------------------------------------------------------------------------------------------------------
590
unsigned int GLWindowImpl::GetWindowHeight()
592
return m_WindowSize.GetHeight();
595
//---------------------------------------------------------------------------------------------------------
596
void GLWindowImpl::SetViewPort (int x, int y, int width, int height)
599
if (IsGfxInterfaceCreated() )
601
//do not rely on m_ViewportSize: glViewport can be called directly
602
m_ViewportSize.SetWidth (width);
603
m_ViewportSize.SetHeight (height);
605
m_GraphicsContext->SetViewport (x, y, m_ViewportSize.GetWidth(), m_ViewportSize.GetHeight() );
606
m_GraphicsContext->SetScissor (0, 0, width, height);
610
Point GLWindowImpl::GetMouseScreenCoord()
618
unsigned int mask_return;
621
XQueryPointer (m_X11Display,
622
RootWindow (m_X11Display, m_X11Screen),
630
XFlush (m_X11Display);
632
return Point (root_x_return, root_y_return);
635
Point GLWindowImpl::GetMouseWindowCoord()
643
unsigned int mask_return;
645
XQueryPointer (m_X11Display,
646
RootWindow (m_X11Display, m_X11Screen),
654
XFlush (m_X11Display);
656
return Point (win_x_return, win_y_return);
659
Point GLWindowImpl::GetWindowCoord()
661
XWindowAttributes attrib;
662
int status = XGetWindowAttributes (m_X11Display, m_X11Window, &attrib);
666
nuxAssert (TEXT ("[GLWindowImpl::GetWindowCoord] Failed to get the window attributes.") );
670
return Point (attrib.x, attrib.y);
673
Rect GLWindowImpl::GetWindowGeometry()
675
XWindowAttributes attrib;
676
int status = XGetWindowAttributes (m_X11Display, m_X11Window, &attrib);
680
nuxAssert (TEXT ("[GLWindowImpl::GetWindowGeometry] Failed to get the window attributes.") );
681
return Rect (0, 0, 0, 0);
684
return Rect (attrib.x, attrib.y, attrib.width, attrib.height);
687
Rect GLWindowImpl::GetNCWindowGeometry()
689
XWindowAttributes attrib;
690
int status = XGetWindowAttributes (m_X11Display, m_X11Window, &attrib);
694
nuxAssert (TEXT ("[GLWindowImpl::GetWindowGeometry] Failed to get the window attributes.") );
695
return Rect (0, 0, 0, 0);
698
return Rect (attrib.x, attrib.y, attrib.width, attrib.height);
701
void GLWindowImpl::MakeGLContextCurrent()
703
if (!glXMakeCurrent (m_X11Display, m_X11Window, m_GLCtx) )
705
DestroyOpenGLWindow();
709
void GLWindowImpl::SwapBuffer (bool glswap)
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.
721
/*bool bsleep = true;
722
if(XPending(m_X11Display) > 0)
725
XPeekEvent(m_X11Display, &xevent);
726
if(xevent.type == MotionNotify)
728
//nuxDebugMsg(TEXT("[GLWindowImpl::SwapBuffer]: MotionNotify event."));
733
if (IsPauseThreadGraphicsRendering() )
738
glXSwapBuffers (m_X11Display, m_X11Window);
741
m_FrameTime = m_Timer.PassedMilliseconds();
743
// if(16.6f - m_FrameTime > 0)
745
// SleepForMilliseconds(16.6f - m_FrameTime);
746
// m_FrameTime = m_Timer.PassedMilliseconds();
750
// m_PeriodeTime += m_FrameTime;
753
// m_FramePeriodeCounter++;
754
// if(m_FramePeriodeCounter >= FRAME_RATE_PERIODE)
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;
762
//---------------------------------------------------------------------------------------------------------
763
void GLWindowImpl::DestroyOpenGLWindow()
765
if (m_GfxInterfaceCreated == true)
769
if (!glXMakeCurrent (m_X11Display, None, NULL) )
771
nuxAssert (TEXT ("[GLWindowImpl::DestroyOpenGLWindow] glXMakeCurrent failed.") );
774
glXDestroyContext (m_X11Display, m_GLCtx);
778
/* switch back to original desktop resolution if we were in fs */
781
XF86VidModeSwitchToMode (m_X11Display, m_X11Screen, &m_X11OriginalVideoMode);
782
XF86VidModeSetViewPort (m_X11Display, m_X11Screen, 0, 0);
785
XCloseDisplay (m_X11Display);
788
m_GfxInterfaceCreated = false;
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*/},
838
// //---------------------------------------------------------------------------------------------------------
839
// static int ms2fltk(int vk, int extended)
841
// static unsigned short vklut[256];
842
// static unsigned short extendedlut[256];
847
// for (i = 0; i < 256; i++)
849
// vklut[i] = i; //tolower(i);
851
// // for (i=VK_F1; i<=VK_F16; i++)
853
// // vklut[i] = i+(FL_F-(VK_F1-1)); // (FL_F + 1 -> VK_F1) ... (FL_F + 16 -> VK_F16)
855
// // for (i=VK_NUMPAD0; i<=VK_NUMPAD9; i++)
857
// // vklut[i] = i+(FL_KP+'0'-VK_NUMPAD0); // (FL_KP + '0' -> VK_NUMPAD0) ... (FL_KP + '9' = VK_NUMPAD9)
859
// for (i = 0; i < sizeof(vktab)/sizeof(*vktab); i++)
861
// vklut[vktab[i].vk] = vktab[i].fltk;
862
// extendedlut[vktab[i].vk] = vktab[i].extended;
864
// for (i = 0; i < 256; i++)
866
// if (!extendedlut[i])
867
// extendedlut[i] = vklut[i];
871
// return extended ? extendedlut[vk] : vklut[vk];
873
//---------------------------------------------------------------------------------------------------------
874
static int mouse_move (XEvent xevent, IEvent *m_pEvent)
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;
881
// Erase mouse event and mouse doubleclick events. Keep the mouse states.
882
t_uint32 _mouse_state = m_pEvent->e_mouse_state & 0x0F000000;
884
m_pEvent->e_event = NUX_MOUSE_MOVE;
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;
890
m_pEvent->e_mouse_state = _mouse_state;
895
static int mouse_press (XEvent xevent, IEvent *m_pEvent)
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;
902
// Erase mouse event and mouse double-click events. Keep the mouse states.
903
ulong _mouse_state = m_pEvent->e_mouse_state & 0x0F000000;
905
m_pEvent->e_event = NUX_MOUSE_PRESSED;
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;
912
if (xevent.xbutton.type == ButtonPress)
914
if (xevent.xbutton.button == Button1)
916
_mouse_state |= NUX_EVENT_BUTTON1_DOWN;
917
_mouse_state |= NUX_STATE_BUTTON1_DOWN;
920
if (xevent.xbutton.button == Button2)
922
_mouse_state |= NUX_EVENT_BUTTON2_DOWN;
923
_mouse_state |= NUX_STATE_BUTTON2_DOWN;
926
if (xevent.xbutton.button == Button3)
928
_mouse_state |= NUX_EVENT_BUTTON3_DOWN;
929
_mouse_state |= NUX_STATE_BUTTON3_DOWN;
932
if (xevent.xbutton.button == Button4)
934
_mouse_state |= NUX_EVENT_MOUSEWHEEL;
935
m_pEvent->e_event = NUX_MOUSEWHEEL;
936
m_pEvent->e_wheeldelta = -NUX_MOUSEWHEEL_DELTA;
940
if (xevent.xbutton.button == Button5)
942
_mouse_state |= NUX_EVENT_MOUSEWHEEL;
943
m_pEvent->e_event = NUX_MOUSEWHEEL;
944
m_pEvent->e_wheeldelta = +NUX_MOUSEWHEEL_DELTA;
950
m_pEvent->e_mouse_state = _mouse_state;
955
static int mouse_release (XEvent xevent, IEvent *m_pEvent)
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;
962
// Erase mouse event and mouse double-click events. Keep the mouse states.
963
ulong _mouse_state = m_pEvent->e_mouse_state & 0x0F000000;
965
m_pEvent->e_event = NUX_MOUSE_RELEASED;
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;
972
if (xevent.xbutton.type == ButtonRelease)
974
if (xevent.xbutton.button == Button1)
976
_mouse_state |= NUX_EVENT_BUTTON1_UP;
977
_mouse_state &= ~NUX_STATE_BUTTON1_DOWN;
980
if (xevent.xbutton.button == Button2)
982
_mouse_state |= NUX_EVENT_BUTTON2_UP;
983
_mouse_state &= ~NUX_STATE_BUTTON2_DOWN;
986
if (xevent.xbutton.button == Button3)
988
_mouse_state |= NUX_EVENT_BUTTON3_UP;
989
_mouse_state &= ~NUX_STATE_BUTTON3_DOWN;
993
m_pEvent->e_mouse_state = _mouse_state;
998
unsigned int GetModifierKeyState (unsigned int modifier_key_state)
1000
unsigned int state = 0;
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;
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;
1012
// if (modifier_key_state & 0x8000)
1013
// state |= NUX_STATE_SCROLLLOCK;
1015
if (modifier_key_state & ControlMask)
1016
state |= NUX_STATE_CTRL;
1018
if (modifier_key_state & ShiftMask)
1019
state |= NUX_STATE_SHIFT;
1021
if (modifier_key_state & Mod1Mask)
1022
state |= NUX_STATE_ALT;
1027
void GLWindowImpl::GetSystemEvent (IEvent *evt)
1030
// Erase mouse event and mouse doubleclick states. Keep the mouse states.
1031
m_pEvent->e_mouse_state &= 0x0F000000;
1032
bool bProcessEvent = true;
1034
// Process event matching this window
1037
if (XPending (m_X11Display))
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) )
1044
if (xevent.xkey.keycode < 256)
1046
// Detect if a key is repeated
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
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.
1055
XQueryKeymap (m_X11Display, Keys);
1057
if (Keys[xevent.xkey.keycode >> 3] & (1 << (xevent.xkey.keycode % 8) ) )
1059
// KeyRelease event + KeyDown = discard repeated event
1060
if (xevent.type == KeyRelease)
1062
m_X11LastEvent = xevent;
1063
bProcessEvent = false;
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) )
1071
bProcessEvent = false;;
1077
if (xevent.type == MotionNotify)
1079
while (XCheckTypedEvent (m_X11Display, MotionNotify, &xevent) );
1082
/*if(previous_event_motion == true)
1084
if(xevent.type == MotionNotify)
1087
if((motion_x == xevent.xmotion.x) && (motion_y == xevent.xmotion.y))
1089
//printf("skipmotion\n");
1090
bProcessEvent = false;
1094
motion_x = xevent.xmotion.x;
1095
motion_y = xevent.xmotion.y;
1100
previous_event_motion = false;
1103
else if(xevent.type == MotionNotify)
1105
//printf("motion\n");
1106
previous_event_motion = true;
1107
motion_x = xevent.xmotion.x;
1108
motion_y = xevent.xmotion.y;
1112
ProcessXEvent (xevent, false);
1114
memcpy (evt, m_pEvent, sizeof (IEvent) );
1119
memcpy (evt, m_pEvent, sizeof (IEvent) );
1123
void GLWindowImpl::ProcessForeignX11Event (XEvent *xevent, IEvent *nux_event)
1126
// Erase mouse event and mouse doubleclick states. Keep the mouse states.
1127
m_pEvent->e_mouse_state &= 0x0F000000;
1128
bool bProcessEvent = true;
1130
// Process event matching this window
1131
if (true /*(NUX_REINTERPRET_CAST(XAnyEvent*, xevent))->window == m_X11Window*/)
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) )
1137
if (xevent->xkey.keycode < 256)
1139
// Detect if a key is repeated
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
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.
1148
XQueryKeymap (m_X11Display, Keys);
1150
if (Keys[xevent->xkey.keycode >> 3] & (1 << (xevent->xkey.keycode % 8) ) )
1152
// KeyRelease event + KeyDown = discard repeated event
1153
if (xevent->type == KeyRelease)
1155
m_X11LastEvent = *xevent;
1156
bProcessEvent = false;
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) )
1164
bProcessEvent = false;;
1170
if (xevent->type == MotionNotify)
1172
while (XCheckTypedEvent (m_X11Display, MotionNotify, xevent) );
1176
ProcessXEvent (*xevent, true);
1178
memcpy (nux_event, m_pEvent, sizeof (IEvent) );
1182
memcpy (nux_event, m_pEvent, sizeof (IEvent) );
1186
IEvent &GLWindowImpl::GetCurrentEvent()
1191
bool GLWindowImpl::HasXPendingEvent() const
1193
return XPending (m_X11Display) ? true : false;
1196
void GLWindowImpl::RecalcXYPosition (Window TheMainWindow, XEvent xevent, int &x_recalc, int &y_recalc)
1198
int main_window_x = m_WindowPosition.x;
1199
int main_window_y = m_WindowPosition.y;
1200
bool same = (TheMainWindow == xevent.xany.window);
1202
switch (xevent.type)
1209
x_recalc = xevent.xbutton.x;
1210
y_recalc = xevent.xbutton.y;
1214
x_recalc = xevent.xbutton.x_root - main_window_x;
1215
y_recalc = xevent.xbutton.y_root - main_window_y;
1224
x_recalc = xevent.xmotion.x;
1225
y_recalc = xevent.xmotion.y;
1229
x_recalc = xevent.xmotion.x_root - main_window_x;
1230
y_recalc = xevent.xmotion.y_root - main_window_y;
1240
x_recalc = xevent.xcrossing.x;
1241
y_recalc = xevent.xcrossing.y;
1245
x_recalc = xevent.xcrossing.x_root - main_window_x;
1246
y_recalc = xevent.xcrossing.y_root - main_window_y;
1253
x_recalc = y_recalc = 0;
1258
void GLWindowImpl::ProcessXEvent (XEvent xevent, bool foreign)
1263
RecalcXYPosition (m_X11Window, xevent, x_recalc, y_recalc);
1265
foreign = foreign || xevent.xany.window != m_X11Window;
1267
m_pEvent->e_event = NUX_NO_EVENT;
1269
switch (xevent.type)
1276
m_pEvent->e_event = NUX_DESTROY_WINDOW;
1277
//nuxDebugMsg(TEXT("[GLWindowImpl::ProcessXEvents]: DestroyNotify event."));
1286
m_pEvent->e_event = NUX_WINDOW_DIRTY;
1287
//nuxDebugMsg(TEXT("[GLWindowImpl::ProcessXEvents]: Expose event."));
1292
case ConfigureNotify:
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);
1304
//nuxDebugMsg(TEXT("[GLWindowImpl::ProcessXEvents]: ConfigureNotify event."));
1313
m_pEvent->e_event = NUX_WINDOW_ENTER_FOCUS;
1314
m_pEvent->e_mouse_state = 0;
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;
1323
m_pEvent->virtual_code = 0;
1324
//nuxDebugMsg(TEXT("[GLWindowImpl::ProcessXEvents]: FocusIn event."));
1333
m_pEvent->e_event = NUX_WINDOW_EXIT_FOCUS;
1334
m_pEvent->e_mouse_state = 0;
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;
1341
m_pEvent->virtual_code = 0;
1342
//nuxDebugMsg(TEXT("[GLWindowImpl::ProcessXEvents]: FocusOut event."));
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;
1355
m_pEvent->e_key_modifiers = GetModifierKeyState (xevent.xkey.state);
1357
m_pEvent->e_key_repeat_count = 0;
1358
m_pEvent->e_keysym = inlKeysym;
1359
m_pEvent->e_event = NUX_KEYDOWN;
1361
static XComposeStatus ComposeStatus;
1362
static char buffer[16];
1363
m_pEvent->e_text[0] = 0;
1365
//nuxDebugMsg(TEXT("[GLWindowImpl::ProcessXEvents]: Keysym: %d - %x."), keysym, keysym);
1366
if (XLookupString (&xevent.xkey, buffer, sizeof (buffer), NULL, &ComposeStatus) )
1368
m_pEvent->e_text[0] = buffer[0];
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;
1383
m_pEvent->e_key_modifiers = GetModifierKeyState (xevent.xkey.state);
1385
m_pEvent->e_key_repeat_count = 0;
1386
m_pEvent->e_keysym = inlKeysym;
1387
m_pEvent->e_event = NUX_KEYUP;
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."));
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."));
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."));
1424
// Note: there is no WM_MOUSEENTER. WM_MOUSEENTER is equivalent to WM_MOUSEMOVE after a WM_MOUSELEAVE.
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."));
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."));
1448
if ( (xevent.xclient.format == 32) && ( (xevent.xclient.data.l[0]) == static_cast<long> (m_WMDeleteWindow) ) )
1450
m_pEvent->e_event = NUX_TERMINATE_APP;
1451
//nuxDebugMsg(TEXT("[GLWindowImpl::ProcessXEvents]: ClientMessage event: Close Application."));
1459
int GLWindowImpl::X11KeySymToINL (int Keysym)
1464
return NUX_VK_CANCEL;
1466
return NUX_VK_BACKSPACE;
1470
return NUX_VK_CLEAR;
1472
return NUX_VK_ENTER;
1474
return NUX_VK_SHIFT;
1476
return NUX_VK_CONTROL;
1480
return NUX_VK_PAUSE;
1482
return NUX_VK_CAPITAL;
1484
return NUX_VK_ESCAPE;
1486
return NUX_VK_SPACE;
1488
return NUX_VK_PAGE_UP;
1490
return NUX_VK_PAGE_DOWN;
1500
return NUX_VK_RIGHT;
1504
return NUX_VK_SELECT;
1506
return NUX_VK_PRINT;
1508
return NUX_VK_EXECUTE;
1510
return NUX_VK_INSERT;
1512
return NUX_VK_DELETE;
1592
return NUX_VK_NUMPAD0;
1594
return NUX_VK_NUMPAD1;
1596
return NUX_VK_NUMPAD2;
1598
return NUX_VK_NUMPAD3;
1600
return NUX_VK_NUMPAD4;
1602
return NUX_VK_NUMPAD5;
1604
return NUX_VK_NUMPAD6;
1606
return NUX_VK_NUMPAD7;
1608
return NUX_VK_NUMPAD8;
1610
return NUX_VK_NUMPAD9;
1611
case XK_KP_Multiply:
1612
return NUX_VK_MULTIPLY;
1615
case XK_KP_Separator:
1616
return NUX_VK_SEPARATOR;
1617
case XK_KP_Subtract:
1618
return NUX_VK_SUBTRACT;
1620
return NUX_VK_DECIMAL;
1622
return NUX_VK_DIVIDE;
1672
return NUX_VK_NUMLOCK;
1673
case XK_Scroll_Lock:
1674
return NUX_VK_SCROLL;
1676
return NUX_VK_RSHIFT;
1678
return NUX_VK_RCONTROL;
1680
return NUX_VK_RMENU;
1686
//---------------------------------------------------------------------------------------------------------
1687
void GLWindowImpl::ShowWindow()
1690
::ShowWindow (hWnd, SW_RESTORE);
1694
//---------------------------------------------------------------------------------------------------------
1695
void GLWindowImpl::HideWindow()
1698
::ShowWindow (hWnd, SW_MINIMIZE);
1702
//---------------------------------------------------------------------------------------------------------
1703
void GLWindowImpl::EnterMaximizeWindow()
1706
::ShowWindow (hWnd, SW_MAXIMIZE);
1710
//---------------------------------------------------------------------------------------------------------
1711
void GLWindowImpl::ExitMaximizeWindow()
1714
::ShowWindow (hWnd, SW_RESTORE);
1718
//---------------------------------------------------------------------------------------------------------
1719
void GLWindowImpl::SetWindowTitle (const TCHAR *Title)
1722
SetWindowText (hWnd, Title);
1726
//---------------------------------------------------------------------------------------------------------
1727
bool GLWindowImpl::HasVSyncSwapControl() const
1729
return GetThreadGLDeviceFactory()->SUPPORT_WGL_EXT_SWAP_CONTROL();
1732
//---------------------------------------------------------------------------------------------------------
1733
void GLWindowImpl::EnableVSyncSwapControl()
1737
if (HasVSyncSwapControl() )
1739
wglSwapIntervalEXT (1);
1745
//---------------------------------------------------------------------------------------------------------
1746
void GLWindowImpl::DisableVSyncSwapControl()
1750
if (HasVSyncSwapControl() )
1752
wglSwapIntervalEXT (0);
1758
float GLWindowImpl::GetFrameTime() const
1763
void GLWindowImpl::ResetFrameTime()
1769
//---------------------------------------------------------------------------------------------------------
1770
bool GLWindowImpl::StartOpenFileDialog(FileDialogOption& fdo)
1772
return Win32OpenFileDialog(GetWindowHandle(), fdo);
1775
//---------------------------------------------------------------------------------------------------------
1776
bool GLWindowImpl::StartSaveFileDialog(FileDialogOption& fdo)
1778
return Win32SaveFileDialog(GetWindowHandle(), fdo);
1781
//---------------------------------------------------------------------------------------------------------
1782
bool GLWindowImpl::StartColorDialog(ColorDialogOption& cdo)
1784
return Win32ColorDialog(GetWindowHandle(), cdo);
1787
//---------------------------------------------------------------------------------------------------------
1788
/*void GLWindowImpl::SetWindowCursor(HCURSOR cursor)
1793
//---------------------------------------------------------------------------------------------------------
1794
HCURSOR GLWindowImpl::GetWindowCursor() const
1799
//---------------------------------------------------------------------------------------------------------
1800
void GLWindowImpl::PauseThreadGraphicsRendering()
1802
m_PauseGraphicsRendering = true;
1803
MakeGLContextCurrent();
1806
//---------------------------------------------------------------------------------------------------------
1807
bool GLWindowImpl::IsPauseThreadGraphicsRendering() const
1809
return m_PauseGraphicsRendering;