nux-1.14.0
GraphicsDisplayWin.cpp
00001 /*
00002  * Copyright 2010 Inalogic® Inc.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser General Public License, as
00006  * published by the  Free Software Foundation; either version 2.1 or 3.0
00007  * of the License.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranties of
00011  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00012  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00013  * License for more details.
00014  *
00015  * You should have received a copy of both the GNU Lesser General Public
00016  * License along with this program. If not, see <http://www.gnu.org/licenses/>
00017  *
00018  * Authored by: Jay Taoko <jaytaoko@inalogic.com>
00019  *
00020  */
00021 
00022 
00023 #include "GLResource.h"
00024 #include "NuxGraphics.h"
00025 #include "GpuDevice.h"
00026 #include "GLDeviceObjects.h"
00027 #include "GLResourceManager.h"
00028 
00029 #include "GLTextureResourceManager.h"
00030 #include "GLVertexResourceManager.h"
00031 #include "GraphicsEngine.h"
00032 #include "GLWindowManager.h"
00033 #include "Events.h"
00034 #include "IniFile.h"
00035 
00036 #include "GraphicsDisplay.h"
00037 
00038 namespace nux
00039 {
00040 
00041   // Compute the frame rate every FRAME_RATE_PERIODE;
00042   #define FRAME_RATE_PERIODE    10
00043 
00044   void ClipOrCenterRectToMonitor (LPRECT prc, t_u32 flags)
00045   {
00046     HMONITOR hMonitor;
00047     MONITORINFO mi;
00048     RECT        rc;
00049     int         w = prc->right  - prc->left;
00050     int         h = prc->bottom - prc->top;
00051 
00052     //
00053     // get the nearest monitor to the passed rect.
00054     //
00055     hMonitor = MonitorFromRect (prc, MONITOR_DEFAULTTONEAREST);
00056 
00057     //
00058     // get the work area or entire monitor rect.
00059     //
00060     mi.cbSize = sizeof (mi);
00061     GetMonitorInfo (hMonitor, &mi);
00062 
00063     //if (flags & MONITOR_WORKAREA)
00064     rc = mi.rcWork;
00065 //    else
00066 //        rc = mi.rcMonitor;
00067 
00068     //
00069     // center or clip the passed rect to the monitor rect
00070     //
00071     //if (flags & MONITOR_CENTER)
00072     {
00073       prc->left   = rc.left + (rc.right  - rc.left - w) / 2;
00074       prc->top    = rc.top  + (rc.bottom - rc.top  - h) / 2;
00075       prc->right  = prc->left + w;
00076       prc->bottom = prc->top  + h;
00077     }
00078 //    else
00079 //    {
00080 //        prc->left   = Max(rc.left, Min(rc.right-w,  prc->left));
00081 //        prc->top    = Max(rc.top,  Min(rc.bottom-h, prc->top));
00082 //        prc->right  = prc->left + w;
00083 //        prc->bottom = prc->top  + h;
00084 //    }
00085   }
00086 
00087   EventToNameStruct EventToName[] =
00088   {
00089     {NUX_NO_EVENT,               TEXT ("NUX_NO_EVENT") },
00090     {NUX_MOUSE_PRESSED,          TEXT ("NUX_MOUSE_PRESSED") },
00091     {NUX_MOUSE_RELEASED,         TEXT ("NUX_MOUSE_RELEASED") },
00092     {NUX_KEYDOWN,                TEXT ("NUX_KEYDOWN") },
00093     {NUX_KEYUP,                  TEXT ("NUX_KEYUP") },
00094     {NUX_MOUSE_MOVE,             TEXT ("NUX_MOUSE_MOVE") },
00095     {NUX_SIZE_CONFIGURATION,     TEXT ("NUX_SIZE_CONFIGURATION") },
00096     {NUX_WINDOW_CONFIGURATION,   TEXT ("NUX_WINDOW_CONFIGURATION") },
00097     {NUX_WINDOW_ENTER_FOCUS,     TEXT ("NUX_WINDOW_ENTER_FOCUS") },
00098     {NUX_WINDOW_EXIT_FOCUS,      TEXT ("NUX_WINDOW_EXIT_FOCUS") },
00099     {NUX_WINDOW_DIRTY,           TEXT ("NUX_WINDOW_DIRTY") },
00100     {NUX_WINDOW_MOUSELEAVE,      TEXT ("NUX_WINDOW_MOUSELEAVE") },
00101     {NUX_TERMINATE_APP,          TEXT ("NUX_TERMINATE_APP") }
00102   };
00103 
00104 //---------------------------------------------------------------------------------------------------------
00105   HGLRC GraphicsDisplay::sMainGLRC = 0;
00106   HDC   GraphicsDisplay::sMainDC = 0;
00107 
00108   GraphicsDisplay::GraphicsDisplay()
00109     :   event_ (NULL)
00110     ,   m_GfxInterfaceCreated (false)
00111     ,   m_fullscreen (false)
00112     ,   m_ScreenBitDepth (32)
00113     ,   m_num_device_modes (0)
00114     ,   m_index_of_current_mode (-1)
00115     ,   m_DeviceFactory (0)
00116     ,   m_GraphicsContext (0)
00117 // ,   m_GLEWContext(0)
00118 // ,   m_WGLEWContext(0)
00119     ,   m_Style (WINDOWSTYLE_NORMAL)
00120     ,   m_Cursor (0)
00121     ,   m_PauseGraphicsRendering (false)
00122     ,   m_ParentWindow (0)
00123     ,   m_dwExStyle (0)
00124     ,   m_dwStyle (0)
00125   {
00126     inlSetThreadLocalStorage (_TLS_GraphicsDisplay, this);
00127 
00128     m_GfxInterfaceCreated = false;
00129     event_ = new Event();
00130     GetDisplayInfo();
00131 
00132     m_WindowSize.width = 0;
00133     m_WindowSize.height = 0;
00134 
00135     // A window never starts in a minimized state.
00136     m_is_window_minimized = false;
00137 
00138     //_dnd_source_grab_active = false;
00139     _global_keyboard_grab_data = 0;
00140     _global_pointer_grab_data = 0;
00141 
00142   }
00143 
00144 //---------------------------------------------------------------------------------------------------------
00145   GraphicsDisplay::~GraphicsDisplay()
00146   {
00147     NUX_SAFE_DELETE ( m_GraphicsContext );
00148     NUX_SAFE_DELETE ( m_DeviceFactory );
00149 
00150 //     NUX_SAFE_DELETE( m_WGLEWContext );
00151 //     NUX_SAFE_DELETE( m_GLEWContext );
00152 
00153     DestroyOpenGLWindow();
00154     NUX_SAFE_DELETE ( event_ );
00155 
00156     inlSetThreadLocalStorage (_TLS_GraphicsDisplay, 0);
00157   }
00158 
00159 //---------------------------------------------------------------------------------------------------------
00160   bool GraphicsDisplay::IsGfxInterfaceCreated()
00161   {
00162     return m_GfxInterfaceCreated;
00163   }
00164 
00165 //---------------------------------------------------------------------------------------------------------
00166   static NCriticalSection CreateOpenGLWindow_CriticalSection;
00167   bool GraphicsDisplay::CreateOpenGLWindow(const TCHAR *WindowTitle,
00168                                          unsigned int WindowWidth,
00169                                          unsigned int WindowHeight,
00170                                          WindowStyle Style,
00171                                          const GraphicsDisplay *Parent,
00172                                          bool FullscreenFlag,
00173                                          bool create_rendering_data)
00174   {
00175     NScopeLock Scope (&CreateOpenGLWindow_CriticalSection);
00176 
00177     RECT                WindowRect;                             // Grabs Rectangle Upper Left / Lower Right Values
00178 
00179     m_GfxInterfaceCreated = false;
00180 
00181     // FIXME : put at the end
00182     m_ViewportSize.width = WindowWidth;
00183     m_ViewportSize.height = WindowHeight;
00184     m_WindowSize.width = WindowWidth;
00185     m_WindowSize.height = WindowHeight;
00186 
00187     // end of fixme
00188 
00189     WindowRect.left     = (long) 0;
00190     WindowRect.right    = (long) m_ViewportSize.width;
00191     WindowRect.top      = (long) 0;
00192     WindowRect.bottom   = (long) m_ViewportSize.height;
00193 
00194     m_fullscreen = FullscreenFlag;                                                              // Set The Global Fullscreen Flag
00195     m_index_of_current_mode = -1;                                                               // assume -1 if the mode is not fullscreen
00196 
00197 
00198     if (m_fullscreen)                                                                           // Attempt Fullscreen Mode?
00199     {
00200       // check if resolution is supported
00201       bool mode_supported = false;
00202 
00203       for (int num_modes = 0 ; num_modes < m_num_gfx_device_modes; num_modes++)
00204       {
00205         if ((m_gfx_device_modes[num_modes].width == m_ViewportSize.width)
00206              && (m_gfx_device_modes[num_modes].height == m_ViewportSize.height)
00207              && (m_gfx_device_modes[num_modes].format == m_ScreenBitDepth))
00208         {
00209           mode_supported = true;
00210           m_index_of_current_mode = num_modes;
00211           break;
00212         }
00213       }
00214 
00215       if (mode_supported == false)
00216       {
00217         if (inlWin32MessageBox (NULL, TEXT ("Info"), MBTYPE_Ok, MBICON_Information, MBMODAL_ApplicationModal,
00218                                 TEXT ("The requested fullscreen mode is not supported by your monitor.\nUsing windowed mode instead.") ) == MBRES_Yes)
00219         {
00220           m_fullscreen = FALSE;         // Windowed Mode Selected.  Fullscreen = FALSE
00221         }
00222       }
00223 
00224       DEVMODE dmScreenSettings;                                               // Device Mode
00225       memset (&dmScreenSettings, 0, sizeof (dmScreenSettings));               // Makes Sure Memory's Cleared
00226       dmScreenSettings.dmSize = sizeof (dmScreenSettings);                    // Size Of The Devmode Structure
00227       dmScreenSettings.dmPelsWidth      = m_ViewportSize.width;                   // Selected Screen Width
00228       dmScreenSettings.dmPelsHeight     = m_ViewportSize.height;                  // Selected Screen Height
00229       dmScreenSettings.dmBitsPerPel     = m_ScreenBitDepth;                              // Selected Bits Per Pixel
00230       dmScreenSettings.dmDisplayFrequency = 60;
00231       dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
00232 
00233       // Try To Set Selected Mode And Get Results.  NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
00234       if (ChangeDisplaySettings (&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
00235       {
00236         if (inlWin32MessageBox (NULL, TEXT ("Info"), MBTYPE_Ok, MBICON_Information, MBMODAL_ApplicationModal,
00237                                 TEXT ("The requested fullscreen mode is not supported by your monitor.\nUsing windowed mode instead.") ) == MBRES_Yes)
00238         {
00239           m_fullscreen = FALSE;                   // Windowed Mode Selected.  Fullscreen = FALSE
00240         }
00241         else
00242         {
00243           // Pop Up A Message Box Letting User Know The Program Is Closing.
00244           MessageBox (NULL, "Program Will Now Close.", "ERROR", MB_OK | MB_ICONSTOP);
00245         }
00246       }
00247     }
00248 
00249     m_dwExStyle = 0;
00250     m_dwStyle = 0;
00251 
00252     if (m_fullscreen)                                   // Are We Still In Fullscreen Mode?
00253     {
00254       m_dwExStyle = WS_EX_APPWINDOW;                    // Window Extended Style
00255       m_dwStyle = WS_POPUP;                             // Windows Style
00256       ShowCursor (FALSE);                              // Hide Mouse Pointer
00257     }
00258     else
00259     {
00260       // Window Extended Style
00261       m_dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
00262       // Windows Style
00263       m_dwStyle = WS_OVERLAPPED;    // Creates an overlapped window. An overlapped window has a title bar and a border
00264 
00265       // See Win32 Window Hierarchy and Styles: http://msdn.microsoft.com/en-us/library/ms997562.aspx
00266 
00267       //WS_EX_APPWINDOW       // Forces a top-level window onto the taskbar when the window is visible
00268       //WS_EX_WINDOWEDGE      // Specifies that a window has a border with a raised edge
00269 
00270       //WS_POPUP      // Creates a pop-up window. This style cannot be used with the WS_CHILD style.
00271       //WS_SYSMENU    // Creates a window that has a window menu on its title bar. The WS_CAPTION style must also be specified.
00272       //WS_SIZEBOX    // Creates a window that has a sizing border. Same as the WS_THICKFRAME style.
00273       //WS_CAPTION    // Creates a window that has a title bar (includes the WS_BORDER style).
00274 
00275       m_Style = Style;
00276 
00277       if (Style == WINDOWSTYLE_TOOL)
00278       {
00279         m_dwExStyle = WS_EX_TOOLWINDOW;
00280         m_dwStyle = WS_CAPTION | WS_SYSMENU;
00281       }
00282       else if (Style == WINDOWSTYLE_DIALOG)
00283       {
00284         m_dwExStyle = WS_EX_DLGMODALFRAME;
00285         m_dwStyle = WS_CAPTION | WS_SYSMENU;
00286       }
00287       else if (Style == WINDOWSTYLE_NOBORDER)
00288       {
00289         m_dwExStyle = WS_EX_TOPMOST | WS_EX_TOOLWINDOW;
00290         m_dwStyle = WS_POPUP;
00291       }
00292       else if (Style == WINDOWSTYLE_PANEL)
00293       {
00294         m_dwExStyle = 0;           // Specifies that a window has a border with a raised edge
00295         m_dwStyle = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SIZEBOX;
00296       }
00297       else
00298       {
00299         // Normal Window: NormalWindow
00300         m_dwExStyle = WS_EX_APPWINDOW |   // Forces a top-level window onto the taskbar when the window is visible
00301                       WS_EX_WINDOWEDGE;   // Specifies that a window has a border with a raised edge
00302 
00303         m_dwStyle |= WS_CAPTION |         // Creates a window that has a title bar.
00304                      WS_SYSMENU |         // Creates a window that has a window menu on its title bar. The WS_CAPTION style must also be specified.
00305                      WS_THICKFRAME |      // Creates a window that has a sizing border.
00306                      WS_MINIMIZEBOX |     // Creates a window that has a minimize button.
00307                      WS_MAXIMIZEBOX |     // Creates a window that has a maximize button.
00308                      WS_BORDER;           // Creates a window that has a thin-line border.
00309       }
00310     }
00311     // The AdjustWindowRectEx function calculates the required size of the window rectangle,
00312     // based on the desired size of the client rectangle. The window rectangle can then be passed to
00313     // the CreateWindowEx function to create a window whose client area is the desired size.
00314     AdjustWindowRectEx (&WindowRect, m_dwStyle, FALSE, m_dwExStyle);    // Adjust Window To True Requested Size
00315 
00316     RECT rect;
00317     rect.top = 0;
00318     rect.bottom = WindowRect.bottom - WindowRect.top;
00319     rect.left = 0;
00320     rect.right = WindowRect.right - WindowRect.left;
00321     int WindowX = 0;
00322     int WindowY = 0;
00323 
00324     if (Parent)
00325     {
00326       m_ParentWindow = Parent->GetWindowHandle();
00327       GetWindowRect (m_ParentWindow, &rect);
00328 
00329       int width = rect.right - rect.left;
00330       int height = rect.bottom - rect.top;
00331 
00332       WindowX = rect.left + (width - (WindowRect.right - WindowRect.left) ) / 2;
00333       WindowY = rect.top + (height - (WindowRect.bottom - WindowRect.top) ) / 2;
00334     }
00335     else if (!m_fullscreen)
00336     {
00337       ClipOrCenterRectToMonitor (&rect, 0);
00338       WindowX = rect.left;
00339       WindowY = rect.top;
00340     }
00341 
00342     m_WindowTitle = WindowTitle;
00343 
00344     // Create The Window
00345     if (! (m_hWnd = ::CreateWindowEx (m_dwExStyle,                      // Extended Style For The Window
00346                                       WINDOW_CLASS_NAME,                  // Class Name
00347                                       m_WindowTitle.GetTCharPtr(),        // Window Title
00348                                       m_dwStyle |                           // Defined Window Style
00349                                       WS_CLIPSIBLINGS |                   // Required Window Style
00350                                       WS_CLIPCHILDREN,                    // Required Window Style
00351                                       WindowX, WindowY,                   // Window Position
00352                                       WindowRect.right - WindowRect.left, // Calculate Window Width
00353                                       WindowRect.bottom - WindowRect.top, // Calculate Window Height
00354                                       m_ParentWindow,                     // No Parent Window
00355                                       NULL,                               // No Menu
00356                                       gGLWindowManager.GetInstance(),     // Instance
00357                                       NULL) ) )                           // Dont Pass Anything To WM_CREATE
00358     {
00359       DestroyOpenGLWindow();
00360       MessageBox (NULL, TEXT ("Window Creation Error."), TEXT ("ERROR"), MB_OK | MB_ICONERROR);
00361                                                  // Return FALSE
00362     }
00363 
00364     static      PIXELFORMATDESCRIPTOR pfd =                             // pfd Tells Windows How We Want Things To Be
00365     {
00366       sizeof (PIXELFORMATDESCRIPTOR),                           // Size Of This Pixel Format Descriptor
00367       1,                                                                                        // Version Number
00368       PFD_DRAW_TO_WINDOW |                                              // Format Must Support Window
00369       PFD_SUPPORT_OPENGL |                                              // Format Must Support OpenGL
00370       PFD_DOUBLEBUFFER,                             // Must Support Double Buffering
00371       PFD_TYPE_RGBA,                                                            // Request An RGBA Format
00372       24,       //        cColorBits
00373       //        Specifies the number of color bitplanes in each color buffer.
00374       //        For RGBA pixel types, it is the size of the color buffer, excluding the alpha bitplanes.
00375       //        For color-index pixels, it is the size of the color-index buffer.
00376 
00377 
00378       0, //        cRedBits
00379       //        Specifies the number of red bitplanes in each RGBA color buffer.
00380       0, //        cRedShift
00381       //        Specifies the shift count for red bitplanes in each RGBA color buffer.
00382       0, //        cGreenBits
00383       //        Specifies the number of green bitplanes in each RGBA color buffer.
00384       0, //        cGreenShift
00385       //        Specifies the shift count for green bitplanes in each RGBA color buffer.
00386       0, //        cBlueBits
00387       //        Specifies the number of blue bitplanes in each RGBA color buffer.
00388       0, //        cBlueShift
00389       //        Specifies the shift count for blue bitplanes in each RGBA color buffer.
00390 
00391       0, //        cAlphaBits
00392       //        Specifies the number of alpha bitplanes in each RGBA color buffer. Alpha bitplanes are not supported.
00393       0, //        cAlphaShift
00394       //        Specifies the shift count for alpha bitplanes in each RGBA color buffer. Alpha bitplanes are not supported.
00395 
00396       0, //        cAccumBits
00397       //        Specifies the total number of bitplanes in the accumulation buffer.
00398       0, //        cAccumRedBits
00399       //        Specifies the number of red bitplanes in the accumulation buffer.
00400       0, //        cAccumGreenBits
00401       //        Specifies the number of green bitplanes in the accumulation buffer.
00402       0, //        cAccumBlueBits
00403       //        Specifies the number of blue bitplanes in the accumulation buffer.
00404       0, //        cAccumAlphaBits
00405       //        Specifies the number of alpha bitplanes in the accumulation buffer.
00406       24,//        cDepthBits
00407       //        Specifies the depth of the depth (z-axis) buffer.
00408       8, //        cStencilBits
00409       //        Specifies the depth of the stencil buffer.
00410       0, //        cAuxBuffers
00411       //        Specifies the number of auxiliary buffers. Auxiliary buffers are not supported.
00412       PFD_MAIN_PLANE,   //        iLayerType
00413       //        Ignored. Earlier implementations of OpenGL used this member, but it is no longer used.
00414       0, //        bReserved
00415       //        Specifies the number of overlay and underlay planes. Bits 0 through 3 specify up to 15 overlay planes and bits 4 through 7 specify up to 15 underlay planes.
00416       0, //        dwLayerMask
00417       //        Ignored. Earlier implementations of OpenGL used this member, but it is no longer used.
00418       0, //        dwVisibleMask
00419       //        Specifies the transparent color or index of an underlay plane. When the pixel type is RGBA, dwVisibleMask is a transparent RGB color value. When the pixel type is color index, it is a transparent index value.
00420       0, //        dwDamageMask
00421       //        Ignored. Earlier implementations of OpenGL used this member, but it is no longer used.
00422     };
00423 
00424     if (! (_device_context = GetDC (m_hWnd) ) ) // Did We Get A Device Context?
00425     {
00426       DestroyOpenGLWindow();
00427       MessageBox (NULL, TEXT ("Can't Create A GL Device Context."), TEXT ("ERROR"), MB_OK | MB_ICONERROR);
00428       return FALSE;
00429     }
00430 
00431     if (! (m_PixelFormat = ChoosePixelFormat (_device_context, &pfd) ) ) // Did Windows Find A Matching Pixel Format?
00432     {
00433       DestroyOpenGLWindow();
00434       MessageBox (NULL, TEXT ("Can't Find A Suitable PixelFormat."), TEXT ("ERROR"), MB_OK | MB_ICONERROR);
00435       return FALSE;
00436     }
00437 
00438     if (!SetPixelFormat (_device_context, m_PixelFormat, &pfd) )        // Are We Able To Set The Pixel Format?
00439     {
00440       DestroyOpenGLWindow();
00441       MessageBox (NULL, TEXT ("Can't Set The PixelFormat."), TEXT ("ERROR"), MB_OK | MB_ICONERROR);
00442       return FALSE;
00443     }
00444 
00445     if (! (_opengl_rendering_context = wglCreateContext (_device_context) ) )               // Are We Able To Get A Rendering Context?
00446     {
00447       DestroyOpenGLWindow();
00448       MessageBox (NULL, TEXT ("Can't Create A GL Rendering Context."), TEXT ("ERROR"), MB_OK | MB_ICONERROR);
00449       return FALSE;
00450     }
00451 
00452     if (sMainGLRC == 0)
00453     {
00454       sMainGLRC = _opengl_rendering_context;
00455       sMainDC = _device_context;
00456     }
00457     else
00458     {
00459 //         wglMakeCurrent(_device_context, 0);
00460 //         // Make the newly created context share it resources with all the other OpenGL context
00461 //         if(wglShareLists(sMainGLRC, _opengl_rendering_context) == FALSE)
00462 //         {
00463 //             DWORD err = GetLastError();
00464 //             DestroyOpenGLWindow();
00465 //             MessageBox(NULL, TEXT("Can't share GL context."), TEXT("ERROR"), MB_OK|MB_ICONERROR);
00466 //             return FALSE;
00467 //         }
00468     }
00469 
00470     // This creates a  warning. It is a 64-bits compatibility issue.
00471     // When not in 64-bit you can disable the warning:
00472     // Project Properties --> C/C++ tab --> General --> Select "NO" for - Detect 64-bit Portability Issues.
00473     // See also SetWindowLongPtr
00474     SetWindowLongPtr (m_hWnd, GWLP_USERDATA, (NUX_PTRSIZE_LONG) this);
00475 
00476     //::ShowWindow(m_hWnd,SW_SHOW);                                             // Show The Window
00477     ::SetForegroundWindow (m_hWnd);                                             // Slightly Higher Priority
00478     ::SetFocus (m_hWnd);                                                                        // Sets Keyboard Focus To The Window
00479 
00480     MakeGLContextCurrent();
00481     glClearColor (0.0, 0.0, 0.0, 0.0);
00482     glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
00483     SwapBuffer();
00484 
00485     m_GfxInterfaceCreated = true;
00486 
00487     //m_GLEWContext = new GLEWContext();
00488     //m_WGLEWContext = new WGLEWContext();
00489 
00490     HGLRC new_opengl_rendering_context = _opengl_rendering_context;
00491     m_DeviceFactory = new GpuDevice (m_ViewportSize.width, m_ViewportSize.height, BITFMT_R8G8B8A8,
00492       _device_context,
00493       new_opengl_rendering_context,
00494       1, 0, false);
00495 
00496     if (new_opengl_rendering_context != 0)
00497     {
00498       _opengl_rendering_context = new_opengl_rendering_context;
00499     }
00500 
00501     m_GraphicsContext = new GraphicsEngine (*this, create_rendering_data);
00502 
00503     //EnableVSyncSwapControl();
00504     //DisableVSyncSwapControl();
00505 
00506     InitGlobalGrabWindow ();
00507 
00508     return true;
00509   }
00510 
00511   bool GraphicsDisplay::CreateFromOpenGLWindow (HWND WindowHandle, HDC WindowDCHandle, HGLRC OpenGLRenderingContext)
00512   {
00513     // Do not make the opengl context current
00514     // Do not swap the framebuffer
00515     // Do not clear the depth or color buffer
00516     // Do not enable/disable VSync
00517 
00518     m_hWnd = WindowHandle;
00519     _device_context = WindowDCHandle;
00520     _opengl_rendering_context = OpenGLRenderingContext;
00521 
00522     RECT rect;
00523     ::GetClientRect (m_hWnd, &rect);
00524     m_WindowSize = Size (rect.right - rect.left, rect.bottom - rect.top);
00525     m_ViewportSize = Size (rect.right - rect.left, rect.bottom - rect.top);
00526 
00527     // The opengl context should be made current by an external entity.
00528 
00529     m_GfxInterfaceCreated = true;
00530     m_DeviceFactory = new GpuDevice (m_ViewportSize.width, m_ViewportSize.height, BITFMT_R8G8B8A8,
00531       _device_context,
00532       _opengl_rendering_context);
00533 
00534     m_GraphicsContext = new GraphicsEngine (*this);
00535 
00536     InitGlobalGrabWindow ();
00537 
00538     return true;
00539   }
00540 
00541   GraphicsEngine* GraphicsDisplay::GetGraphicsEngine() const
00542   {
00543     return m_GraphicsContext;
00544   }
00545   
00546   GpuDevice* GraphicsDisplay::GetGpuDevice () const
00547   {
00548     return m_DeviceFactory;
00549   }
00550 
00551 //---------------------------------------------------------------------------------------------------------
00552   // NUXTODO: remove this call. Make a direct access to GpuInfo via GpuDevice.
00553   bool GraphicsDisplay::HasFrameBufferSupport()
00554   {
00555     return m_DeviceFactory->GetGpuInfo ().Support_EXT_Framebuffer_Object ();
00556   }
00557 
00558 //---------------------------------------------------------------------------------------------------------
00559   void GraphicsDisplay::GetWindowSize (int &w, int &h)
00560   {
00561     w = m_WindowSize.width;
00562     h = m_WindowSize.height;
00563   }
00564 
00565 //---------------------------------------------------------------------------------------------------------
00566   int GraphicsDisplay::GetWindowWidth ()
00567   {
00568     return m_WindowSize.width;
00569   }
00570 
00571 //---------------------------------------------------------------------------------------------------------
00572   int GraphicsDisplay::GetWindowHeight ()
00573   {
00574     return m_WindowSize.height;
00575   }
00576 
00577   void GraphicsDisplay::ResetWindowSize ()
00578   {
00579     RECT rect;
00580     ::GetClientRect (m_hWnd, &rect);
00581     m_WindowSize = Size (rect.right - rect.left, rect.bottom - rect.top);
00582     m_ViewportSize = Size (rect.right - rect.left, rect.bottom - rect.top);
00583   }
00584 
00585 //---------------------------------------------------------------------------------------------------------
00586   void GraphicsDisplay::SetWindowSize (int width, int height)
00587   {
00588     RECT window_rect;
00589     RECT new_rect;
00590     ::GetWindowRect (m_hWnd, &window_rect);
00591 
00592     new_rect.left = 0;
00593     new_rect.right = width;
00594     new_rect.top = 0;
00595     new_rect.bottom = height;
00596     BOOL b = ::AdjustWindowRectEx (&new_rect, m_dwStyle, FALSE, m_dwExStyle);    // Adjust Window To True Requested Size
00597 
00598     ::MoveWindow (m_hWnd,
00599                   window_rect.left,
00600                   window_rect.top,
00601                   (new_rect.right - new_rect.left),
00602                   (new_rect.bottom - new_rect.top),
00603                   TRUE);
00604   }
00605 
00606 //---------------------------------------------------------------------------------------------------------
00607   void GraphicsDisplay::SetViewPort (int x, int y, int width, int height)
00608   {
00609     if (IsGfxInterfaceCreated ())
00610     {
00611       //do not rely on m_ViewportSize: glViewport can be called directly
00612       m_ViewportSize.width = width;
00613       m_ViewportSize.height = height;
00614 
00615       m_GraphicsContext->SetViewport (x, y, m_ViewportSize.width, m_ViewportSize.height);
00616       m_GraphicsContext->SetScissor (0, 0, width, height);
00617     }
00618   }
00619 
00620   Point GraphicsDisplay::GetMouseScreenCoord ()
00621   {
00622     POINT pt;
00623     ::GetCursorPos (&pt);
00624     ScreenToClient (m_hWnd, &pt);
00625     Point point (pt.x, pt.y);
00626     return point;
00627   }
00628 
00629   Point GraphicsDisplay::GetMouseWindowCoord ()
00630   {
00631     POINT pt;
00632     ::GetCursorPos (&pt);
00633     ::ScreenToClient (m_hWnd, &pt);
00634     Point point (pt.x, pt.y);
00635     return point;
00636   }
00637 
00638   Point GraphicsDisplay::GetWindowCoord ()
00639   {
00640     RECT rect;
00641     ::GetWindowRect (m_hWnd, &rect);
00642     Point point (rect.left, rect.top);
00643     return point;
00644   }
00645 
00646   Rect GraphicsDisplay::GetWindowGeometry ()
00647   {
00648     RECT rect;
00649     ::GetClientRect (m_hWnd, &rect);
00650     Rect geo (rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
00651     return geo;
00652   }
00653 
00654   Rect GraphicsDisplay::GetNCWindowGeometry ()
00655   {
00656     RECT rect;
00657     ::GetWindowRect (m_hWnd, &rect);
00658     Rect geo (rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
00659     return geo;
00660   }
00661 
00662   void GraphicsDisplay::MakeGLContextCurrent (bool b)
00663   {
00664     HGLRC glrc = _opengl_rendering_context;
00665 
00666     if (b == false)
00667     {
00668       glrc = 0;
00669     }
00670 
00671     if (!wglMakeCurrent (_device_context, glrc) )
00672     {
00673       NString error = inlGetSystemErrorMessage();
00674       DestroyOpenGLWindow();
00675       MessageBox (NULL, TEXT ("Can't Activate The GL Rendering Context."), TEXT ("ERROR"), MB_OK | MB_ICONERROR);
00676     }
00677   }
00678 
00679   void GraphicsDisplay::SwapBuffer (bool glswap)
00680   {
00681     if (IsPauseThreadGraphicsRendering() )
00682       return;
00683 
00684     if (glswap)
00685     {
00686       SwapBuffers (_device_context);
00687     }
00688 
00689     m_FrameTime = m_Timer.PassedMilliseconds();
00690 
00691 //     if(16.6f - m_FrameTime > 0)
00692 //     {
00693 //         SleepForMilliseconds(16.6f - m_FrameTime);
00694 //     }
00695 //
00696 //     m_FrameTime = m_Timer.PassedMilliseconds();
00697 //     m_Timer.Reset();
00698 //     m_PeriodeTime += m_FrameTime;
00699 //
00700 //     m_FrameCounter++;
00701 //     m_FramePeriodeCounter++;
00702 //     if(m_FramePeriodeCounter >= FRAME_RATE_PERIODE)
00703 //     {
00704 //         m_FrameRate = m_FramePeriodeCounter * 1000.0f / m_PeriodeTime;
00705 //         m_PeriodeTime = 0.0f;
00706 //         m_FramePeriodeCounter = 0;
00707 //     }
00708   }
00709 //---------------------------------------------------------------------------------------------------------
00710   void GraphicsDisplay::DestroyOpenGLWindow()
00711   {
00712     if (m_GfxInterfaceCreated == true)
00713     {
00714       if (m_fullscreen)                                                                         // Are We In Fullscreen Mode?
00715       {
00716         ChangeDisplaySettings (NULL, 0);                                        // If So Switch Back To The Desktop
00717         ShowCursor (TRUE);                                                              // Show Mouse Pointer
00718       }
00719 
00720       if (_opengl_rendering_context)                                                                                    // Do We Have A Rendering Context?
00721       {
00722         if (!wglMakeCurrent (_device_context, NULL) )                                   // Are We Able To Release The DC And RC Contexts?
00723         {
00724           MessageBox (NULL, TEXT ("Release Of DC And RC Failed."), TEXT ("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
00725         }
00726 
00727         if (!wglDeleteContext (_opengl_rendering_context) )                                             // Are We Able To Delete The RC?
00728         {
00729           MessageBox (NULL, TEXT ("Release Rendering Context Failed."), TEXT ("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
00730         }
00731 
00732         _opengl_rendering_context = NULL;                                                                               // Set RC To NULL
00733       }
00734 
00735       if (_device_context && !ReleaseDC (m_hWnd, _device_context) )                                     // Are We Able To Release The DC
00736       {
00737         MessageBox (NULL, TEXT ("Release Device Context Failed."), TEXT ("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
00738         _device_context = NULL;                                                                         // Set DC To NULL
00739       }
00740 
00741       if (m_hWnd && ! (::DestroyWindow (m_hWnd) ) )                                     // Are We Able To Destroy The Window?
00742       {
00743         MessageBox (NULL, TEXT ("Could Not Release window handle."), TEXT ("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
00744         m_hWnd = NULL;                                                                          // Set Window Handle To NULL
00745       }
00746     }
00747 
00748     m_GfxInterfaceCreated = false;
00749   }
00750 
00751 
00752 // //---------------------------------------------------------------------------------------------------------
00753 // // convert a MSWindows VK_x to an Fltk (X) Keysym:
00754 // // See also the inverse converter in Fl_get_key_win32.cxx
00755 // // This table is in numeric order by VK:
00756 // static const struct {unsigned short vk, fltk, extended;} vktab[] = {
00757 //     {NUX_VK_BACK,        NUX_BackSpace},
00758 //     {NUX_VK_TAB,         NUX_Tab},
00759 //     {NUX_VK_CLEAR,       NUX_Clear,      0xff0b/*XK_Clear*/},
00760 //     {NUX_VK_ENTER,       NUX_Enter,      NUX_KP_ENTER},
00761 //     {NUX_VK_SHIFT,       NUX_Shift_L,        NUX_EXT_Shift_R},
00762 //     {NUX_VK_CONTROL, NUX_Control_L,  NUX_EXT_Control_R},
00763 //     {NUX_VK_MENU,        NUX_Alt_L,      NUX_EXT_Alt_R},
00764 //     {NUX_VK_PAUSE,       NUX_Pause},
00765 //     {NUX_VK_CAPITAL, NUX_Caps_Lock},
00766 //     {NUX_VK_ESCAPE,      NUX_Escape},
00767 //     {NUX_VK_SPACE,       ' '},
00768 //     {NUX_VK_PAGE_UP, NUX_Page_Up     /*KP+'9'*/,         NUX_KP_PAGE_UP},
00769 //     {NUX_VK_PAGE_DOWN,  NUX_Page_Down   /*KP+'3'*/,      NUX_KP_PAGE_DOWN},
00770 //     {NUX_VK_END,         NUX_End         /*KP+'1'*/,     NUX_KP_END},
00771 //     {NUX_VK_HOME,        NUX_Home        /*KP+'7'*/,     NUX_KP_HOME},
00772 //     {NUX_VK_LEFT,        NUX_Left        /*KP+'4'*/,     NUX_KP_LEFT},
00773 //     {NUX_VK_UP,              NUX_Up          /*KP+'8'*/,         NUX_KP_UP},
00774 //     {NUX_VK_RIGHT,       NUX_Right       /*KP+'6'*/,     NUX_KP_RIGHT},
00775 //     {NUX_VK_DOWN,        NUX_Down        /*KP+'2'*/,     NUX_KP_DOWN},
00776 //     {NUX_VK_SNAPSHOT,        NUX_Print},         // does not work on NT
00777 //     {NUX_VK_INSERT,      NUX_Insert      /*KP+'0'*/,     NUX_KP_INSERT},
00778 //     {NUX_VK_DELETE,      NUX_Delete      /*KP+'.'*/,     NUX_KP_DELETE},
00779 //     {NUX_VK_LWIN,        NUX_LWin        /*Meta_L*/},
00780 //     {NUX_VK_RWIN,        NUX_RWin        /*Meta_R*/},
00781 //     {NUX_VK_APPS,        NUX_VK_APPS     /*Menu*/},
00782 //     {NUX_VK_MULTIPLY,        NUX_Multiply    /*KP+'*'*/},
00783 //     {NUX_VK_ADD,         NUX_Add         /*KP+'+'*/},
00784 //     {NUX_VK_SUBTRACT,        NUX_Subtract    /*KP+'-'*/},
00785 //     {NUX_VK_DECIMAL, NUX_Decimal     /*KP+'.'*/},
00786 //     {NUX_VK_DIVIDE,      NUX_Divide      /*KP+'/'*/},
00787 //     {NUX_VK_NUMLOCK, NUX_Numlock     /*Num_Lock*/},
00788 //     {NUX_VK_SCROLL,      NUX_Scroll      /*Scroll_Lock*/},
00789 //     {0xba,   ';'},
00790 //     {0xbb,   '='},
00791 //     {0xbc,   ','},
00792 //     {0xbd,   '-'},
00793 //     {0xbe,   '.'},
00794 //     {0xbf,   '/'},
00795 //     {0xc0,   '`'},
00796 //     {0xdb,   '['},
00797 //     {0xdc,   '\\'},
00798 //     {0xdd,   ']'},
00799 //     {0xde,   '\''}
00800 // };
00801 
00802   /*
00803       The extended-key flag indicates whether the keystroke message originated
00804       from one of the additional keys on the enhanced keyboard. The extended keys
00805       consist of the ALT and CTRL keys on the right-hand side of the keyboard;
00806       the INS, DEL, HOME, END, PAGE UP, PAGE DOWN, and arrow keys in the clusters
00807       to the left of the numeric keypad; the NUM LOCK key; the BREAK (CTRL+PAUSE) key;
00808       the PRINT SCRN key; and the divide (/) and ENTER keys in the numeric keypad.
00809       The extended-key flag is set if the key is an extended key.
00810   */
00811 //---------------------------------------------------------------------------------------------------------
00812   /*static int ms2fltk(int vk, int extended)
00813   {
00814       static unsigned short vklut[256];
00815       static unsigned short extendedlut[256];
00816       if (!vklut[1])
00817       {
00818           // init the table
00819           unsigned int i;
00820           for (i = 0; i < 256; i++)
00821           {
00822               vklut[i] = i; //tolower(i);
00823           }
00824   //        for (i=VK_F1; i<=VK_F16; i++)
00825   //        {
00826   //            vklut[i] = i+(FL_F-(VK_F1-1));   // (FL_F + 1 -> VK_F1) ... (FL_F + 16 -> VK_F16)
00827   //        }
00828   //        for (i=VK_NUMPAD0; i<=VK_NUMPAD9; i++)
00829   //        {
00830   //            vklut[i] = i+(FL_KP+'0'-VK_NUMPAD0);    // (FL_KP + '0' -> VK_NUMPAD0) ... (FL_KP + '9' = VK_NUMPAD9)
00831   //        }
00832           for (i = 0; i < sizeof(vktab)/sizeof(*vktab); i++)
00833           {
00834               vklut[vktab[i].vk] = vktab[i].fltk;
00835               extendedlut[vktab[i].vk] = vktab[i].extended;
00836           }
00837           for (i = 0; i < 256; i++)
00838           {
00839               if (!extendedlut[i])
00840                   extendedlut[i] = vklut[i];
00841           }
00842       }
00843 
00844       return extended ? extendedlut[vk] : vklut[vk];
00845   }*/
00846 //---------------------------------------------------------------------------------------------------------
00847   static int mouse_event (HWND window, Event *event, int what, int button,
00848                           WPARAM wParam, LPARAM lParam)
00849   {
00850     static int px, py, pmx, pmy;
00851     event->e_x = (signed short) LOWORD (lParam);
00852     event->e_y = (signed short) HIWORD (lParam);
00853     event->e_x_root = 0;
00854     event->e_y_root = 0;
00855 
00856     POINT EventScreenPosition;
00857 
00858     ClientToScreen (window, &EventScreenPosition);
00859     EventScreenPosition.x = event->e_x;
00860     EventScreenPosition.y = event->e_y;
00861     POINT WindowScreenPosition;
00862     WindowScreenPosition.x = WindowScreenPosition.y = 0;
00863     ClientToScreen (window, &WindowScreenPosition);
00864 
00865     // Erase mouse event and mouse doubleclick events. Keep the mouse states.
00866     ulong _mouse_state = event->e_mouse_state & 0x0F000000;
00867 
00868     // establish cause of the event
00869 //     if(button == 1)
00870 //         _mouse_state |= NUX_EVENT_BUTTON1;
00871 //     else if(button == 2)
00872 //         _mouse_state |= NUX_EVENT_BUTTON2;
00873 //     else if(button == 3)
00874 //         _mouse_state |= NUX_EVENT_BUTTON3;
00875 //     else
00876     if (button == 4)
00877     {
00878       event->e_mouse_state |= NUX_EVENT_MOUSEWHEEL;
00879       event->e_event = NUX_MOUSE_WHEEL;
00880 
00881       int zDelta = GET_WHEEL_DELTA_WPARAM (wParam);
00882       int xPos = (int) (short) LOWORD (lParam) - WindowScreenPosition.x;
00883       int yPos = (int) (short) HIWORD (lParam) - WindowScreenPosition.y;
00884       event->e_x = xPos;
00885       event->e_y = yPos;
00886 
00887       event->e_wheeldelta = zDelta;
00888       return 1;
00889     }
00890 
00891     // set the cause of the event
00892     switch (what)
00893     {
00894       case 0:
00895       {
00896         // mouse down
00897         if (button == 1)
00898         {
00899           _mouse_state |= NUX_STATE_BUTTON1_DOWN;
00900           _mouse_state |= NUX_EVENT_BUTTON1_DOWN;
00901         }
00902         else if (button == 2)
00903         {
00904           _mouse_state |= NUX_STATE_BUTTON2_DOWN;
00905           _mouse_state |= NUX_EVENT_BUTTON2_DOWN;
00906         }
00907         else if (button == 3)
00908         {
00909           _mouse_state |= NUX_STATE_BUTTON3_DOWN;
00910           _mouse_state |= NUX_EVENT_BUTTON3_DOWN;
00911         }
00912       }
00913       break;
00914 
00915       case 1:
00916       {
00917         // double click
00918         if (button == 1)
00919         {
00920           _mouse_state |= NUX_EVENT_BUTTON1_DBLCLICK;
00921           _mouse_state |= NUX_STATE_BUTTON1_DOWN;
00922           _mouse_state |= NUX_EVENT_BUTTON1_DOWN;
00923         }
00924         else if (button == 2)
00925         {
00926           _mouse_state |= NUX_EVENT_BUTTON2_DBLCLICK;
00927           _mouse_state |= NUX_STATE_BUTTON2_DOWN;
00928           _mouse_state |= NUX_EVENT_BUTTON2_DOWN;
00929         }
00930         else if (button == 3)
00931         {
00932           _mouse_state |= NUX_EVENT_BUTTON3_DBLCLICK;
00933           _mouse_state |= NUX_STATE_BUTTON3_DOWN;
00934           _mouse_state |= NUX_EVENT_BUTTON3_DOWN;
00935         }
00936       }
00937       break;
00938 
00939       case 2:
00940       {
00941         // button up
00942         if (button == 1)
00943         {
00944           _mouse_state &= ~NUX_STATE_BUTTON1_DOWN;
00945           _mouse_state |= NUX_EVENT_BUTTON1_UP;
00946         }
00947         else if (button == 2)
00948         {
00949           _mouse_state &= ~NUX_STATE_BUTTON2_DOWN;
00950           _mouse_state |= NUX_EVENT_BUTTON2_UP;
00951         }
00952         else if (button == 3)
00953         {
00954           _mouse_state &= ~NUX_STATE_BUTTON3_DOWN;
00955           _mouse_state |= NUX_EVENT_BUTTON3_UP;
00956         }
00957       }
00958       break;
00959     }
00960 
00961     event->e_mouse_state = _mouse_state;
00962 
00963     switch (what)
00964     {
00965       case 1: // double-click
00966 
00967         if (event->e_is_click)
00968         {
00969           event->e_clicks++;
00970           // The SetCapture function sets the mouse capture to the specified window belonging to
00971           // the current thread. SetCapture captures mouse input either when the mouse is over the
00972           // capturing window, or when the mouse button was pressed while the mouse was over the
00973           // capturing window and the button is still down. Only one window at a time can capture the mouse.
00974           SetCapture (window);
00975           event->e_is_click = 1;
00976           px = pmx = event->e_x;
00977           py = pmy = event->e_y;
00978           event->e_event = NUX_MOUSE_DOUBLECLICK;
00979           return 1;
00980         }
00981 
00982       case 0: // single-click
00983         event->e_clicks = 0;
00984         // The SetCapture function sets the mouse capture to the specified window belonging to
00985         // the current thread. SetCapture captures mouse input either when the mouse is over the
00986         // capturing window, or when the mouse button was pressed while the mouse was over the
00987         // capturing window and the button is still down. Only one window at a time can capture the mouse.
00988         SetCapture (window);
00989         event->e_is_click = 1;
00990         px = pmx = event->e_x;
00991         py = pmy = event->e_y;
00992         event->e_event = NUX_MOUSE_PRESSED;
00993         return 1;
00994 
00995       case 2: // release:
00996         // The ReleaseCapture function releases the mouse capture from a window in the current thread
00997         // and restores normal mouse input processing. A window that has captured the mouse receives all
00998         // mouse input, regardless of the position of the cursor, except when a mouse button is clicked
00999         // while the cursor hot spot is in the window of another thread.
01000         ReleaseCapture();
01001         event->e_event = NUX_MOUSE_RELEASED;
01002         return 1;
01003 
01004       case 3: // move:
01005       default: // avoid compiler warning
01006         // MSWindows produces extra events even if mouse does not move, ignore them.
01007         // http://blogs.msdn.com/oldnewthing/archive/2003/10/01/55108.aspx: Why do I get spurious WM_MOUSEMOVE messages?
01008         if (event->e_x == pmx && event->e_y == pmy)
01009           return 1;
01010 
01011         pmx = event->e_x;
01012         pmy = event->e_y;
01013 //        if(abs(event->e_x - px)>5 || abs(event->e_y - py)>5)
01014 //            event->e_is_click = 0;
01015         event->e_event = NUX_MOUSE_MOVE;
01016         return 1;
01017     }
01018 
01019     return 0;
01020   }
01021 
01022   unsigned int GetModifierKeyState()
01023   {
01024     unsigned int state = 0;
01025     unsigned short r = 0;
01026 
01027     // For CapsLock, we don't want to know if the key is pressed Down or Up.
01028     // We really want to know the state of the the CapsLock: on (keyboard light is on) or off?
01029     r = GetKeyState (VK_CAPITAL);
01030 
01031     if (r & 1)
01032       state |= NUX_STATE_CAPS_LOCK;
01033 
01034     // For NumLock, we don't want to know if the key is pressed Down or Up.
01035     // We really want to know the state of the the NumLock: on (keyboard light is on) or off?
01036     r = GetKeyState (VK_NUMLOCK);
01037 
01038     if (r & 1)
01039       state |= NUX_STATE_NUMLOCK;
01040 
01041     r = GetKeyState (VK_SCROLL);
01042 
01043     if (r & 0x8000)
01044       state |= NUX_STATE_SCROLLLOCK;
01045 
01046     r = GetKeyState (VK_CONTROL);
01047 
01048     if (r & 0x8000)
01049       state |= NUX_STATE_CTRL;
01050 
01051     r = GetKeyState (VK_SHIFT);
01052 
01053     if (r & 0x8000)
01054       state |= NUX_STATE_SHIFT;
01055 
01056     r = GetKeyState (VK_MENU);
01057 
01058     if (r & 0x8000)
01059       state |= NUX_STATE_ALT;
01060 
01061 
01062 
01063     if ( (GetKeyState (VK_LWIN) | GetKeyState (VK_RWIN) ) &~1)
01064     {
01065       // WIN32 bug?  GetKeyState returns garbage if the user hit the
01066       // meta key to pop up start menu.  Sigh.
01067       if ( (GetAsyncKeyState (VK_LWIN) | GetAsyncKeyState (VK_RWIN) ) &~1)
01068         state |= NUX_STATE_META;
01069     }
01070 
01071     return state;
01072   }
01073 
01074 //---------------------------------------------------------------------------------------------------------
01075   void GraphicsDisplay::GetSystemEvent (Event *evt)
01076   {
01077     MSG         msg;
01078     event_->Reset();
01079     // Erase mouse event and mouse doubleclick states. Keep the mouse states.
01080     event_->e_mouse_state &= 0x0F000000;
01081 
01082     // Always set the second parameter of PeekMessage to NULL. Indeed, many services creates
01083     // windows on the program behalf. If pass the main window as filter, we will miss all the
01084     // messages from the other windows.
01085     // Same with GetMessage.
01086     if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE) )     // Is There A Message Waiting? If yes, remove it.
01087     {
01088       if (msg.message == NUX_THREADMSG_START_RENDERING)
01089       {
01090         m_PauseGraphicsRendering = false;
01091         MakeGLContextCurrent (true);
01092       }
01093 
01094       TranslateMessage (&msg);
01095       DispatchMessage (&msg);
01096 
01097       memcpy (evt, event_, sizeof (Event) );
01098     }
01099     else
01100     {
01101       memcpy (evt, event_, sizeof (Event) );
01102     }
01103 
01104     if (msg.message == WM_QUIT)
01105     {
01106       // Re-post the message that we retrieved so other modal loops will catch it.
01107       // See [Modality, part 3: The WM_QUIT message] http://blogs.msdn.com/oldnewthing/archive/2005/02/22/378018.aspx
01108       PostQuitMessage (msg.wParam);
01109 
01110       event_->e_event = NUX_TERMINATE_APP;
01111       memcpy (evt, event_, sizeof (Event) );
01112     }
01113 
01114     if (msg.message == -1) // error
01115     {
01116       event_->e_event = NUX_NO_EVENT;
01117       memcpy (evt, event_, sizeof (Event) );
01118     }
01119   }
01120 
01121   void GraphicsDisplay::ProcessForeignWin32Event (HWND hWnd, MSG msg, WPARAM wParam, LPARAM lParam, Event *event)
01122   {
01123     event_->Reset();
01124     // Erase mouse event and mouse doubleclick states. Keep the mouse states.
01125     event_->e_mouse_state &= 0x0F000000;
01126 
01127     // Always set the second parameter of PeekMessage to NULL. Indeed, many services creates
01128     // windows on the program behalf. If pass the main window as filter, we will miss all the
01129     // messages from the other windows.
01130     // Same with GetMessage.
01131     ProcessWin32Event (hWnd, msg.message, wParam, lParam);
01132     memcpy (event, event_, sizeof (Event) );
01133 
01134     if (msg.message != WM_QUIT)
01135     {
01136       // Re-post the message that we retrieved so other modal loops will catch it.
01137       // See [Modality, part 3: The WM_QUIT message] http://blogs.msdn.com/oldnewthing/archive/2005/02/22/378018.aspx
01138       PostQuitMessage (msg.wParam);
01139 
01140       event_->e_event = NUX_TERMINATE_APP;
01141       memcpy (event, event_, sizeof (Event) );
01142     }
01143 
01144     if (msg.message == -1) // error
01145     {
01146       event_->e_event = NUX_NO_EVENT;
01147       memcpy (event, event_, sizeof (Event) );
01148     }
01149   }
01150 
01151   Event &GraphicsDisplay::GetCurrentEvent()
01152   {
01153     return *event_;
01154   }
01155 
01156 //---------------------------------------------------------------------------------------------------------
01157   LRESULT CALLBACK WndProcManager (HWND hWnd,                   // Handle For This Window
01158                                    UINT uMsg,                   // Message For This Window
01159                                    WPARAM       wParam,                 // Additional Message Information
01160                                    LPARAM       lParam)                 // Additional Message Information
01161   {
01162     // This creates a  warning. It is a 64-bits compatibility issue.
01163     // When not in 64-bit you can disable the warning:
01164     // Project Properties --> C/C++ tab --> General --> Select "NO" for - Detect 64-bit Portability Issues.
01165     // See also GetWindowLongPtr
01166     GraphicsDisplay *GLWindow = reinterpret_cast<GraphicsDisplay *> (::GetWindowLongPtr (hWnd, GWLP_USERDATA) );
01167 
01168     if (GLWindow == 0)
01169     {
01170       switch (uMsg)
01171       {
01172           // These cases happens before GLWindow is set. So we must catch them here.
01173 
01174         case WM_NCCREATE:
01175         {
01176           // Non Client Area
01177 
01178           // WARNING: MUST RETURN TRUE TO CONTINUE WITH THE CREATION OF THE WINDOW
01179           // return TRUE;
01180 
01181           // WARNING: Continue with DefWindowProc if you want the title of the window to appears
01182           // or you have to set it yourself before returning true
01183           break;
01184         }
01185         case WM_CREATE:
01186         {
01187           // WARNING: MUST RETURN 0 TO CONTINUE WITH THE CREATION OF THE WINDOW
01188           return 0;
01189         }
01190       }
01191 
01192       return DefWindowProc (hWnd, uMsg, wParam, lParam);
01193     }
01194 
01195     return GLWindow->ProcessWin32Event (hWnd, uMsg, wParam, lParam);
01196   }
01197 
01198   LRESULT GraphicsDisplay::ProcessWin32Event (HWND      hWnd,          // Handle For This Window
01199       UINT      uMsg,           // Message For This Window
01200       WPARAM    wParam,         // Additional Message Information
01201       LPARAM    lParam)         // Additional Message Information
01202   {
01203     switch (uMsg)
01204     {
01205       case WM_DESTROY:
01206       {
01207         nuxDebugMsg (TEXT ("[GraphicsDisplay::WndProc]: Window \"%s\" received WM_DESTROY message."), m_WindowTitle.GetTCharPtr() );
01208         break;
01209       }
01210 
01211       case WM_CLOSE:
01212       {
01213         nuxDebugMsg (TEXT ("[GraphicsDisplay::WndProc]: Window \"%s\" received WM_CLOSE message."), m_WindowTitle.GetTCharPtr() );
01214         // close? yes or no?
01215         PostQuitMessage (0);
01216         return 0;
01217       }
01218 
01219       case WM_PAINT:
01220       {
01221         ValidateRect (hWnd, NULL); //  validate the surface to avoid receiving WM_PAINT continuously
01222         event_->e_event = NUX_WINDOW_DIRTY;
01223         break;
01224       }
01225 
01226       case WM_CAPTURECHANGED:
01227       {
01228         // The WM_CAPTURECHANGED message is sent to the window that is losing the mouse capture
01229         if ((HWND) lParam == hWnd)
01230         {
01231           // Cancel everything about the mouse state and send a NUX_WINDOW_EXIT_FOCUS message.
01232           event_->e_mouse_state = 0;
01233           //nuxDebugMsg(TEXT("Windows Msg: WM_CAPTURECHANGED/NUX_WINDOW_EXIT_FOCUS"));
01234           return 0;
01235         }
01236 
01237         break;
01238       }
01239 
01240       case WM_ENTERSIZEMOVE:
01241       {
01242         return 0;
01243       }
01244 
01245       case WM_EXITSIZEMOVE:
01246       {
01247         RECT clientrect;
01248         GetClientRect ( hWnd, &clientrect);
01249 
01250         event_->e_event = NUX_SIZE_CONFIGURATION;
01251         event_->width =  clientrect.right - clientrect.left;
01252         event_->height =  clientrect.bottom - clientrect.top;
01253         return 0;
01254       }
01255 
01256       case WM_SIZE:
01257       {
01258         RECT clientrect;
01259         GetClientRect ( hWnd, &clientrect);
01260 
01261         event_->e_event = NUX_NO_EVENT; //NUX_SIZE_CONFIGURATION;
01262         event_->width =  clientrect.right - clientrect.left;
01263         event_->height =  clientrect.bottom - clientrect.top;
01264 
01265         //setViewPort(0, 0, clientrect.right - clientrect.left, clientrect.bottom - clientrect.top);
01266         m_WindowSize.width = clientrect.right - clientrect.left;
01267         m_WindowSize.height = clientrect.bottom - clientrect.top;
01268 
01269         if ((wParam == SIZE_MAXHIDE) || (wParam == SIZE_MINIMIZED))
01270         {
01271           m_is_window_minimized = true;
01272         }
01273         else
01274         {
01275           m_is_window_minimized = false;
01276         }
01277 
01278         if ((wParam == SIZE_MAXIMIZED) || (wParam == SIZE_RESTORED))
01279         {
01280           event_->e_event = NUX_SIZE_CONFIGURATION;
01281         }
01282 
01283         return 0;
01284       }
01285 
01286       case WM_SETFOCUS:
01287       {
01288         event_->e_event = NUX_WINDOW_ENTER_FOCUS;
01289         event_->e_mouse_state = 0;
01290 
01291         // This causes the mouse to be outside of all widgets when it is tested in m_EventHandler.Process().
01292         // 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
01293         // outside of all widgets. A subsequent mouse down or mouse move event will set the correct values for e_x and e_y.
01294         event_->e_x = 0xFFFFFFFF;
01295         event_->e_y = 0xFFFFFFFF;
01296         event_->e_dx = 0;
01297         event_->e_dy = 0;
01298         event_->virtual_code = 0;
01299         //nuxDebugMsg(TEXT("Windows Msg: WM_SETFOCUS/NUX_WINDOW_ENTER_FOCUS"));
01300         break;
01301       }
01302 
01303       case WM_KILLFOCUS:
01304       {
01305         event_->e_event = NUX_WINDOW_EXIT_FOCUS;
01306         event_->e_mouse_state = 0;
01307 
01308         // This causes the mouse to be outside of all widgets when it is tested in m_EventHandler.Process()
01309         event_->e_x = 0xFFFFFFFF;
01310         event_->e_y = 0xFFFFFFFF;
01311         event_->e_dx = 0;
01312         event_->e_dy = 0;
01313         event_->virtual_code = 0;
01314         //nuxDebugMsg(TEXT("Windows Msg: WM_KILLFOCUS/NUX_WINDOW_EXIT_FOCUS"));
01315         break;
01316       }
01317 
01318       case WM_NCHITTEST:
01319       {
01320         break;
01321       }
01322 
01323       case WM_ACTIVATE:
01324       {
01325         if (LOWORD (wParam) != WA_INACTIVE)
01326         {
01327           event_->e_event = NUX_WINDOW_ENTER_FOCUS;
01328         }
01329         else
01330         {
01331           event_->e_event = NUX_WINDOW_EXIT_FOCUS;
01332         }
01333         event_->e_mouse_state = 0;
01334 
01335         // This causes the mouse to be outside of all widgets when it is tested in m_EventHandler.Process().
01336         // 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
01337         // outside of all widgets. A subsequent mouse down or mouse move event will set the correct values for e_x and e_y.
01338         event_->e_x = 0xFFFFFFFF;
01339         event_->e_y = 0xFFFFFFFF;
01340         event_->e_dx = 0;
01341         event_->e_dy = 0;
01342         event_->virtual_code = 0;
01343 
01344         event_->e_key_modifiers = GetModifierKeyState();
01345         return 0;
01346       }
01347 
01348       case WM_ACTIVATEAPP:
01349         {
01350           if (wParam)
01351           {
01352             event_->e_event = NUX_WINDOW_ENTER_FOCUS;
01353           }
01354           else
01355           {
01356             event_->e_event = NUX_WINDOW_EXIT_FOCUS;
01357           }
01358           event_->e_mouse_state = 0;
01359 
01360           // This causes the mouse to be outside of all widgets when it is tested in m_EventHandler.Process().
01361           // 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
01362           // outside of all widgets. A subsequent mouse down or mouse move event will set the correct values for e_x and e_y.
01363           event_->e_x = 0xFFFFFFFF;
01364           event_->e_y = 0xFFFFFFFF;
01365           event_->e_dx = 0;
01366           event_->e_dy = 0;
01367           event_->virtual_code = 0;
01368 
01369           event_->e_key_modifiers = GetModifierKeyState();
01370           return 0;
01371         }
01372 
01373       case WM_SYSKEYDOWN:
01374       case WM_KEYDOWN:
01375       {
01376         event_->e_event = NUX_KEYDOWN;
01377         event_->e_key_modifiers = GetModifierKeyState();
01378         event_->e_keysym = wParam;
01379 
01380         if ( (uMsg == WM_KEYDOWN) || (uMsg == WM_SYSKEYDOWN) )
01381         {
01382           event_->VirtualKeycodeState[GraphicsDisplay::Win32KeySymToINL (wParam) ] = 1;
01383         }
01384 
01385         if (wParam == VK_CONTROL)
01386         {
01387           if (lParam & (1 << 24) )
01388           {
01389             event_->e_keysym = NUX_VK_RCONTROL;
01390           }
01391           else
01392           {
01393             event_->e_keysym = NUX_VK_LCONTROL;
01394           }
01395         }
01396 
01397         if (wParam == VK_MENU)
01398         {
01399           if (lParam & (1 << 24) )
01400           {
01401             event_->e_keysym = NUX_VK_RALT;
01402           }
01403           else
01404           {
01405             event_->e_keysym = NUX_VK_LALT;
01406           }
01407         }
01408 
01409         if (wParam == VK_SHIFT)
01410         {
01411           if (HIWORD (GetAsyncKeyState (VK_LSHIFT) ) )
01412           {
01413             event_->e_keysym = NUX_VK_LSHIFT;
01414           }
01415           else if (HIWORD (GetAsyncKeyState (VK_RSHIFT) ) )
01416           {
01417             event_->e_keysym = NUX_VK_RSHIFT;
01418           }
01419         }
01420 
01421         break;
01422       }
01423 
01424       case WM_SYSKEYUP:
01425       case WM_KEYUP:
01426       {
01427         event_->e_event = NUX_KEYUP;
01428         event_->e_key_modifiers = GetModifierKeyState();
01429         event_->e_keysym = wParam;
01430 
01431         if ( (uMsg == WM_KEYUP) || (uMsg == WM_SYSKEYUP) )
01432         {
01433           event_->VirtualKeycodeState[GraphicsDisplay::Win32KeySymToINL (wParam) ] = 0;
01434         }
01435 
01436         break;
01437       }
01438 
01439       case WM_DEADCHAR:
01440       case WM_SYSDEADCHAR:
01441       case WM_CHAR:
01442       case WM_SYSCHAR:
01443       {
01444         event_->e_key_modifiers = GetModifierKeyState();
01445 
01446         // reset key repeat count to 0.
01447         event_->e_key_repeat_count = 0;
01448 
01449         if (lParam & (1 << 31) )
01450         {
01451           // key up events.
01452           event_->e_event = NUX_KEYUP;
01453           return 0;
01454         }
01455         else
01456         {
01457           // key down events.
01458           event_->e_event = NUX_KEYDOWN;
01459           event_->e_key_repeat_count = (int) (lParam & 0xff);
01460         }
01461 
01462 
01463         if ((wParam == '\b') || // backspace
01464           (wParam == '\t') || // tab
01465           (wParam == '\n') || // linefeed
01466           (wParam == '\r')) // carriage return
01467         {
01468           return 0;
01469         }
01470 
01471         t_UTF16 *utf16_str = new t_UTF16 [4];
01472         Memset (utf16_str, 0, sizeof (t_UTF16) * 4);
01473         Memcpy (utf16_str, (int*) &wParam, sizeof (wParam));
01474         t_UTF16 *temp0 = utf16_str;
01475 
01476         t_UTF8 *utf8_str = new t_UTF8 [NUX_EVENT_TEXT_BUFFER_SIZE];
01477         Memset (utf8_str, 0, sizeof (t_UTF8) * NUX_EVENT_TEXT_BUFFER_SIZE);
01478         t_UTF8 *temp1 = utf8_str;
01479 
01480 
01481         ConversionResult res = ConvertUTF16toUTF8 ((const nux::t_UTF16 **) &temp0,
01482           utf16_str + sizeof (t_UTF16) * 4,
01483           &temp1,
01484           utf8_str + NUX_EVENT_TEXT_BUFFER_SIZE,
01485           lenientConversion);
01486 
01487         if (res == conversionOK)
01488         {
01489           Memcpy (event_->e_text, utf8_str, NUX_EVENT_TEXT_BUFFER_SIZE);
01490         }
01491         delete utf8_str;
01492         delete utf16_str;
01493 
01494         return 0;
01495       }
01496 
01497       case WM_UNICHAR:
01498       {
01499         if (wParam == UNICODE_NOCHAR)
01500           return 1;
01501 
01502         event_->e_key_modifiers = GetModifierKeyState();
01503 
01504         // reset key repeat count to 0.
01505         event_->e_key_repeat_count = 0;
01506 
01507         if (lParam & (1 << 31) )
01508         {
01509           // key up events.
01510           event_->e_event = NUX_KEYUP;
01511           return 0;
01512         }
01513         else
01514         {
01515           // key down events.
01516           event_->e_event = NUX_KEYDOWN;
01517           event_->e_key_repeat_count = (int) (lParam & 0xff);
01518         }
01519 
01520         t_UTF32 *utf32_str = new t_UTF32 [4];
01521         Memset (utf32_str, 0, sizeof (t_UTF32) * 4);
01522         Memcpy (utf32_str, (int*) &wParam, sizeof (wParam));
01523         t_UTF32 *temp0 = utf32_str;
01524 
01525         t_UTF8 *utf8_str = new t_UTF8 [NUX_EVENT_TEXT_BUFFER_SIZE];
01526         Memset (utf8_str, 0, sizeof (t_UTF8) * NUX_EVENT_TEXT_BUFFER_SIZE);
01527         t_UTF8 *temp1 = utf8_str;
01528 
01529 
01530         ConversionResult res = ConvertUTF32toUTF8 ((const nux::t_UTF32 **) &temp0,
01531           utf32_str + sizeof (t_UTF32) * 4,
01532           &temp1,
01533           utf8_str + NUX_EVENT_TEXT_BUFFER_SIZE,
01534           lenientConversion);
01535 
01536         if (res == conversionOK)
01537         {
01538           Memcpy (event_->e_text, utf8_str, NUX_EVENT_TEXT_BUFFER_SIZE);
01539         }
01540         delete utf8_str;
01541         delete utf32_str;
01542       }
01543 
01544       case WM_LBUTTONDOWN:
01545       {
01546         mouse_event (hWnd, event_, 0, 1, wParam, lParam);
01547         //nuxDebugMsg(TEXT("Windows Msg: WM_LBUTTONDOWN"));
01548         return 0;
01549       }
01550       case WM_LBUTTONDBLCLK:
01551       {
01552         mouse_event (hWnd, event_, 1, 1, wParam, lParam);
01553         //nuxDebugMsg(TEXT("Windows Msg: WM_LBUTTONDBLCLK"));
01554         return 0;
01555       }
01556       case WM_LBUTTONUP:
01557       {
01558         mouse_event (hWnd, event_, 2, 1, wParam, lParam);
01559         //nuxDebugMsg(TEXT("Windows Msg: WM_LBUTTONUP"));
01560         return 0;
01561       }
01562       case WM_MBUTTONDOWN:
01563       {
01564         mouse_event (hWnd, event_, 0, 2, wParam, lParam);
01565         break;
01566       }
01567       case WM_MBUTTONDBLCLK:
01568       {
01569         mouse_event (hWnd, event_, 1, 2, wParam, lParam);
01570         break;
01571       }
01572       case WM_MBUTTONUP:
01573       {
01574         mouse_event (hWnd, event_, 2, 2, wParam, lParam);
01575         break;
01576       }
01577       case WM_RBUTTONDOWN:
01578       {
01579         mouse_event (hWnd, event_, 0, 3, wParam, lParam);
01580         break;
01581       }
01582       case WM_RBUTTONDBLCLK:
01583       {
01584         mouse_event (hWnd, event_, 1, 3, wParam, lParam);
01585         break;
01586       }
01587       case WM_RBUTTONUP:
01588       {
01589         mouse_event (hWnd, event_, 2, 3, wParam, lParam);
01590         break;
01591       }
01592       case WM_MOUSEWHEEL:
01593       {
01594         mouse_event (hWnd, event_, 0, 4, wParam, lParam);
01595         break;
01596       }
01597 
01598       case WM_NCLBUTTONDBLCLK:
01599       {
01600         event_->e_event = NUX_WINDOW_CONFIGURATION;
01601         break;
01602       }
01603       case WM_NCLBUTTONDOWN:
01604       {
01605         event_->e_event = NUX_WINDOW_CONFIGURATION;
01606         break;
01607       }
01608       case WM_NCLBUTTONUP:
01609       {
01610         event_->e_event = NUX_WINDOW_CONFIGURATION;
01611         break;
01612       }
01613       case WM_NCMBUTTONDBLCLK:
01614       {
01615         event_->e_event = NUX_WINDOW_CONFIGURATION;
01616         break;
01617       }
01618       case WM_NCMBUTTONDOWN:
01619       {
01620         event_->e_event = NUX_WINDOW_CONFIGURATION;
01621         break;
01622       }
01623       case WM_NCMBUTTONUP:
01624       {
01625         event_->e_event = NUX_WINDOW_CONFIGURATION;
01626         break;
01627       }
01628       case WM_NCRBUTTONDBLCLK:
01629       {
01630         event_->e_event = NUX_WINDOW_CONFIGURATION;
01631         break;
01632       }
01633       case WM_NCRBUTTONDOWN:
01634       {
01635         event_->e_event = NUX_WINDOW_CONFIGURATION;
01636         break;
01637       }
01638       case WM_NCRBUTTONUP:
01639       {
01640         event_->e_event = NUX_WINDOW_CONFIGURATION;
01641         break;
01642       }
01643 
01644       case WM_MOUSEMOVE:
01645       {
01646         mouse_event (hWnd, event_, 3, 0, wParam, lParam);
01647         //nuxDebugMsg(TEXT("Windows Msg: WM_MOUSEMOVE"));
01648 
01649         TRACKMOUSEEVENT tme = { sizeof (tme) };
01650         // Enable NUX_WINDOW_MOUSELEAVE event.
01651         tme.dwFlags = TME_LEAVE;
01652         tme.hwndTrack = hWnd;
01653         TrackMouseEvent (&tme);
01654         break;
01655       }
01656 
01657       // Note: there is no WM_MOUSEENTER. WM_MOUSEENTER is equivalent to WM_MOUSEMOVE after a WM_MOUSELEAVE.
01658       case WM_MOUSELEAVE:
01659       {
01660         // All tracking requested by TrackMouseEvent is canceled when this message is generated.
01661         // The application must call TrackMouseEvent when the mouse reenters its window if
01662         // it requires further tracking of mouse hover behavior.
01663         event_->e_event = NUX_WINDOW_MOUSELEAVE;
01664         // This causes the mouse to be outside of all widgets when it is tested in m_EventHandler.Process()
01665         event_->e_x = 0xFFFFFFFF;
01666         event_->e_y = 0xFFFFFFFF;
01667         //nuxDebugMsg(TEXT("Windows Msg: WM_MOUSELEAVE/NUX_WINDOW_MOUSELEAVE"));
01668         break;
01669       }
01670 
01671       case WM_SETCURSOR:
01672 
01673         if ( (LOWORD (lParam) == HTCLIENT) && m_Cursor)
01674         {
01675           SetCursor (m_Cursor);
01676           return TRUE; //return FALSE;
01677         }
01678         else
01679           break;
01680 
01681       case WM_COMMAND:
01682       {
01683         nuxDebugMsg (TEXT ("[GraphicsDisplay::WndProc]: Window \"%s\" received WM_COMMAND message."), m_WindowTitle.GetTCharPtr() );
01684         break;;
01685       }
01686 
01687       case WM_SYSCOMMAND:                             // Intercept System Commands
01688       {
01689         switch (wParam)                         // Check System Calls
01690         {
01691           case SC_CLOSE:
01692             break;
01693           case SC_CONTEXTHELP:
01694             break;
01695           case SC_DEFAULT:
01696             break;
01697           case SC_HOTKEY:
01698             break;
01699           case SC_HSCROLL:
01700             break;
01701           case SC_KEYMENU:
01702             break;
01703           case SC_MAXIMIZE:
01704             break;
01705           case SC_MINIMIZE:
01706             break;
01707           case SC_MONITORPOWER:
01708             break;
01709           case SC_MOUSEMENU:
01710             break;
01711           case SC_MOVE:
01712             break;
01713           case SC_NEXTWINDOW:
01714             break;
01715           case SC_PREVWINDOW:
01716             break;
01717           case SC_RESTORE:
01718             break;
01719           case SC_SCREENSAVE:
01720             break;
01721           case SC_SIZE:
01722             break;
01723           case SC_TASKLIST:
01724             break;
01725           case SC_VSCROLL:
01726             break;
01727         }
01728 
01729         break;                                                                  // Exit
01730       }
01731     }
01732 
01733     return DefWindowProc (hWnd, uMsg, wParam, lParam);
01734   }
01735 
01736   int GraphicsDisplay::Win32VKToNuxKey (int vk)
01737   {
01738     switch (vk)
01739     {
01740       case VK_CANCEL:
01741         return NUX_VK_CANCEL;
01742       case VK_BACK:
01743         return NUX_VK_BACKSPACE;
01744       case VK_TAB:
01745         return NUX_VK_TAB;
01746       case VK_CLEAR:
01747         return NUX_VK_CLEAR;
01748       case VK_RETURN:
01749         return NUX_VK_ENTER;
01750       case VK_SHIFT:
01751         return NUX_VK_SHIFT;
01752       
01753       case VK_CONTROL:
01754         return NUX_VK_LCONTROL;
01755       case VK_LCONTROL:
01756         return NUX_VK_LCONTROL;
01757       case VK_RCONTROL:
01758         return NUX_VK_RCONTROL;
01759 
01760       case VK_MENU:
01761         return NUX_VK_LALT;
01762       case VK_LMENU:
01763         return NUX_VK_LALT;
01764       case VK_RMENU:
01765         return NUX_VK_RALT;
01766 
01767       case VK_PAUSE:
01768         return NUX_VK_PAUSE;
01769       case VK_CAPITAL:
01770         return NUX_VK_CAPITAL;
01771       case VK_ESCAPE:
01772         return NUX_VK_ESCAPE;
01773 
01774       case VK_PRIOR:
01775         return NUX_VK_PAGE_UP;
01776       case VK_NEXT:
01777         return NUX_VK_PAGE_DOWN;
01778       case VK_END:
01779         return NUX_VK_END;
01780       case VK_HOME:
01781         return NUX_VK_HOME;
01782       case VK_LEFT:
01783         return NUX_VK_LEFT;
01784       case VK_UP:
01785         return NUX_VK_UP;
01786       case VK_RIGHT:
01787         return NUX_VK_RIGHT;
01788       case VK_DOWN:
01789         return NUX_VK_DOWN;
01790 
01791       case VK_INSERT:
01792         return NUX_VK_INSERT;
01793       case VK_DELETE:
01794         return NUX_VK_DELETE;
01795 
01796       case 0x30:
01797         return NUX_VK_0;
01798       case 0x31:
01799         return NUX_VK_1;
01800       case 0x32:
01801         return NUX_VK_2;
01802       case 0x33:
01803         return NUX_VK_3;
01804       case 0x34:
01805         return NUX_VK_4;
01806       case 0x35:
01807         return NUX_VK_5;
01808       case 0x36:
01809         return NUX_VK_6;
01810       case 0x37:
01811         return NUX_VK_7;
01812       case 0x38:
01813         return NUX_VK_8;
01814       case 0x39:
01815         return NUX_VK_9;
01816       case 0x41:
01817         return NUX_VK_A;
01818       case 0x42:
01819         return NUX_VK_B;
01820       case 0x43:
01821         return NUX_VK_C;
01822       case 0x44:
01823         return NUX_VK_D;
01824       case 0x45:
01825         return NUX_VK_E;
01826       case 0x46:
01827         return NUX_VK_F;
01828       case 0x47:
01829         return NUX_VK_G;
01830       case 0x48:
01831         return NUX_VK_H;
01832       case 0x49:
01833         return NUX_VK_I;
01834       case 0x4A:
01835         return NUX_VK_J;
01836       case 0x4B:
01837         return NUX_VK_K;
01838       case 0x4C:
01839         return NUX_VK_L;
01840       case 0x4D:
01841         return NUX_VK_M;
01842       case 0x4E:
01843         return NUX_VK_N;
01844       case 0x4F:
01845         return NUX_VK_O;
01846       case 0x50:
01847         return NUX_VK_P;
01848       case 0x51:
01849         return NUX_VK_Q;
01850       case 0x52:
01851         return NUX_VK_R;
01852       case 0x53:
01853         return NUX_VK_S;
01854       case 0x54:
01855         return NUX_VK_T;
01856       case 0x55:
01857         return NUX_VK_U;
01858       case 0x56:
01859         return NUX_VK_V;
01860       case 0x57:
01861         return NUX_VK_W;
01862       case 0x58:
01863         return NUX_VK_X;
01864       case 0x59:
01865         return NUX_VK_Y;
01866       case 0x5A:
01867         return NUX_VK_Z;
01868 
01869       case VK_LWIN:
01870         return NUX_VK_LSUPER; // Windows key left
01871       case VK_RWIN:
01872         return NUX_VK_RSUPER; // Windows key right
01873 
01874       case VK_NUMLOCK:
01875         return NUX_VK_NUMLOCK;
01876       case VK_SCROLL:
01877         return NUX_VK_SCROLL;
01878       case VK_LSHIFT:
01879         return NUX_VK_LSHIFT;
01880       case VK_RSHIFT:
01881         return NUX_VK_RSHIFT;
01882 
01883       case VK_NUMPAD0:
01884         return NUX_KP_0;
01885       case VK_NUMPAD1:
01886         return NUX_KP_1;
01887       case VK_NUMPAD2:
01888         return NUX_KP_2;
01889       case VK_NUMPAD3:
01890         return NUX_KP_3;
01891       case VK_NUMPAD4:
01892         return NUX_KP_4;
01893       case VK_NUMPAD5:
01894         return NUX_KP_5;
01895       case VK_NUMPAD6:
01896         return NUX_KP_6;
01897       case VK_NUMPAD7:
01898         return NUX_KP_7;
01899       case VK_NUMPAD8:
01900         return NUX_KP_8;
01901       case VK_NUMPAD9:
01902         return NUX_KP_9;
01903 
01904       case VK_MULTIPLY:
01905         return NUX_KP_MULTIPLY;
01906       case VK_ADD:
01907         return NUX_KP_ADD;
01908       case VK_SEPARATOR:
01909         return NUX_KP_SEPARATOR;
01910       case VK_SUBTRACT:
01911         return NUX_VK_SUBTRACT;
01912       case VK_DECIMAL:
01913         return NUX_VK_DECIMAL;
01914       case VK_DIVIDE:
01915         return NUX_VK_SLASH;
01916 
01917       case VK_F1:
01918         return NUX_VK_F1;
01919       case VK_F2:
01920         return NUX_VK_F2;
01921       case VK_F3:
01922         return NUX_VK_F3;
01923       case VK_F4:
01924         return NUX_VK_F4;
01925       case VK_F5:
01926         return NUX_VK_F5;
01927       case VK_F6:
01928         return NUX_VK_F6;
01929       case VK_F7:
01930         return NUX_VK_F7;
01931       case VK_F8:
01932         return NUX_VK_F8;
01933       case VK_F9:
01934         return NUX_VK_F9;
01935       case VK_F10:
01936         return NUX_VK_F10;
01937       case VK_F11:
01938         return NUX_VK_F11;
01939       case VK_F12:
01940         return NUX_VK_F12;
01941       case VK_F13:
01942         return NUX_VK_F13;
01943       case VK_F14:
01944         return NUX_VK_F14;
01945       case VK_F15:
01946         return NUX_VK_F15;
01947       case VK_F16:
01948         return NUX_VK_F16;
01949       case VK_F17:
01950         return NUX_VK_F17;
01951       case VK_F18:
01952         return NUX_VK_F18;
01953       case VK_F19:
01954         return NUX_VK_F19;
01955       case VK_F20:
01956         return NUX_VK_F20;
01957       case VK_F21:
01958         return NUX_VK_F21;
01959       case VK_F22:
01960         return NUX_VK_F22;
01961       case VK_F23:
01962         return NUX_VK_F23;
01963       case VK_F24:
01964         return NUX_VK_F24;
01965 
01966       default:
01967         return 0x0;
01968     }
01969   }
01970 
01971   int GraphicsDisplay::Win32KeySymToINL (int Keysym)
01972   {
01973     return Keysym;
01974 
01975 //     switch (Keysym)
01976 //     {
01977 //       case VK_CANCEL:
01978 //         return NUX_VK_CANCEL;
01979 //       case VK_BACK:
01980 //         return NUX_VK_BACKSPACE;
01981 //       case VK_TAB:
01982 //         return NUX_VK_TAB;
01983 //       case VK_CLEAR:
01984 //         return NUX_VK_CLEAR;
01985 //       case VK_RETURN:
01986 //         return NUX_VK_ENTER;
01987 //       case VK_SHIFT:
01988 //         return NUX_VK_SHIFT;
01989 //       case VK_CONTROL:
01990 //         return NUX_VK_CONTROL;
01991 //       case VK_MENU:
01992 //         return NUX_VK_MENU; // ALT key
01993 //       case VK_PAUSE:
01994 //         return NUX_VK_PAUSE;
01995 //       case VK_CAPITAL:
01996 //         return NUX_VK_CAPITAL;
01997 //       case VK_ESCAPE:
01998 //         return NUX_VK_ESCAPE;
01999 //       case VK_SPACE:
02000 //         return NUX_VK_SPACE;
02001 //       case VK_PRIOR:
02002 //         return NUX_VK_PAGE_UP;
02003 //       case VK_NEXT:
02004 //         return NUX_VK_PAGE_DOWN;
02005 //       case VK_END:
02006 //         return NUX_VK_END;
02007 //       case VK_HOME:
02008 //         return NUX_VK_HOME;
02009 //       case VK_LEFT:
02010 //         return NUX_VK_LEFT;
02011 //       case VK_UP:
02012 //         return NUX_VK_UP;
02013 //       case VK_RIGHT:
02014 //         return NUX_VK_RIGHT;
02015 //       case VK_DOWN:
02016 //         return NUX_VK_DOWN;
02017 //       case VK_SELECT:
02018 //         return NUX_VK_SELECT;
02019 //       case VK_PRINT:
02020 //         return NUX_VK_PRINT;
02021 //       case VK_EXECUTE:
02022 //         return NUX_VK_EXECUTE;
02023 //       case VK_INSERT:
02024 //         return NUX_VK_INSERT;
02025 //       case VK_DELETE:
02026 //         return NUX_VK_DELETE;
02027 //       case VK_HELP:
02028 //         return NUX_VK_HELP;
02029 //       case 0x30:
02030 //         return NUX_VK_0;
02031 //       case 0x31:
02032 //         return NUX_VK_1;
02033 //       case 0x32:
02034 //         return NUX_VK_2;
02035 //       case 0x33:
02036 //         return NUX_VK_3;
02037 //       case 0x34:
02038 //         return NUX_VK_4;
02039 //       case 0x35:
02040 //         return NUX_VK_5;
02041 //       case 0x36:
02042 //         return NUX_VK_6;
02043 //       case 0x37:
02044 //         return NUX_VK_7;
02045 //       case 0x38:
02046 //         return NUX_VK_8;
02047 //       case 0x39:
02048 //         return NUX_VK_9;
02049 //       case 0x41:
02050 //         return NUX_VK_A;
02051 //       case 0x42:
02052 //         return NUX_VK_B;
02053 //       case 0x43:
02054 //         return NUX_VK_C;
02055 //       case 0x44:
02056 //         return NUX_VK_D;
02057 //       case 0x45:
02058 //         return NUX_VK_E;
02059 //       case 0x46:
02060 //         return NUX_VK_F;
02061 //       case 0x47:
02062 //         return NUX_VK_G;
02063 //       case 0x48:
02064 //         return NUX_VK_H;
02065 //       case 0x49:
02066 //         return NUX_VK_I;
02067 //       case 0x4A:
02068 //         return NUX_VK_J;
02069 //       case 0x4B:
02070 //         return NUX_VK_K;
02071 //       case 0x4C:
02072 //         return NUX_VK_L;
02073 //       case 0x4D:
02074 //         return NUX_VK_M;
02075 //       case 0x4E:
02076 //         return NUX_VK_N;
02077 //       case 0x4F:
02078 //         return NUX_VK_O;
02079 //       case 0x50:
02080 //         return NUX_VK_P;
02081 //       case 0x51:
02082 //         return NUX_VK_Q;
02083 //       case 0x52:
02084 //         return NUX_VK_R;
02085 //       case 0x53:
02086 //         return NUX_VK_S;
02087 //       case 0x54:
02088 //         return NUX_VK_T;
02089 //       case 0x55:
02090 //         return NUX_VK_U;
02091 //       case 0x56:
02092 //         return NUX_VK_V;
02093 //       case 0x57:
02094 //         return NUX_VK_W;
02095 //       case 0x58:
02096 //         return NUX_VK_X;
02097 //       case 0x59:
02098 //         return NUX_VK_Y;
02099 //       case 0x5A:
02100 //         return NUX_VK_Z;
02101 //       case VK_LWIN:
02102 //         return NUX_VK_LWIN; // Windows key left
02103 //       case VK_RWIN:
02104 //         return NUX_VK_RWIN; // Windows key right
02105 //       case VK_NUMPAD0:
02106 //         return NUX_VK_NUMPAD0;
02107 //       case VK_NUMPAD1:
02108 //         return NUX_VK_NUMPAD1;
02109 //       case VK_NUMPAD2:
02110 //         return NUX_VK_NUMPAD2;
02111 //       case VK_NUMPAD3:
02112 //         return NUX_VK_NUMPAD3;
02113 //       case VK_NUMPAD4:
02114 //         return NUX_VK_NUMPAD4;
02115 //       case VK_NUMPAD5:
02116 //         return NUX_VK_NUMPAD5;
02117 //       case VK_NUMPAD6:
02118 //         return NUX_VK_NUMPAD6;
02119 //       case VK_NUMPAD7:
02120 //         return NUX_VK_NUMPAD7;
02121 //       case VK_NUMPAD8:
02122 //         return NUX_VK_NUMPAD8;
02123 //       case VK_NUMPAD9:
02124 //         return NUX_VK_NUMPAD9;
02125 //       case VK_MULTIPLY:
02126 //         return NUX_VK_MULTIPLY;
02127 //       case VK_ADD:
02128 //         return NUX_VK_ADD;
02129 //       case VK_SEPARATOR:
02130 //         return NUX_VK_SEPARATOR;
02131 //       case VK_SUBTRACT:
02132 //         return NUX_VK_SUBTRACT;
02133 //       case VK_DECIMAL:
02134 //         return NUX_VK_DECIMAL;
02135 //       case VK_DIVIDE:
02136 //         return NUX_VK_DIVIDE;
02137 //       case VK_F1:
02138 //         return NUX_VK_F1;
02139 //       case VK_F2:
02140 //         return NUX_VK_F2;
02141 //       case VK_F3:
02142 //         return NUX_VK_F3;
02143 //       case VK_F4:
02144 //         return NUX_VK_F4;
02145 //       case VK_F5:
02146 //         return NUX_VK_F5;
02147 //       case VK_F6:
02148 //         return NUX_VK_F6;
02149 //       case VK_F7:
02150 //         return NUX_VK_F7;
02151 //       case VK_F8:
02152 //         return NUX_VK_F8;
02153 //       case VK_F9:
02154 //         return NUX_VK_F9;
02155 //       case VK_F10:
02156 //         return NUX_VK_F10;
02157 //       case VK_F11:
02158 //         return NUX_VK_F11;
02159 //       case VK_F12:
02160 //         return NUX_VK_F12;
02161 //       case VK_F13:
02162 //         return NUX_VK_F13;
02163 //       case VK_F14:
02164 //         return NUX_VK_F14;
02165 //       case VK_F15:
02166 //         return NUX_VK_F15;
02167 //       case VK_F16:
02168 //         return NUX_VK_F16;
02169 //       case VK_F17:
02170 //         return NUX_VK_F17;
02171 //       case VK_F18:
02172 //         return NUX_VK_F18;
02173 //       case VK_F19:
02174 //         return NUX_VK_F19;
02175 //       case VK_F20:
02176 //         return NUX_VK_F20;
02177 //       case VK_F21:
02178 //         return NUX_VK_F21;
02179 //       case VK_F22:
02180 //         return NUX_VK_F22;
02181 //       case VK_F23:
02182 //         return NUX_VK_F23;
02183 //       case VK_F24:
02184 //         return NUX_VK_F24;
02185 //       case VK_NUMLOCK:
02186 //         return NUX_VK_NUMLOCK;
02187 //       case VK_SCROLL:
02188 //         return NUX_VK_SCROLL;
02189 //       case VK_LSHIFT:
02190 //         return NUX_VK_LSHIFT;
02191 //       case VK_RSHIFT:
02192 //         return NUX_VK_RSHIFT;
02193 //       case VK_LCONTROL:
02194 //         return NUX_VK_LCONTROL;
02195 //       case VK_RCONTROL:
02196 //         return NUX_VK_RCONTROL;
02197 //       case VK_LMENU:
02198 //         return NUX_VK_LMENU;
02199 //       case VK_RMENU:
02200 //         return NUX_VK_RMENU;
02201 //       default:
02202 //         return 0x0;
02203 //     }
02204   }
02205 
02206   void GraphicsDisplay::InitGlobalGrabWindow ()
02207   {
02208 
02209   }
02210 
02211   bool GraphicsDisplay::GrabPointer (GrabReleaseCallback callback, void *data, bool replace_existing)
02212   {
02213     return false;
02214   }
02215 
02216   bool GraphicsDisplay::UngrabPointer (void *data)
02217   {
02218     return true;
02219   }
02220 
02221   bool GraphicsDisplay::PointerIsGrabbed ()
02222   {
02223     return false;  
02224   }
02225 
02226   bool GraphicsDisplay::GrabKeyboard (GrabReleaseCallback callback, void *data, bool replace_existing)
02227   {
02228     return _global_keyboard_grab_active;
02229   }
02230 
02231   bool GraphicsDisplay::UngrabKeyboard (void *data)
02232   {
02233     return true;
02234   }
02235 
02236   bool GraphicsDisplay::KeyboardIsGrabbed ()
02237   {
02238     return _global_keyboard_grab_active;  
02239   }
02240 
02241 //---------------------------------------------------------------------------------------------------------
02242   void GraphicsDisplay::GetDisplayInfo()
02243   {
02244     DEVMODE   devmode;
02245     INT         iMode = 0;
02246     BOOL                bRetVal;
02247     DeviceModes dm;
02248     m_num_gfx_device_modes = 0;
02249 
02250     do
02251     {
02252       bRetVal = ::EnumDisplaySettings (NULL, iMode, &devmode);
02253       iMode++;
02254 
02255       if (bRetVal)
02256       {
02257         dm.width        = devmode.dmPelsWidth;
02258         dm.height       = devmode.dmPelsHeight;
02259         dm.format       = devmode.dmBitsPerPel;
02260         dm.refresh_rate = devmode.dmDisplayFrequency;
02261         m_gfx_device_modes.push_back (dm);
02262         m_num_gfx_device_modes++;
02263       }
02264     }
02265     while (bRetVal);
02266   }
02267 
02268 //---------------------------------------------------------------------------------------------------------
02269   void GraphicsDisplay::ShowWindow()
02270   {
02271     ::ShowWindow (m_hWnd, SW_SHOW);
02272   }
02273 
02274 //---------------------------------------------------------------------------------------------------------
02275   void GraphicsDisplay::HideWindow()
02276   {
02277     ::ShowWindow (m_hWnd, SW_HIDE);
02278   }
02279 
02280   bool GraphicsDisplay::IsWindowVisible ()
02281   {
02282     return (::IsWindowVisible (m_hWnd) ? true : false);
02283   }
02284 //---------------------------------------------------------------------------------------------------------
02285   void GraphicsDisplay::EnterMaximizeWindow()
02286   {
02287     ::ShowWindow (m_hWnd, SW_MAXIMIZE);
02288   }
02289 
02290 //---------------------------------------------------------------------------------------------------------
02291   void GraphicsDisplay::ExitMaximizeWindow()
02292   {
02293     ::ShowWindow (m_hWnd, SW_RESTORE);
02294   }
02295 
02296 //---------------------------------------------------------------------------------------------------------
02297   void GraphicsDisplay::SetWindowTitle (const TCHAR *Title)
02298   {
02299     SetWindowText (m_hWnd, Title);
02300   }
02301 
02302 //---------------------------------------------------------------------------------------------------------
02303   // NUXTODO: remove this call. Make a direct access to GpuInfo via GpuDevice.
02304   bool GraphicsDisplay::HasVSyncSwapControl() const
02305   {
02306     return GetGpuDevice()->GetGpuInfo().Support_EXT_Swap_Control();
02307   }
02308 
02309 //---------------------------------------------------------------------------------------------------------
02310   void GraphicsDisplay::EnableVSyncSwapControl()
02311   {
02312     if (HasVSyncSwapControl() )
02313     {
02314       wglSwapIntervalEXT (1);
02315     }
02316   }
02317 
02318 //---------------------------------------------------------------------------------------------------------
02319   void GraphicsDisplay::DisableVSyncSwapControl()
02320   {
02321     if (HasVSyncSwapControl() )
02322     {
02323       wglSwapIntervalEXT (0);
02324     }
02325   }
02326 
02327   float GraphicsDisplay::GetFrameTime() const
02328   {
02329     return m_FrameTime;
02330   }
02331 
02332   void GraphicsDisplay::ResetFrameTime()
02333   {
02334     m_Timer.Reset();
02335   }
02336 
02337   bool GraphicsDisplay::StartOpenFileDialog (FileDialogOption &fdo)
02338   {
02339     return Win32OpenFileDialog (GetWindowHandle(), fdo);
02340   }
02341 
02342   bool GraphicsDisplay::StartSaveFileDialog (FileDialogOption &fdo)
02343   {
02344     return Win32SaveFileDialog (GetWindowHandle(), fdo);
02345   }
02346 
02347   bool GraphicsDisplay::StartColorDialog (ColorDialogOption &cdo)
02348   {
02349     return Win32ColorDialog (GetWindowHandle(), cdo);
02350   }
02351 
02352 //---------------------------------------------------------------------------------------------------------
02353   void GraphicsDisplay::SetWindowCursor (HCURSOR cursor)
02354   {
02355     m_Cursor = cursor;
02356   }
02357 
02358 //---------------------------------------------------------------------------------------------------------
02359   HCURSOR GraphicsDisplay::GetWindowCursor() const
02360   {
02361     return m_Cursor;
02362   }
02363 
02364 //---------------------------------------------------------------------------------------------------------
02365   void GraphicsDisplay::PauseThreadGraphicsRendering()
02366   {
02367     m_PauseGraphicsRendering = true;
02368     MakeGLContextCurrent (false);
02369   }
02370 
02371 //---------------------------------------------------------------------------------------------------------
02372   bool GraphicsDisplay::IsPauseThreadGraphicsRendering() const
02373   {
02374     return m_PauseGraphicsRendering;
02375   }
02376 
02377 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends