2010-06-08 16:58:58 +00:00
|
|
|
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
|
|
|
// Copyright (C) 2010 Winch Gate Property Limited
|
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Affero General Public License as
|
|
|
|
// published by the Free Software Foundation, either version 3 of the
|
|
|
|
// License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU Affero General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
#include "stdopengl.h"
|
|
|
|
#include "driver_opengl.h"
|
|
|
|
#include "driver_opengl_extension.h"
|
|
|
|
#include "driver_opengl_vertex_buffer_hard.h"
|
|
|
|
|
|
|
|
// by default, we disable the windows menu keys (F10, ALT and ALT+SPACE key doesn't freeze or open the menu)
|
|
|
|
#define NL_DISABLE_MENU
|
|
|
|
|
|
|
|
#ifdef NL_OS_WINDOWS
|
|
|
|
# include <windowsx.h>
|
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
|
|
|
# define GL_GLEXT_LEGACY
|
|
|
|
# include <OpenGL/gl.h>
|
|
|
|
# include "mac/glext.h"
|
|
|
|
# include "mac/cocoa_adapter.h"
|
|
|
|
#elif defined (NL_OS_UNIX)
|
|
|
|
# include <GL/gl.h>
|
|
|
|
# include <GL/glx.h>
|
2010-07-12 19:52:35 +00:00
|
|
|
# ifdef XRANDR
|
|
|
|
# include <X11/extensions/Xrandr.h>
|
|
|
|
# endif
|
2010-07-13 18:21:32 +00:00
|
|
|
# include <X11/Xatom.h>
|
2010-07-24 21:59:11 +00:00
|
|
|
# define _NET_WM_STATE_REMOVE 0
|
|
|
|
# define _NET_WM_STATE_ADD 1
|
2010-06-08 16:58:58 +00:00
|
|
|
#endif // NL_OS_UNIX
|
|
|
|
|
|
|
|
#include "nel/misc/mouse_device.h"
|
|
|
|
#include "nel/misc/di_event_emitter.h"
|
|
|
|
#include "nel/3d/u_driver.h"
|
2010-07-13 18:21:32 +00:00
|
|
|
#include "nel/misc/file.h"
|
2010-06-08 16:58:58 +00:00
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
using namespace NLMISC;
|
|
|
|
|
|
|
|
namespace NL3D
|
|
|
|
{
|
|
|
|
|
|
|
|
#ifdef NL_OS_WINDOWS
|
|
|
|
|
2010-07-24 21:09:43 +00:00
|
|
|
bool GlWndProc(CDriverGL *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
|
|
|
H_AUTO_OGL(GlWndProc)
|
|
|
|
if(message == WM_SIZE)
|
|
|
|
{
|
|
|
|
if (driver != NULL)
|
|
|
|
{
|
|
|
|
RECT rect;
|
2010-06-12 20:22:32 +00:00
|
|
|
GetClientRect (driver->_win, &rect);
|
2010-06-08 16:58:58 +00:00
|
|
|
|
|
|
|
// Setup gl viewport
|
|
|
|
driver->_WindowWidth = rect.right-rect.left;
|
|
|
|
driver->_WindowHeight = rect.bottom-rect.top;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(message == WM_MOVE)
|
|
|
|
{
|
|
|
|
if (driver != NULL)
|
|
|
|
{
|
|
|
|
RECT rect;
|
|
|
|
GetWindowRect (hWnd, &rect);
|
|
|
|
driver->_WindowX = rect.left;
|
|
|
|
driver->_WindowY = rect.top;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (message == WM_ACTIVATE)
|
|
|
|
{
|
|
|
|
WORD fActive = LOWORD(wParam);
|
|
|
|
if (fActive == WA_INACTIVE)
|
|
|
|
{
|
|
|
|
driver->_WndActive = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
driver->_WndActive = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool trapMessage = false;
|
|
|
|
if (driver->_EventEmitter.getNumEmitters() > 0)
|
|
|
|
{
|
|
|
|
CWinEventEmitter *we = NLMISC::safe_cast<CWinEventEmitter *>(driver->_EventEmitter.getEmitter(0));
|
|
|
|
// Process the message by the emitter
|
|
|
|
we->setHWnd(hWnd);
|
|
|
|
trapMessage = we->processMessage (hWnd, message, wParam, lParam);
|
|
|
|
}
|
|
|
|
return trapMessage;
|
|
|
|
}
|
|
|
|
|
|
|
|
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(DriverGL_WndProc)
|
|
|
|
// Get the driver pointer..
|
|
|
|
CDriverGL *pDriver=(CDriverGL*)GetWindowLongPtr (hWnd, GWLP_USERDATA);
|
|
|
|
bool trapMessage = false;
|
|
|
|
if (pDriver != NULL)
|
|
|
|
{
|
|
|
|
trapMessage = GlWndProc (pDriver, hWnd, message, wParam, lParam);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef NL_DISABLE_MENU
|
|
|
|
// disable menu (F10, ALT and ALT+SPACE key doesn't freeze or open the menu)
|
|
|
|
if(message == WM_SYSCOMMAND && wParam == SC_KEYMENU)
|
|
|
|
return 0;
|
|
|
|
#endif // NL_DISABLE_MENU
|
|
|
|
|
|
|
|
// disable menu (default ALT-F4 behavior is disabled)
|
|
|
|
if(message == WM_CLOSE)
|
|
|
|
{
|
|
|
|
if(pDriver && pDriver->ExitFunc)
|
|
|
|
{
|
|
|
|
pDriver->ExitFunc();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifndef NL_DISABLE_MENU
|
|
|
|
// if we don't disable menu, alt F4 make a direct exit else we discard the message
|
|
|
|
exit(0);
|
|
|
|
#endif // NL_DISABLE_MENU
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return trapMessage ? 0 : DefWindowProcW(hWnd, message, wParam, lParam);
|
|
|
|
}
|
|
|
|
|
2010-07-24 21:09:43 +00:00
|
|
|
#elif defined (NL_MAC_NATIVE)
|
|
|
|
|
|
|
|
bool GlWndProc(CDriverGL *driver)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
#elif defined (NL_OS_UNIX)
|
|
|
|
|
|
|
|
bool GlWndProc(CDriverGL *driver, XEvent &e)
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(GlWndProc)
|
|
|
|
|
|
|
|
if (!driver)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// nlinfo("3D: glop %d %d", e.type, e.xmap.window);
|
|
|
|
|
|
|
|
// disable menu (default ALT-F4 behavior is disabled)
|
|
|
|
switch(e.type)
|
|
|
|
{
|
|
|
|
case DestroyNotify:
|
|
|
|
|
|
|
|
if(driver && driver->ExitFunc)
|
|
|
|
{
|
|
|
|
driver->ExitFunc();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifndef NL_DISABLE_MENU
|
|
|
|
// if we don't disable menu, alt F4 make a direct exit else we discard the message
|
|
|
|
exit(0);
|
|
|
|
#endif // NL_DISABLE_MENU
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ConfigureNotify:
|
|
|
|
|
|
|
|
driver->_WindowWidth = e.xconfigure.width;
|
|
|
|
driver->_WindowHeight = e.xconfigure.height;
|
|
|
|
driver->_WindowX = e.xconfigure.x;
|
|
|
|
driver->_WindowY = e.xconfigure.y;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
// Process the message by the emitter
|
|
|
|
return driver->_EventEmitter.processMessage(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
/*
|
|
|
|
else if (message == WM_ACTIVATE)
|
|
|
|
{
|
|
|
|
WORD fActive = LOWORD(wParam);
|
|
|
|
if (fActive == WA_INACTIVE)
|
|
|
|
{
|
|
|
|
driver->_WndActive = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
driver->_WndActive = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // NL_OS_UNIX
|
2010-06-08 16:58:58 +00:00
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
bool CDriverGL::init (uint windowIcon, emptyProc exitFunc)
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_init)
|
|
|
|
|
|
|
|
ExitFunc = exitFunc;
|
|
|
|
|
|
|
|
#ifdef NL_OS_WINDOWS
|
|
|
|
WNDCLASSW wc;
|
|
|
|
|
|
|
|
if (!_Registered)
|
|
|
|
{
|
|
|
|
memset(&wc,0,sizeof(wc));
|
|
|
|
wc.style = CS_HREDRAW | CS_VREDRAW ;//| CS_DBLCLKS;
|
|
|
|
wc.lpfnWndProc = (WNDPROC)WndProc;
|
|
|
|
wc.cbClsExtra = 0;
|
|
|
|
wc.cbWndExtra = 0;
|
|
|
|
wc.hInstance = GetModuleHandle(NULL);
|
|
|
|
wc.hIcon = (HICON)windowIcon;
|
2010-06-12 13:34:20 +00:00
|
|
|
wc.hCursor = LoadCursorA(NULL, IDC_ARROW);
|
2010-06-08 16:58:58 +00:00
|
|
|
wc.hbrBackground = WHITE_BRUSH;
|
|
|
|
wc.lpszClassName = L"NLClass";
|
|
|
|
wc.lpszMenuName = NULL;
|
|
|
|
if ( !RegisterClassW(&wc) )
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
_Registered=1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Backup monitor color parameters
|
|
|
|
HDC dc = CreateDC ("DISPLAY", NULL, NULL, NULL);
|
|
|
|
if (dc)
|
|
|
|
{
|
|
|
|
_NeedToRestaureGammaRamp = GetDeviceGammaRamp (dc, _GammaRampBackuped) != FALSE;
|
|
|
|
|
|
|
|
// Release the DC
|
|
|
|
ReleaseDC (NULL, dc);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nlwarning ("(CDriverGL::init): can't create DC");
|
|
|
|
}
|
|
|
|
|
|
|
|
// ati specific : try to retrieve driver version
|
|
|
|
retrieveATIDriverVersion();
|
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
|
|
|
|
2010-06-23 21:37:19 +00:00
|
|
|
if(!NL3D::MAC::init(windowIcon, exitFunc))
|
|
|
|
{
|
|
|
|
nldebug("cannot init");
|
|
|
|
return false;
|
|
|
|
}
|
2010-06-08 16:58:58 +00:00
|
|
|
|
|
|
|
#elif defined (NL_OS_UNIX)
|
|
|
|
|
2010-06-12 13:34:20 +00:00
|
|
|
_dpy = XOpenDisplay(NULL);
|
|
|
|
|
|
|
|
if (_dpy == NULL)
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
|
|
|
nlerror ("XOpenDisplay failed on '%s'", getenv("DISPLAY"));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nldebug("3D: XOpenDisplay on '%s' OK", getenv("DISPLAY"));
|
|
|
|
}
|
|
|
|
|
2010-07-12 19:52:35 +00:00
|
|
|
_xrandr_version = 0;
|
|
|
|
|
|
|
|
#ifdef XRANDR
|
|
|
|
_OldSizeID = 0;
|
|
|
|
sint xrandr_major, xrandr_minor;
|
|
|
|
if (XRRQueryVersion(_dpy, &xrandr_major, &xrandr_minor))
|
|
|
|
{
|
|
|
|
_xrandr_version = xrandr_major * 100 + xrandr_minor;
|
|
|
|
nlinfo("3D: XRandR %d.%d found", xrandr_major, xrandr_minor);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
_xvidmode_version = 0;
|
|
|
|
|
|
|
|
#ifdef XF86VIDMODE
|
|
|
|
sint event = 0, error = -1, vm_major = 0, vm_minor = 0;
|
|
|
|
if (XF86VidModeQueryExtension(_dpy, &event, &error) && XF86VidModeQueryVersion(_dpy, &vm_major, &vm_minor))
|
|
|
|
{
|
|
|
|
_xvidmode_version = vm_major * 100 + vm_minor;
|
2010-07-12 21:02:55 +00:00
|
|
|
nlinfo("3D: XF86VidMode %d.%d found", vm_major, vm_minor);
|
2010-07-12 19:52:35 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#endif
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-06-12 20:22:32 +00:00
|
|
|
// ***************************************************************************
|
|
|
|
bool CDriverGL::unInit()
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
2010-06-12 20:22:32 +00:00
|
|
|
H_AUTO_OGL(CDriverGL_unInit)
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-06-12 20:22:32 +00:00
|
|
|
if (_FullScreen)
|
|
|
|
{
|
|
|
|
restoreScreenMode();
|
|
|
|
showCursor(true);
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-06-12 20:22:32 +00:00
|
|
|
_FullScreen = false;
|
|
|
|
}
|
2010-06-12 15:38:03 +00:00
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#ifdef NL_OS_WINDOWS
|
|
|
|
|
2010-06-12 20:22:32 +00:00
|
|
|
// Off-screen rendering ?
|
|
|
|
if (_PBuffer)
|
|
|
|
{
|
|
|
|
nwglReleasePbufferDCARB(_PBuffer, _hDC);
|
|
|
|
nwglDestroyPbufferARB(_PBuffer);
|
|
|
|
_PBuffer = NULL;
|
|
|
|
}
|
|
|
|
|
2010-06-13 16:01:03 +00:00
|
|
|
if (_Registered && !UnregisterClassW(L"NLClass", GetModuleHandle(NULL)))
|
|
|
|
{
|
2010-06-12 20:22:32 +00:00
|
|
|
nlwarning("Can't unregister NLClass");
|
2010-06-13 16:01:03 +00:00
|
|
|
}
|
2010-06-12 20:22:32 +00:00
|
|
|
|
|
|
|
// Restaure monitor color parameters
|
|
|
|
if (_NeedToRestaureGammaRamp)
|
|
|
|
{
|
|
|
|
HDC dc = CreateDC ("DISPLAY", NULL, NULL, NULL);
|
|
|
|
if (dc)
|
|
|
|
{
|
|
|
|
if (!SetDeviceGammaRamp (dc, _GammaRampBackuped))
|
|
|
|
nlwarning ("(CDriverGL::release): SetDeviceGammaRamp failed");
|
|
|
|
|
|
|
|
// Release the DC
|
|
|
|
ReleaseDC (NULL, dc);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nlwarning ("(CDriverGL::release): can't create DC");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
|
|
|
|
2010-06-23 21:37:19 +00:00
|
|
|
if(!NL3D::MAC::unInit())
|
|
|
|
{
|
|
|
|
nldebug("cannot uninit");
|
|
|
|
return false;
|
|
|
|
}
|
2010-06-12 20:22:32 +00:00
|
|
|
|
|
|
|
#elif defined (NL_OS_UNIX)
|
|
|
|
|
|
|
|
XCloseDisplay(_dpy);
|
|
|
|
_dpy = NULL;
|
|
|
|
|
|
|
|
#endif // NL_OS_UNIX
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-07-13 18:21:32 +00:00
|
|
|
void CDriverGL::setWindowIcon(const std::vector<NLMISC::CBitmap> &bitmaps)
|
|
|
|
{
|
2010-07-14 14:16:15 +00:00
|
|
|
if (_win == EmptyWindow)
|
|
|
|
return;
|
|
|
|
|
2010-07-13 18:21:32 +00:00
|
|
|
#if defined(NL_OS_WINDOWS)
|
|
|
|
|
2010-07-14 09:48:24 +00:00
|
|
|
static HICON winIconBig = NULL;
|
|
|
|
static HICON winIconSmall = NULL;
|
|
|
|
|
|
|
|
if (winIconBig)
|
|
|
|
{
|
|
|
|
DestroyIcon(winIconBig);
|
|
|
|
winIconBig = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (winIconSmall)
|
|
|
|
{
|
|
|
|
DestroyIcon(winIconSmall);
|
|
|
|
winIconSmall = NULL;
|
|
|
|
}
|
|
|
|
|
2010-07-14 14:16:15 +00:00
|
|
|
sint smallIndex = -1;
|
|
|
|
uint smallWidth = GetSystemMetrics(SM_CXSMICON);
|
|
|
|
uint smallHeight = GetSystemMetrics(SM_CYSMICON);
|
|
|
|
|
|
|
|
sint bigIndex = -1;
|
|
|
|
uint bigWidth = GetSystemMetrics(SM_CXICON);
|
|
|
|
uint bigHeight = GetSystemMetrics(SM_CYICON);
|
|
|
|
|
|
|
|
// find icons with the exact size
|
|
|
|
for(uint i = 0; i < bitmaps.size(); ++i)
|
|
|
|
{
|
|
|
|
if (smallIndex == -1 && bitmaps[i].getWidth() == smallWidth && bitmaps[i].getHeight() == smallHeight)
|
|
|
|
smallIndex = i;
|
|
|
|
|
|
|
|
if (bigIndex == -1 && bitmaps[i].getWidth() == bigWidth && bitmaps[i].getHeight() == bigHeight)
|
|
|
|
bigIndex = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
// find icons with taller size (we will resize them)
|
|
|
|
for(uint i = 0; i < bitmaps.size(); ++i)
|
|
|
|
{
|
|
|
|
if (smallIndex == -1 && bitmaps[i].getWidth() >= smallWidth && bitmaps[i].getHeight() >= smallHeight)
|
|
|
|
smallIndex = i;
|
|
|
|
|
|
|
|
if (bigIndex == -1 && bitmaps[i].getWidth() >= bigWidth && bitmaps[i].getHeight() >= bigHeight)
|
|
|
|
bigIndex = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (smallIndex > -1)
|
|
|
|
winIconSmall = bitmaps[smallIndex].getHICON(smallWidth, smallHeight, 32);
|
2010-07-14 09:48:24 +00:00
|
|
|
|
2010-07-14 14:16:15 +00:00
|
|
|
if (bigIndex > -1)
|
|
|
|
winIconBig = bitmaps[bigIndex].getHICON(bigWidth, bigHeight, 32);
|
2010-07-14 09:48:24 +00:00
|
|
|
|
|
|
|
if (winIconBig)
|
|
|
|
{
|
|
|
|
SendMessage(_win, WM_SETICON, 0 /* ICON_SMALL */, (LPARAM)winIconSmall);
|
|
|
|
SendMessage(_win, WM_SETICON, 1 /* ICON_BIG */, (LPARAM)winIconBig);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SendMessage(_win, WM_SETICON, 0 /* ICON_SMALL */, (LPARAM)winIconSmall);
|
|
|
|
SendMessage(_win, WM_SETICON, 1 /* ICON_BIG */, (LPARAM)winIconSmall);
|
|
|
|
}
|
2010-07-13 18:21:32 +00:00
|
|
|
|
|
|
|
#elif defined(NL_OS_MAC)
|
|
|
|
|
2010-07-14 14:16:15 +00:00
|
|
|
// nothing to do
|
2010-07-13 18:21:32 +00:00
|
|
|
|
|
|
|
#elif defined(NL_OS_UNIX)
|
|
|
|
|
|
|
|
std::vector<long> icon_data;
|
|
|
|
|
|
|
|
if (!bitmaps.empty())
|
|
|
|
{
|
|
|
|
// process each bitmap
|
|
|
|
for(uint i = 0; i < bitmaps.size(); ++i)
|
|
|
|
{
|
|
|
|
// get bitmap width and height
|
|
|
|
uint width = bitmaps[i].getWidth();
|
|
|
|
uint height = bitmaps[i].getHeight();
|
|
|
|
|
|
|
|
// icon_data position for bitmap
|
|
|
|
uint pos = (uint)icon_data.size();
|
|
|
|
|
|
|
|
// extend icon_data size for bitmap
|
|
|
|
icon_data.resize(pos + 2 + width*height);
|
|
|
|
|
|
|
|
// set bitmap width and height
|
|
|
|
icon_data[pos++] = width;
|
|
|
|
icon_data[pos++] = height;
|
|
|
|
|
|
|
|
// convert RGBA to ARGB
|
|
|
|
CObjectVector<uint8> pixels = bitmaps[i].getPixels();
|
|
|
|
for(uint j = 0; j < pixels.size(); j+=4)
|
|
|
|
icon_data[pos++] = pixels[j] << 16 | pixels[j+1] << 8 | pixels[j+2] | pixels[j+3] << 24;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Atom _NET_WM_ICON = XInternAtom(_dpy, "_NET_WM_ICON", False);
|
|
|
|
|
|
|
|
if (!icon_data.empty())
|
|
|
|
{
|
|
|
|
// change window icon
|
|
|
|
XChangeProperty(_dpy, _win, _NET_WM_ICON, XA_CARDINAL, 32, PropModeReplace, (const unsigned char *) &icon_data[0], icon_data.size());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// delete window icon if no bitmap is available
|
|
|
|
XDeleteProperty(_dpy, _win, _NET_WM_ICON);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // NL_OS_WINDOWS
|
|
|
|
}
|
|
|
|
|
2010-06-12 20:22:32 +00:00
|
|
|
// --------------------------------------------------
|
|
|
|
bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool resizeable) throw(EBadDisplay)
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_setDisplay)
|
|
|
|
|
|
|
|
_win = EmptyWindow;
|
|
|
|
_WindowWidth = _WindowHeight = _WindowX = _WindowY = 0;
|
|
|
|
_FullScreen = false;
|
|
|
|
_Resizable = resizeable;
|
2010-06-08 16:58:58 +00:00
|
|
|
_OffScreen = mode.OffScreen;
|
2010-06-12 20:22:32 +00:00
|
|
|
_DestroyWindow = false;
|
|
|
|
|
|
|
|
#ifdef NL_OS_WINDOWS
|
2010-06-08 16:58:58 +00:00
|
|
|
|
|
|
|
// Init pointers
|
|
|
|
_PBuffer = NULL;
|
|
|
|
_hRC = NULL;
|
|
|
|
_hDC = NULL;
|
|
|
|
|
2010-06-12 20:22:32 +00:00
|
|
|
// Driver caps.
|
|
|
|
//=============
|
|
|
|
// Retrieve the WGL extensions before init the driver.
|
|
|
|
int pf;
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
// Offscreen mode ?
|
|
|
|
if (_OffScreen)
|
|
|
|
{
|
2010-06-12 20:22:32 +00:00
|
|
|
#if 0
|
|
|
|
if (!createWindow(mode))
|
2010-06-08 16:58:58 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
// resize the window
|
|
|
|
RECT rc;
|
|
|
|
SetRect (&rc, 0, 0, width, height);
|
2010-06-12 20:22:32 +00:00
|
|
|
AdjustWindowRectEx (&rc, GetWindowStyle (_win), GetMenu (_win) != NULL, GetWindowExStyle (_win));
|
|
|
|
SetWindowPos (_win, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE );
|
2010-06-08 16:58:58 +00:00
|
|
|
|
|
|
|
// Get the
|
|
|
|
HDC tempHDC = GetDC(tmpHWND);
|
|
|
|
|
|
|
|
_Depth=uint8(GetDeviceCaps(tempHDC,BITSPIXEL));
|
|
|
|
|
|
|
|
// ---
|
|
|
|
memset(&_pfd,0,sizeof(_pfd));
|
|
|
|
_pfd.nSize = sizeof(_pfd);
|
|
|
|
_pfd.nVersion = 1;
|
|
|
|
_pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
|
|
|
_pfd.iPixelType = PFD_TYPE_RGBA;
|
|
|
|
_pfd.cColorBits = (char)_Depth;
|
|
|
|
|
|
|
|
// Choose best suited Depth Buffer.
|
|
|
|
if(_Depth<=16)
|
|
|
|
{
|
|
|
|
_pfd.cDepthBits = 16;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_pfd.cDepthBits = 24;
|
|
|
|
_pfd.cAlphaBits = 8;
|
|
|
|
}
|
|
|
|
_pfd.iLayerType = PFD_MAIN_PLANE;
|
|
|
|
pf=ChoosePixelFormat(tempHDC,&_pfd);
|
|
|
|
if (!pf)
|
|
|
|
{
|
|
|
|
nlwarning ("CDriverGL::setDisplay: ChoosePixelFormat failed");
|
|
|
|
DestroyWindow (tmpHWND);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if ( !SetPixelFormat(tempHDC,pf,&_pfd) )
|
|
|
|
{
|
|
|
|
nlwarning ("CDriverGL::setDisplay: SetPixelFormat failed");
|
|
|
|
DestroyWindow (tmpHWND);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create gl context
|
|
|
|
HGLRC tempGLRC = wglCreateContext(tempHDC);
|
|
|
|
if (tempGLRC == NULL)
|
|
|
|
{
|
|
|
|
DWORD error = GetLastError ();
|
|
|
|
nlwarning ("CDriverGL::setDisplay: wglCreateContext failed: 0x%x", error);
|
|
|
|
DestroyWindow (tmpHWND);
|
|
|
|
_PBuffer = NULL;
|
2010-06-12 20:22:32 +00:00
|
|
|
_win = EmptyWindow;
|
2010-06-08 16:58:58 +00:00
|
|
|
_hRC = NULL;
|
|
|
|
_hDC = NULL;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make the context current
|
|
|
|
if (!wglMakeCurrent(tempHDC,tempGLRC))
|
|
|
|
{
|
|
|
|
DWORD error = GetLastError ();
|
|
|
|
nlwarning ("CDriverGL::setDisplay: wglMakeCurrent failed: 0x%x", error);
|
|
|
|
wglDeleteContext (tempGLRC);
|
|
|
|
DestroyWindow (tmpHWND);
|
|
|
|
_PBuffer = NULL;
|
2010-06-12 20:22:32 +00:00
|
|
|
_win = EmptyWindow;
|
2010-06-08 16:58:58 +00:00
|
|
|
_hRC = NULL;
|
|
|
|
_hDC = NULL;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Register WGL functions
|
|
|
|
registerWGlExtensions (_Extensions, tempHDC);
|
|
|
|
|
|
|
|
HDC hdc = wglGetCurrentDC ();
|
|
|
|
|
|
|
|
if (hdc == NULL)
|
|
|
|
{
|
|
|
|
DWORD error = GetLastError ();
|
|
|
|
nlwarning ("CDriverGL::setDisplay: wglGetCurrentDC failed: 0x%x", error);
|
|
|
|
DestroyWindow (tmpHWND);
|
|
|
|
_PBuffer = NULL;
|
2010-06-12 20:22:32 +00:00
|
|
|
_win = EmptyWindow;
|
2010-06-08 16:58:58 +00:00
|
|
|
_hRC = NULL;
|
|
|
|
_hDC = NULL;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get ready to query for a suitable pixel format that meets our
|
|
|
|
// minimum requirements.
|
|
|
|
int iattributes[2*20];
|
|
|
|
float fattributes[2*20];
|
|
|
|
int niattribs = 0;
|
|
|
|
|
|
|
|
// Attribute arrays must be "0" terminated - for simplicity, first
|
|
|
|
// just zero-out the array then fill from left to right.
|
|
|
|
for ( int a = 0; a < 2*20; a++ )
|
|
|
|
{
|
|
|
|
iattributes[a] = 0;
|
|
|
|
fattributes[a] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Since we are trying to create a pbuffer, the pixel format we
|
|
|
|
// request (and subsequently use) must be "buffer capable".
|
|
|
|
iattributes[2*niattribs ] = WGL_DRAW_TO_PBUFFER_ARB;
|
|
|
|
iattributes[2*niattribs+1] = true;
|
|
|
|
niattribs++;
|
|
|
|
|
|
|
|
// We require a minimum of 24-bit depth.
|
|
|
|
iattributes[2*niattribs ] = WGL_DEPTH_BITS_ARB;
|
|
|
|
iattributes[2*niattribs+1] = 24;
|
|
|
|
niattribs++;
|
|
|
|
|
|
|
|
// We require a minimum of 8-bits for each R, G, B, and A.
|
|
|
|
iattributes[2*niattribs ] = WGL_RED_BITS_ARB;
|
|
|
|
iattributes[2*niattribs+1] = 8;
|
|
|
|
niattribs++;
|
|
|
|
iattributes[2*niattribs ] = WGL_GREEN_BITS_ARB;
|
|
|
|
iattributes[2*niattribs+1] = 8;
|
|
|
|
niattribs++;
|
|
|
|
iattributes[2*niattribs ] = WGL_BLUE_BITS_ARB;
|
|
|
|
iattributes[2*niattribs+1] = 8;
|
|
|
|
niattribs++;
|
|
|
|
iattributes[2*niattribs ] = WGL_ALPHA_BITS_ARB;
|
|
|
|
iattributes[2*niattribs+1] = 8;
|
|
|
|
niattribs++;
|
|
|
|
|
|
|
|
// Now obtain a list of pixel formats that meet these minimum
|
|
|
|
// requirements.
|
|
|
|
int pformat[20];
|
|
|
|
unsigned int nformats;
|
|
|
|
if ( !nwglChoosePixelFormatARB ( hdc, iattributes, fattributes,
|
|
|
|
20, pformat, &nformats ) )
|
|
|
|
{
|
|
|
|
nlwarning ( "pbuffer creation error: Couldn't find a suitable pixel format." );
|
|
|
|
wglDeleteContext (tempGLRC);
|
|
|
|
DestroyWindow (tmpHWND);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* After determining a compatible pixel format, the next step is to create a pbuffer of the
|
|
|
|
chosen format. Fortunately this step is fairly easy, as you merely select one of the formats
|
|
|
|
returned in the list in step #2 and call the function: */
|
|
|
|
int iattributes2[1] = {0};
|
|
|
|
// int iattributes2[] = {WGL_PBUFFER_LARGEST_ARB, 1, 0};
|
|
|
|
_PBuffer = nwglCreatePbufferARB( hdc, pformat[0], width, height, iattributes2 );
|
|
|
|
if (_PBuffer == NULL)
|
|
|
|
{
|
|
|
|
DWORD error = GetLastError ();
|
|
|
|
nlwarning ("CDriverGL::setDisplay: wglCreatePbufferARB failed: 0x%x", error);
|
|
|
|
wglDeleteContext (tempGLRC);
|
|
|
|
|
|
|
|
DestroyWindow (tmpHWND);
|
|
|
|
_PBuffer = NULL;
|
2010-06-12 20:22:32 +00:00
|
|
|
_win = EmptyWindow;
|
2010-06-08 16:58:58 +00:00
|
|
|
_hRC = NULL;
|
|
|
|
_hDC = NULL;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* After creating a pbuffer, you may use this functions to determine the dimensions of the pbuffer actually created. */
|
|
|
|
if ( !nwglQueryPbufferARB( _PBuffer, WGL_PBUFFER_WIDTH_ARB, (int*)&width ) )
|
|
|
|
{
|
|
|
|
DWORD error = GetLastError ();
|
|
|
|
nlwarning ("CDriverGL::setDisplay: wglQueryPbufferARB failed: 0x%x", error);
|
|
|
|
wglDeleteContext (tempGLRC);
|
|
|
|
DestroyWindow (tmpHWND);
|
|
|
|
_PBuffer = NULL;
|
2010-06-12 20:22:32 +00:00
|
|
|
_win = EmptyWindow;
|
2010-06-08 16:58:58 +00:00
|
|
|
_hRC = NULL;
|
|
|
|
_hDC = NULL;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !nwglQueryPbufferARB( _PBuffer, WGL_PBUFFER_HEIGHT_ARB, (int*)&height ) )
|
|
|
|
{
|
|
|
|
DWORD error = GetLastError ();
|
|
|
|
nlwarning ("CDriverGL::setDisplay: wglQueryPbufferARB failed: 0x%x", error);
|
|
|
|
wglDeleteContext (tempGLRC);
|
|
|
|
DestroyWindow (tmpHWND);
|
|
|
|
_PBuffer = NULL;
|
2010-06-12 20:22:32 +00:00
|
|
|
_win = EmptyWindow;
|
2010-06-08 16:58:58 +00:00
|
|
|
_hRC = NULL;
|
|
|
|
_hDC = NULL;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
_WindowWidth = width;
|
|
|
|
_WindowHeight = height;
|
|
|
|
|
|
|
|
/* The next step is to create a device context for the newly created pbuffer. To do this,
|
|
|
|
call the the function: */
|
|
|
|
_hDC = nwglGetPbufferDCARB( _PBuffer );
|
|
|
|
if (_hDC == NULL)
|
|
|
|
{
|
|
|
|
DWORD error = GetLastError ();
|
|
|
|
nlwarning ("CDriverGL::setDisplay: wglGetPbufferDCARB failed: 0x%x", error);
|
|
|
|
nwglDestroyPbufferARB( _PBuffer );
|
|
|
|
|
|
|
|
wglDeleteContext (tempGLRC);
|
|
|
|
|
|
|
|
DestroyWindow (tmpHWND);
|
|
|
|
_PBuffer = NULL;
|
2010-06-12 20:22:32 +00:00
|
|
|
_win = EmptyWindow;
|
2010-06-08 16:58:58 +00:00
|
|
|
_hRC = NULL;
|
|
|
|
_hDC = NULL;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The final step of pbuffer creation is to create an OpenGL rendering context and
|
|
|
|
associate it with the handle for the pbuffer's device context created in step #4. This is done as follows */
|
|
|
|
_hRC = wglCreateContext( _hDC );
|
|
|
|
if (_hRC == NULL)
|
|
|
|
{
|
|
|
|
DWORD error = GetLastError ();
|
|
|
|
nlwarning ("CDriverGL::setDisplay: wglCreateContext failed: 0x%x", error);
|
|
|
|
nwglReleasePbufferDCARB( _PBuffer, _hDC );
|
|
|
|
nwglDestroyPbufferARB( _PBuffer );
|
|
|
|
wglDeleteContext (tempGLRC);
|
|
|
|
DestroyWindow (tmpHWND);
|
|
|
|
_PBuffer = NULL;
|
2010-06-12 20:22:32 +00:00
|
|
|
_win = EmptyWindow;
|
2010-06-08 16:58:58 +00:00
|
|
|
_hRC = NULL;
|
|
|
|
_hDC = NULL;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the depth
|
|
|
|
_Depth = uint8(GetDeviceCaps (_hDC, BITSPIXEL));
|
|
|
|
|
|
|
|
// Destroy the temp gl context
|
|
|
|
if (!wglDeleteContext (tempGLRC))
|
|
|
|
{
|
|
|
|
DWORD error = GetLastError ();
|
|
|
|
nlwarning ("CDriverGL::setDisplay: wglDeleteContext failed: 0x%x", error);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Destroy the temp windows
|
|
|
|
if (!DestroyWindow (tmpHWND))
|
|
|
|
nlwarning ("CDriverGL::setDisplay: DestroyWindow failed");
|
|
|
|
|
|
|
|
/* After a pbuffer has been successfully created you can use it for off-screen rendering. To do
|
|
|
|
so, you'll first need to bind the pbuffer, or more precisely, make its GL rendering context
|
|
|
|
the current context that will interpret all OpenGL commands and state changes. */
|
|
|
|
if (!wglMakeCurrent(_hDC,_hRC))
|
|
|
|
{
|
|
|
|
DWORD error = GetLastError ();
|
|
|
|
nlwarning ("CDriverGL::setDisplay: wglMakeCurrent failed: 0x%x", error);
|
|
|
|
wglDeleteContext (_hRC);
|
|
|
|
nwglReleasePbufferDCARB( _PBuffer, _hDC );
|
|
|
|
nwglDestroyPbufferARB( _PBuffer );
|
|
|
|
DestroyWindow (tmpHWND);
|
|
|
|
_PBuffer = NULL;
|
2010-06-12 20:22:32 +00:00
|
|
|
_win = EmptyWindow;
|
2010-06-08 16:58:58 +00:00
|
|
|
_hRC = NULL;
|
|
|
|
_hDC = NULL;
|
|
|
|
return false;
|
|
|
|
}
|
2010-06-12 20:22:32 +00:00
|
|
|
#endif
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-06-12 20:22:32 +00:00
|
|
|
if (wnd == EmptyWindow)
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
2010-06-12 20:22:32 +00:00
|
|
|
if (!createWindow(mode))
|
|
|
|
return false;
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-06-12 20:22:32 +00:00
|
|
|
_win = wnd;
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
|
2010-06-13 16:01:03 +00:00
|
|
|
// associate OpenGL driver to window
|
|
|
|
SetWindowLongPtr(_win, GWLP_USERDATA, (LONG_PTR)this);
|
|
|
|
|
|
|
|
|
2010-06-12 20:22:32 +00:00
|
|
|
_hDC=GetDC(_win);
|
2010-06-08 16:58:58 +00:00
|
|
|
wglMakeCurrent(_hDC,NULL);
|
|
|
|
|
|
|
|
_Depth=uint8(GetDeviceCaps(_hDC,BITSPIXEL));
|
|
|
|
// ---
|
|
|
|
memset(&_pfd,0,sizeof(_pfd));
|
|
|
|
_pfd.nSize = sizeof(_pfd);
|
|
|
|
_pfd.nVersion = 1;
|
|
|
|
_pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
|
|
|
_pfd.iPixelType = PFD_TYPE_RGBA;
|
|
|
|
_pfd.cColorBits = (char)_Depth;
|
|
|
|
// Choose best suited Depth Buffer.
|
|
|
|
if(_Depth<=16)
|
|
|
|
{
|
|
|
|
_pfd.cDepthBits = 16;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_pfd.cDepthBits = 24;
|
|
|
|
_pfd.cAlphaBits = 8;
|
|
|
|
_pfd.cStencilBits = 8;
|
|
|
|
}
|
|
|
|
_pfd.iLayerType = PFD_MAIN_PLANE;
|
|
|
|
pf=ChoosePixelFormat(_hDC,&_pfd);
|
|
|
|
if (!pf)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !SetPixelFormat(_hDC,pf,&_pfd) )
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
_hRC=wglCreateContext(_hDC);
|
|
|
|
|
|
|
|
wglMakeCurrent(_hDC,_hRC);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/// release old emitter
|
|
|
|
while (_EventEmitter.getNumEmitters() != 0)
|
|
|
|
{
|
|
|
|
_EventEmitter.removeEmitter(_EventEmitter.getEmitter(_EventEmitter.getNumEmitters() - 1));
|
|
|
|
}
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
NLMISC::CWinEventEmitter *we = new NLMISC::CWinEventEmitter;
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
// setup the event emitter, and try to retrieve a direct input interface
|
|
|
|
_EventEmitter.addEmitter(we, true /*must delete*/); // the main emitter
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
/// try to get direct input
|
|
|
|
try
|
|
|
|
{
|
2010-06-12 20:22:32 +00:00
|
|
|
NLMISC::CDIEventEmitter *diee = NLMISC::CDIEventEmitter::create(GetModuleHandle(NULL), _win, we);
|
2010-06-08 16:58:58 +00:00
|
|
|
if (diee)
|
|
|
|
{
|
|
|
|
_EventEmitter.addEmitter(diee, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch(EDirectInput &e)
|
|
|
|
{
|
|
|
|
nlinfo(e.what());
|
|
|
|
}
|
|
|
|
|
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
|
|
|
|
2010-06-23 21:37:19 +00:00
|
|
|
_win = NL3D::MAC::setDisplay(wnd, mode, show, resizeable);
|
|
|
|
|
|
|
|
if(_win != EmptyWindow)
|
|
|
|
_DestroyWindow = true;
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-07-31 09:09:09 +00:00
|
|
|
#elif defined(NL_OS_UNIX)
|
2010-06-08 16:58:58 +00:00
|
|
|
|
|
|
|
static int sAttribList16bpp[] =
|
|
|
|
{
|
|
|
|
GLX_RGBA,
|
|
|
|
GLX_DOUBLEBUFFER,
|
|
|
|
GLX_DEPTH_SIZE, 16,
|
|
|
|
GLX_RED_SIZE, 4,
|
|
|
|
GLX_GREEN_SIZE, 4,
|
|
|
|
GLX_BLUE_SIZE, 4,
|
|
|
|
GLX_ALPHA_SIZE, 4,
|
|
|
|
GLX_STENCIL_SIZE, 8,
|
|
|
|
None
|
|
|
|
};
|
|
|
|
|
|
|
|
static int sAttribList24bpp[] =
|
|
|
|
{
|
|
|
|
GLX_RGBA,
|
|
|
|
GLX_DOUBLEBUFFER,
|
|
|
|
GLX_DEPTH_SIZE, 24,
|
|
|
|
GLX_RED_SIZE, 8,
|
|
|
|
GLX_GREEN_SIZE, 8,
|
|
|
|
GLX_BLUE_SIZE, 8,
|
|
|
|
GLX_ALPHA_SIZE, 8,
|
|
|
|
GLX_STENCIL_SIZE, 8,
|
|
|
|
None
|
|
|
|
};
|
|
|
|
|
|
|
|
// first try 24bpp and if that fails 16bpp
|
2010-06-12 13:34:20 +00:00
|
|
|
XVisualInfo *visual_info = glXChooseVisual (_dpy, DefaultScreen(_dpy), sAttribList24bpp);
|
2010-06-08 16:58:58 +00:00
|
|
|
if (visual_info == NULL)
|
2010-06-12 13:34:20 +00:00
|
|
|
visual_info = glXChooseVisual(_dpy, DefaultScreen(_dpy), sAttribList16bpp);
|
2010-06-08 16:58:58 +00:00
|
|
|
if(visual_info == NULL)
|
|
|
|
{
|
|
|
|
nlerror("glXChooseVisual() failed");
|
|
|
|
}
|
|
|
|
|
2010-06-13 16:01:03 +00:00
|
|
|
_visual_info = visual_info;
|
|
|
|
|
2010-06-12 13:34:20 +00:00
|
|
|
_ctx = glXCreateContext (_dpy, visual_info, None, GL_TRUE);
|
2010-06-12 20:22:32 +00:00
|
|
|
if (_ctx == NULL)
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
|
|
|
nlerror("glXCreateContext() failed");
|
|
|
|
}
|
|
|
|
|
2010-06-12 21:01:46 +00:00
|
|
|
if (wnd == EmptyWindow)
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
2010-06-12 20:22:32 +00:00
|
|
|
if (!createWindow(mode))
|
|
|
|
return false;
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-06-12 13:34:20 +00:00
|
|
|
_win = wnd;
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-06-12 20:22:32 +00:00
|
|
|
XSetWindowAttributes attr;
|
|
|
|
attr.background_pixel = BlackPixel(_dpy, DefaultScreen(_dpy));
|
|
|
|
attr.override_redirect = False;
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-06-12 20:22:32 +00:00
|
|
|
int attr_flags = CWOverrideRedirect | CWBackPixel;
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-06-12 20:22:32 +00:00
|
|
|
XChangeWindowAttributes(_dpy, _win, attr_flags, &attr);
|
|
|
|
}
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-06-12 13:34:20 +00:00
|
|
|
glXMakeCurrent (_dpy, _win, _ctx);
|
2010-06-14 19:54:58 +00:00
|
|
|
// XMapRaised (_dpy, _win);
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-06-12 20:22:32 +00:00
|
|
|
// XMapWindow(_dpy, _win);
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-07-24 21:09:43 +00:00
|
|
|
_EventEmitter.init (_dpy, _win, this);
|
2010-06-08 16:58:58 +00:00
|
|
|
|
|
|
|
// XEvent event;
|
|
|
|
// XIfEvent(dpy, &event, WaitForNotify, (char *)this);
|
|
|
|
|
2010-06-12 20:22:32 +00:00
|
|
|
#endif // NL_OS_UNIX
|
|
|
|
|
2010-06-14 19:54:58 +00:00
|
|
|
// setup OpenGL structures
|
2010-06-12 20:22:32 +00:00
|
|
|
if (!setupDisplay())
|
|
|
|
return false;
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-06-15 15:44:03 +00:00
|
|
|
// setup window size and screen mode
|
|
|
|
if (!setMode(mode))
|
|
|
|
return false;
|
2010-06-15 14:47:05 +00:00
|
|
|
|
2010-06-15 15:44:03 +00:00
|
|
|
if (show || _FullScreen)
|
|
|
|
showWindow(true);
|
2010-06-12 20:22:32 +00:00
|
|
|
|
|
|
|
return true;
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------
|
2010-06-12 13:34:20 +00:00
|
|
|
bool CDriverGL::saveScreenMode()
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
2010-06-12 13:34:20 +00:00
|
|
|
H_AUTO_OGL(CDriverGL_saveScreenMode)
|
|
|
|
|
|
|
|
bool res = true;
|
|
|
|
|
|
|
|
#if defined(NL_OS_WINDOWS)
|
|
|
|
|
|
|
|
// don't need to save it because Windows will use default desktop resolution
|
|
|
|
|
2010-06-23 21:37:19 +00:00
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
|
|
|
|
|
|
|
// no need to store because the screen mode is never really changed
|
|
|
|
|
2010-06-12 13:34:20 +00:00
|
|
|
#elif defined(NL_OS_UNIX)
|
|
|
|
|
2010-07-12 19:52:35 +00:00
|
|
|
int screen = DefaultScreen(_dpy);
|
|
|
|
res = false;
|
|
|
|
|
|
|
|
#ifdef XRANDR
|
|
|
|
|
|
|
|
if (!res && _xrandr_version > 0)
|
|
|
|
{
|
|
|
|
XRRScreenConfiguration *screen_config = XRRGetScreenInfo(_dpy, RootWindow(_dpy, screen));
|
|
|
|
|
|
|
|
if (screen_config)
|
|
|
|
{
|
|
|
|
Rotation saved_rotation;
|
|
|
|
_OldSizeID = XRRConfigCurrentConfiguration(screen_config, &saved_rotation);
|
|
|
|
nlinfo("3D: current XRandR mode %d", _OldSizeID);
|
|
|
|
XRRFreeScreenConfigInfo(screen_config);
|
|
|
|
|
|
|
|
res = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nlwarning("3D: XRRGetScreenInfo failed");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // XRANDR
|
|
|
|
|
2010-06-12 13:34:20 +00:00
|
|
|
#if defined(XF86VIDMODE)
|
|
|
|
|
2010-07-12 19:52:35 +00:00
|
|
|
if (!res && _xvidmode_version > 0)
|
|
|
|
{
|
|
|
|
// Store old mode in order to restore it when leaving fullscreen
|
|
|
|
memset(&_OldScreenMode, 0, sizeof(XF86VidModeModeLine));
|
|
|
|
XF86VidModeGetModeLine(_dpy, screen, &_OldDotClock, &_OldScreenMode);
|
|
|
|
res = XF86VidModeGetViewPort(_dpy, screen, &_OldX, &_OldY);
|
|
|
|
}
|
2010-06-12 13:34:20 +00:00
|
|
|
|
|
|
|
#endif // XF86VIDMODE
|
|
|
|
|
|
|
|
#endif // NL_OS_WINDOWS
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------
|
|
|
|
bool CDriverGL::restoreScreenMode()
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_restoreScreenMode)
|
|
|
|
|
|
|
|
bool res = false;
|
|
|
|
|
|
|
|
#if defined(NL_OS_WINDOWS)
|
|
|
|
|
|
|
|
res = (ChangeDisplaySettings(NULL, 0) == DISP_CHANGE_SUCCESSFUL);
|
|
|
|
|
2010-06-23 21:37:19 +00:00
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
|
|
|
|
|
|
|
// no need to restore because the screen mode was never really changed
|
|
|
|
res = true;
|
|
|
|
|
2010-06-12 13:34:20 +00:00
|
|
|
#elif defined(NL_OS_UNIX)
|
|
|
|
|
2010-07-12 19:52:35 +00:00
|
|
|
int screen = DefaultScreen(_dpy);
|
|
|
|
|
|
|
|
#ifdef XRANDR
|
|
|
|
|
|
|
|
if (!res && _xrandr_version > 0)
|
|
|
|
{
|
|
|
|
Window root = RootWindow(_dpy, screen);
|
|
|
|
|
|
|
|
XRRScreenConfiguration *screen_config = XRRGetScreenInfo(_dpy, root);
|
|
|
|
|
|
|
|
if (screen_config)
|
|
|
|
{
|
|
|
|
Rotation saved_rotation;
|
|
|
|
SizeID size = XRRConfigCurrentConfiguration(screen_config, &saved_rotation);
|
|
|
|
if (XRRSetScreenConfig(_dpy, screen_config, root, _OldSizeID, saved_rotation, CurrentTime) == RRSetConfigSuccess)
|
|
|
|
{
|
|
|
|
nlinfo("3D: Switching back to XRandR mode %d", _OldSizeID);
|
|
|
|
res = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
XRRFreeScreenConfigInfo(screen_config);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nlwarning("3D: XRRGetScreenInfo failed");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // XRANDR
|
|
|
|
|
2010-06-12 13:34:20 +00:00
|
|
|
#if defined(XF86VIDMODE)
|
|
|
|
|
2010-07-12 19:52:35 +00:00
|
|
|
if (!res && _xvidmode_version > 0)
|
|
|
|
{
|
|
|
|
XF86VidModeModeInfo info;
|
|
|
|
nlinfo("3D: Switching back to original mode");
|
|
|
|
|
|
|
|
// This is UGLY
|
|
|
|
info.dotclock = _OldDotClock;
|
|
|
|
info.hdisplay = _OldScreenMode.hdisplay;
|
|
|
|
info.hsyncstart = _OldScreenMode.hsyncstart;
|
|
|
|
info.hsyncend = _OldScreenMode.hsyncend;
|
|
|
|
info.htotal = _OldScreenMode.htotal;
|
|
|
|
info.vdisplay = _OldScreenMode.vdisplay;
|
|
|
|
info.vsyncstart = _OldScreenMode.vsyncstart;
|
|
|
|
info.vsyncend = _OldScreenMode.vsyncend;
|
|
|
|
info.vtotal = _OldScreenMode.vtotal;
|
|
|
|
info.flags = _OldScreenMode.flags;
|
|
|
|
info.privsize = _OldScreenMode.privsize;
|
|
|
|
info.c_private = _OldScreenMode.c_private;
|
|
|
|
|
|
|
|
nlinfo("3D: Switching back mode to %dx%d", info.hdisplay, info.vdisplay);
|
|
|
|
XF86VidModeSwitchToMode(_dpy, screen, &info);
|
|
|
|
nlinfo("3D: Switching back viewport to %d,%d",_OldX, _OldY);
|
|
|
|
res = XF86VidModeSetViewPort(_dpy, screen, _OldX, _OldY);
|
|
|
|
}
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#endif // XF86VIDMODE
|
|
|
|
|
2010-06-12 13:34:20 +00:00
|
|
|
#endif // NL_OS_WINDOWS
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-07-12 19:52:35 +00:00
|
|
|
// --------------------------------------------------
|
|
|
|
#ifdef XF86VIDMODE
|
|
|
|
static sint modeInfoToFrequency(XF86VidModeModeInfo *info)
|
|
|
|
{
|
|
|
|
return (info->htotal && info->vtotal) ? (1000 * info->dotclock / (info->htotal * info->vtotal)) : 0;
|
|
|
|
}
|
|
|
|
#endif // XF86VIDMODE
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
// --------------------------------------------------
|
2010-06-12 15:38:03 +00:00
|
|
|
bool CDriverGL::setScreenMode(const GfxMode &mode)
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
2010-06-12 15:38:03 +00:00
|
|
|
H_AUTO_OGL(CDriverGL_setScreenMode)
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
if (mode.Windowed)
|
|
|
|
{
|
2010-06-12 15:38:03 +00:00
|
|
|
// if fullscreen, switch back to desktop screen mode
|
2010-06-08 16:58:58 +00:00
|
|
|
if (_FullScreen)
|
2010-06-12 13:34:20 +00:00
|
|
|
restoreScreenMode();
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-06-12 15:38:03 +00:00
|
|
|
return true;
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
2010-06-12 15:38:03 +00:00
|
|
|
|
|
|
|
// save previous screen mode only if switching from windowed to fullscreen
|
|
|
|
if (!_FullScreen)
|
|
|
|
saveScreenMode();
|
|
|
|
|
|
|
|
// if switching exactly to the same screen mode, doesn't change it
|
|
|
|
GfxMode previousMode;
|
|
|
|
if (getCurrentScreenMode(previousMode)
|
|
|
|
&& mode.Width == previousMode.Width
|
|
|
|
&& mode.Height == previousMode.Height
|
|
|
|
&& mode.Depth == previousMode.Depth
|
|
|
|
&& mode.Frequency == previousMode.Frequency)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
#if defined(NL_OS_WINDOWS)
|
|
|
|
|
|
|
|
DEVMODE devMode;
|
|
|
|
memset(&devMode, 0, sizeof(DEVMODE));
|
|
|
|
devMode.dmSize = sizeof(DEVMODE);
|
|
|
|
devMode.dmDriverExtra = 0;
|
|
|
|
devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
|
|
|
|
devMode.dmPelsWidth = mode.Width;
|
|
|
|
devMode.dmPelsHeight = mode.Height;
|
|
|
|
|
|
|
|
if(mode.Depth > 0)
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
2010-06-12 15:38:03 +00:00
|
|
|
devMode.dmBitsPerPel = mode.Depth;
|
|
|
|
devMode.dmFields |= DM_BITSPERPEL;
|
|
|
|
}
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-06-12 15:38:03 +00:00
|
|
|
if(mode.Frequency > 0)
|
|
|
|
{
|
|
|
|
devMode.dmDisplayFrequency = mode.Frequency;
|
|
|
|
devMode.dmFields |= DM_DISPLAYFREQUENCY;
|
|
|
|
}
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-06-12 15:38:03 +00:00
|
|
|
if (ChangeDisplaySettings(&devMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
|
|
|
|
{
|
2010-07-13 18:21:32 +00:00
|
|
|
nlwarning("3D: Fullscreen mode switch failed");
|
2010-06-12 15:38:03 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-06-23 21:37:19 +00:00
|
|
|
// no need to do anything here, on mac os, the screen mode is never changed
|
2010-06-12 15:38:03 +00:00
|
|
|
|
|
|
|
#elif defined(NL_OS_UNIX)
|
|
|
|
|
|
|
|
bool found = false;
|
|
|
|
|
2010-07-12 19:52:35 +00:00
|
|
|
#ifdef XRANDR
|
|
|
|
|
|
|
|
if (!found && _xrandr_version > 0)
|
2010-06-12 15:38:03 +00:00
|
|
|
{
|
2010-07-12 19:52:35 +00:00
|
|
|
int screen = DefaultScreen(_dpy);
|
|
|
|
Window root = RootWindow(_dpy, screen);
|
|
|
|
|
|
|
|
XRRScreenConfiguration *screen_config = XRRGetScreenInfo(_dpy, root);
|
|
|
|
|
|
|
|
if (screen_config)
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
2010-07-12 19:52:35 +00:00
|
|
|
Rotation saved_rotation;
|
2010-07-12 21:02:55 +00:00
|
|
|
SizeID cur_size = XRRConfigCurrentConfiguration(screen_config, &saved_rotation);
|
2010-07-12 19:52:35 +00:00
|
|
|
|
|
|
|
sint nsizes;
|
|
|
|
XRRScreenSize *sizes = XRRConfigSizes(screen_config, &nsizes);
|
|
|
|
sint size = -1;
|
|
|
|
|
|
|
|
for (sint i = 0; i < nsizes; ++i)
|
2010-06-12 15:38:03 +00:00
|
|
|
{
|
2010-07-12 19:52:35 +00:00
|
|
|
if (sizes[i].width == mode.Width && sizes[i].height == mode.Height)
|
2010-06-12 15:38:03 +00:00
|
|
|
{
|
2010-07-12 19:52:35 +00:00
|
|
|
size = i;
|
|
|
|
break;
|
2010-06-12 15:38:03 +00:00
|
|
|
}
|
|
|
|
}
|
2010-07-12 19:52:35 +00:00
|
|
|
|
|
|
|
if (size > -1 && XRRSetScreenConfig(_dpy, screen_config, root, size, saved_rotation, CurrentTime) == RRSetConfigSuccess)
|
|
|
|
{
|
|
|
|
nlinfo("3D: Switching to XRandR mode %d: %dx%d", size, sizes[size].width, sizes[size].height);
|
|
|
|
found = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nlwarning("3D: No corresponding screen mode or XRRSetScreenConfig failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
XRRFreeScreenConfigInfo(screen_config);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nlwarning("3D: XRRGetScreenInfo failed");
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
2010-06-12 15:38:03 +00:00
|
|
|
}
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-07-12 19:52:35 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(XF86VIDMODE)
|
|
|
|
|
|
|
|
if (!found && _xvidmode_version > 0)
|
|
|
|
{
|
|
|
|
// Find the requested mode and use it
|
|
|
|
XF86VidModeModeInfo **modes;
|
|
|
|
int nmodes;
|
|
|
|
if (XF86VidModeGetAllModeLines(_dpy, DefaultScreen(_dpy), &nmodes, &modes))
|
|
|
|
{
|
|
|
|
for (int i = 0; i < nmodes; i++)
|
|
|
|
{
|
|
|
|
const uint16 freq = modeInfoToFrequency(modes[i]);
|
|
|
|
|
|
|
|
nldebug("3D: Available mode - %dx%d %d Hz", modes[i]->hdisplay, modes[i]->vdisplay, (int)freq);
|
|
|
|
if (modes[i]->hdisplay == mode.Width && modes[i]->vdisplay == mode.Height /* && freq == mode.Frequency */)
|
|
|
|
{
|
|
|
|
if (XF86VidModeSwitchToMode(_dpy, DefaultScreen(_dpy), modes[i]))
|
|
|
|
{
|
|
|
|
nlinfo("3D: XF86VidMode Switching to mode %dx%d", modes[i]->hdisplay, modes[i]->vdisplay);
|
|
|
|
XF86VidModeSetViewPort(_dpy, DefaultScreen(_dpy), 0, 0);
|
|
|
|
found = true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
XFree(modes);
|
|
|
|
}
|
|
|
|
}
|
2010-06-12 15:38:03 +00:00
|
|
|
|
|
|
|
#endif // XF86VIDMODE
|
|
|
|
|
2010-07-12 19:52:35 +00:00
|
|
|
if (!found)
|
|
|
|
return false;
|
|
|
|
|
2010-06-12 15:38:03 +00:00
|
|
|
#endif // NL_OS_WINDOWS
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-06-12 20:22:32 +00:00
|
|
|
// ***************************************************************************
|
|
|
|
bool CDriverGL::createWindow(const GfxMode &mode)
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_createWindow)
|
|
|
|
|
|
|
|
nlWindow window = EmptyWindow;
|
|
|
|
|
|
|
|
#ifdef NL_OS_WINDOWS
|
|
|
|
|
|
|
|
// create the OpenGL window
|
|
|
|
window = CreateWindowW(L"NLClass", L"NeL Window", WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
|
|
|
|
CW_USEDEFAULT, CW_USEDEFAULT, mode.Width, mode.Height, HWND_DESKTOP, NULL, GetModuleHandle(NULL), NULL);
|
|
|
|
|
|
|
|
if (window == EmptyWindow)
|
|
|
|
{
|
|
|
|
DWORD res = GetLastError();
|
|
|
|
nlwarning("CreateWindow failed: %u", res);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
|
|
|
|
2010-06-23 21:37:19 +00:00
|
|
|
window = NL3D::MAC::createWindow(mode);
|
|
|
|
|
|
|
|
if(window == EmptyWindow)
|
|
|
|
{
|
|
|
|
nldebug("cannot create window");
|
|
|
|
return false;
|
|
|
|
}
|
2010-06-12 20:22:32 +00:00
|
|
|
|
|
|
|
#elif defined (NL_OS_UNIX)
|
|
|
|
|
2010-06-12 21:01:46 +00:00
|
|
|
if (_visual_info == NULL)
|
|
|
|
return false;
|
|
|
|
|
2010-06-13 16:01:03 +00:00
|
|
|
nlWindow root = RootWindow(_dpy, DefaultScreen(_dpy));
|
|
|
|
|
2010-06-12 20:22:32 +00:00
|
|
|
XSetWindowAttributes attr;
|
|
|
|
attr.background_pixel = BlackPixel(_dpy, DefaultScreen(_dpy));
|
2010-06-13 16:01:03 +00:00
|
|
|
attr.colormap = XCreateColormap(_dpy, root, _visual_info->visual, AllocNone);
|
2010-06-15 14:47:05 +00:00
|
|
|
int attr_flags = CWBackPixel | CWColormap;
|
2010-06-12 20:22:32 +00:00
|
|
|
|
2010-06-12 21:01:46 +00:00
|
|
|
window = XCreateWindow (_dpy, root, 0, 0, mode.Width, mode.Height, 0, _visual_info->depth, InputOutput, _visual_info->visual, attr_flags, &attr);
|
2010-06-12 20:22:32 +00:00
|
|
|
|
|
|
|
if (window == EmptyWindow)
|
|
|
|
{
|
|
|
|
nlerror("3D: XCreateWindow() failed");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // NL_OS_UNIX
|
|
|
|
|
|
|
|
_win = window;
|
|
|
|
|
|
|
|
_WindowWidth = mode.Width;
|
|
|
|
_WindowHeight = mode.Height;
|
|
|
|
|
|
|
|
// Must destroy this window
|
|
|
|
_DestroyWindow = true;
|
|
|
|
|
|
|
|
setWindowTitle(ucstring("NeL window"));
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
bool CDriverGL::destroyWindow()
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_destroyWindow)
|
|
|
|
|
2010-07-14 09:48:24 +00:00
|
|
|
// make sure window icons are deleted
|
|
|
|
std::vector<NLMISC::CBitmap> bitmaps;
|
|
|
|
setWindowIcon(bitmaps);
|
|
|
|
|
2010-06-12 20:22:32 +00:00
|
|
|
#ifdef NL_OS_WINDOWS
|
|
|
|
|
|
|
|
// Then delete.
|
|
|
|
// wglMakeCurrent(NULL,NULL);
|
|
|
|
|
|
|
|
if (_hDC)
|
|
|
|
wglMakeCurrent(_hDC, NULL);
|
|
|
|
|
2010-06-15 15:44:03 +00:00
|
|
|
if (_DestroyWindow && _hRC)
|
2010-06-12 20:22:32 +00:00
|
|
|
{
|
|
|
|
wglDeleteContext(_hRC);
|
|
|
|
_hRC = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_win && _hDC)
|
|
|
|
{
|
|
|
|
ReleaseDC(_win, _hDC);
|
|
|
|
_hDC = NULL;
|
|
|
|
|
2010-06-14 19:54:58 +00:00
|
|
|
// don't destroy window if it hasn't been created by our driver
|
2010-06-12 20:22:32 +00:00
|
|
|
if (_DestroyWindow)
|
|
|
|
DestroyWindow(_win);
|
|
|
|
}
|
|
|
|
|
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
|
|
|
|
2010-06-23 21:37:19 +00:00
|
|
|
if(_DestroyWindow)
|
|
|
|
{
|
|
|
|
if(!NL3D::MAC::destroyWindow(_win))
|
|
|
|
{
|
|
|
|
nldebug("cannot destroy window");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2010-06-12 20:22:32 +00:00
|
|
|
|
|
|
|
#elif defined (NL_OS_UNIX)
|
|
|
|
|
2010-06-15 15:44:03 +00:00
|
|
|
if (_DestroyWindow)
|
2010-06-12 20:22:32 +00:00
|
|
|
{
|
2010-06-15 15:44:03 +00:00
|
|
|
if (_ctx)
|
|
|
|
glXDestroyContext(_dpy, _ctx);
|
|
|
|
|
|
|
|
if (_win)
|
|
|
|
XDestroyWindow(_dpy, _win);
|
2010-06-12 20:22:32 +00:00
|
|
|
}
|
|
|
|
|
2010-06-15 15:44:03 +00:00
|
|
|
_ctx = NULL;
|
2010-06-12 20:22:32 +00:00
|
|
|
|
|
|
|
// Ungrab the keyboard (probably not necessary);
|
|
|
|
// XUnmapWindow(_dpy, _win);
|
|
|
|
XSync(_dpy, True);
|
|
|
|
XUngrabKeyboard(_dpy, CurrentTime);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
_win = EmptyWindow;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-06-14 19:54:58 +00:00
|
|
|
CDriverGL::EWindowStyle CDriverGL::getWindowStyle() const
|
2010-06-12 15:38:03 +00:00
|
|
|
{
|
2010-06-14 19:54:58 +00:00
|
|
|
H_AUTO_OGL(CDriverGL_getWindowStyle)
|
2010-06-12 15:38:03 +00:00
|
|
|
|
2010-06-14 19:54:58 +00:00
|
|
|
if (_FullScreen)
|
|
|
|
return EWSFullscreen;
|
2010-06-12 15:38:03 +00:00
|
|
|
|
2010-06-14 19:54:58 +00:00
|
|
|
return EWSWindowed;
|
|
|
|
}
|
2010-06-12 20:22:32 +00:00
|
|
|
|
2010-06-14 19:54:58 +00:00
|
|
|
bool CDriverGL::setWindowStyle(EWindowStyle windowStyle)
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_setWindowStyle)
|
2010-06-12 15:38:03 +00:00
|
|
|
|
2010-06-15 15:44:03 +00:00
|
|
|
// don't change window style, if we did not create the window
|
2010-07-24 21:09:43 +00:00
|
|
|
if (_win == EmptyWindow || !_DestroyWindow)
|
2010-06-15 15:44:03 +00:00
|
|
|
return true;
|
|
|
|
|
2010-06-14 19:54:58 +00:00
|
|
|
#if defined(NL_OS_WINDOWS)
|
|
|
|
|
|
|
|
// get current style
|
|
|
|
LONG dwStyle = GetWindowLong(_win, GWL_STYLE);
|
|
|
|
|
|
|
|
// prepare new style
|
|
|
|
LONG dwNewStyle = WS_CLIPCHILDREN|WS_CLIPSIBLINGS;
|
|
|
|
|
|
|
|
// get window current state
|
|
|
|
WINDOWPLACEMENT wndpl;
|
|
|
|
wndpl.length = sizeof(WINDOWPLACEMENT);
|
|
|
|
|
|
|
|
bool isMaximized = GetWindowPlacement(_win, &wndpl) && (wndpl.showCmd == SW_SHOWMAXIMIZED);
|
|
|
|
bool isVisible = false;
|
|
|
|
|
|
|
|
if (windowStyle == EWSWindowed && !_OffScreen)
|
2010-06-12 15:38:03 +00:00
|
|
|
{
|
2010-06-14 19:54:58 +00:00
|
|
|
dwNewStyle |= WS_OVERLAPPEDWINDOW;
|
|
|
|
|
|
|
|
// if we can't resize window, remove maximize box and resize anchors
|
|
|
|
if (!_Resizable) dwNewStyle ^= WS_MAXIMIZEBOX|WS_THICKFRAME;
|
|
|
|
|
|
|
|
isVisible = (dwStyle & WS_VISIBLE) != 0;
|
2010-06-12 15:38:03 +00:00
|
|
|
}
|
2010-06-14 19:54:58 +00:00
|
|
|
else if (windowStyle == EWSFullscreen)
|
2010-06-12 15:38:03 +00:00
|
|
|
{
|
2010-06-14 19:54:58 +00:00
|
|
|
dwNewStyle |= WS_POPUP;
|
|
|
|
isVisible = true;
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
|
2010-06-14 19:54:58 +00:00
|
|
|
if (isVisible)
|
|
|
|
dwNewStyle |= WS_VISIBLE;
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-06-14 19:54:58 +00:00
|
|
|
if (dwStyle != dwNewStyle)
|
|
|
|
SetWindowLong(_win, GWL_STYLE, dwNewStyle);
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-06-14 19:54:58 +00:00
|
|
|
// if (windowStyle == EWSMaximized && isVisible && !isMaximized)
|
|
|
|
// ShowWindow(_hWnd, SW_SHOWMAXIMIZED);
|
|
|
|
// else if (isMaximized && isVisible)
|
|
|
|
// ShowWindow(_hWnd, SW_RESTORE);
|
2010-06-11 15:12:19 +00:00
|
|
|
|
2010-06-23 21:37:19 +00:00
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
|
|
|
|
|
|
|
if(!NL3D::MAC::setWindowStyle(_win, windowStyle == EWSFullscreen))
|
|
|
|
{
|
|
|
|
nldebug("cannot set window style");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-06-14 19:54:58 +00:00
|
|
|
#elif defined(NL_OS_UNIX)
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-06-11 15:12:19 +00:00
|
|
|
// x11 fullscreen is not working on mac os x
|
2010-07-12 19:52:35 +00:00
|
|
|
|
2010-06-11 15:12:19 +00:00
|
|
|
#if !defined(NL_OS_MAC)
|
2010-07-12 19:52:35 +00:00
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
// Toggle fullscreen
|
2010-07-24 21:09:43 +00:00
|
|
|
XEvent xev;
|
|
|
|
xev.xclient.type = ClientMessage;
|
|
|
|
xev.xclient.serial = 0;
|
|
|
|
xev.xclient.send_event = True;
|
|
|
|
xev.xclient.display = _dpy;
|
|
|
|
xev.xclient.window = _win;
|
|
|
|
xev.xclient.message_type = XInternAtom(_dpy, "_NET_WM_STATE", False);
|
|
|
|
xev.xclient.format = 32;
|
|
|
|
xev.xclient.data.l[0] = windowStyle == EWSFullscreen ? _NET_WM_STATE_ADD:_NET_WM_STATE_REMOVE;
|
|
|
|
xev.xclient.data.l[1] = XInternAtom(_dpy, "_NET_WM_STATE_FULLSCREEN", False);
|
|
|
|
xev.xclient.data.l[2] = 0;
|
|
|
|
xev.xclient.data.l[3] = 1; // 1 for Application, 2 for Page or Taskbar, 0 for old source
|
|
|
|
xev.xclient.data.l[4] = 0;
|
2010-07-31 09:09:09 +00:00
|
|
|
if (!XSendEvent(_dpy, DefaultRootWindow(_dpy), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev))
|
2010-07-24 21:09:43 +00:00
|
|
|
{
|
|
|
|
nlwarning("3D: Failed to toggle to fullscreen");
|
|
|
|
return false;
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
2010-06-14 19:54:58 +00:00
|
|
|
|
2010-06-11 15:12:19 +00:00
|
|
|
#endif
|
|
|
|
|
2010-06-14 19:54:58 +00:00
|
|
|
#endif // NL_OS_WINDOWS
|
2010-06-12 20:22:32 +00:00
|
|
|
|
2010-06-14 19:54:58 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------
|
|
|
|
bool CDriverGL::setMode(const GfxMode& mode)
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_setMode)
|
|
|
|
|
|
|
|
if (!setScreenMode(mode))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// when changing window style, it's possible system change window size too
|
2010-07-24 21:09:43 +00:00
|
|
|
setWindowStyle(mode.Windowed ? EWSWindowed:EWSFullscreen);
|
2010-06-14 19:54:58 +00:00
|
|
|
|
|
|
|
_WindowWidth = mode.Width;
|
|
|
|
_WindowHeight = mode.Height;
|
|
|
|
|
|
|
|
if (!mode.Windowed)
|
|
|
|
_Depth = mode.Depth;
|
2010-06-12 20:22:32 +00:00
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
_FullScreen = !mode.Windowed;
|
2010-06-14 19:54:58 +00:00
|
|
|
|
2010-06-23 21:37:19 +00:00
|
|
|
#if defined(NL_OS_MAC) && !defined(NL_MAC_NATIVE)
|
2010-06-14 19:54:58 +00:00
|
|
|
// X11 under Mac OS can't use fullscreen
|
2010-06-11 15:12:19 +00:00
|
|
|
_FullScreen = false;
|
2010-06-14 19:54:58 +00:00
|
|
|
#endif // NL_MAC_NATIVE
|
|
|
|
|
2010-06-13 19:00:19 +00:00
|
|
|
setWindowSize(mode.Width, mode.Height);
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------
|
|
|
|
bool CDriverGL::getModes(std::vector<GfxMode> &modes)
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_getModes)
|
2010-07-24 21:09:43 +00:00
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#ifdef NL_OS_WINDOWS
|
|
|
|
sint modeIndex = 0;
|
|
|
|
DEVMODE devMode;
|
|
|
|
while (EnumDisplaySettings (NULL, modeIndex, &devMode))
|
|
|
|
{
|
|
|
|
// Keep only 16 and 32 bits
|
|
|
|
if ((devMode.dmBitsPerPel == 16 ) || (devMode.dmBitsPerPel == 32))
|
|
|
|
{
|
|
|
|
// Add this mode
|
|
|
|
GfxMode mode;
|
|
|
|
mode.Width = (uint16)devMode.dmPelsWidth;
|
|
|
|
mode.Height = (uint16)devMode.dmPelsHeight;
|
|
|
|
mode.Depth = (uint8)devMode.dmBitsPerPel;
|
|
|
|
mode.Frequency = devMode.dmDisplayFrequency;
|
|
|
|
modes.push_back (mode);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Mode index
|
|
|
|
modeIndex++;
|
|
|
|
}
|
|
|
|
#elif defined(NL_OS_MAC)
|
|
|
|
getMacModes(modes);
|
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
|
|
|
# warning "OpenGL Driver: Missing Mac Implementation"
|
|
|
|
nlwarning("OpenGL Driver: Missing Mac Implementation");
|
|
|
|
|
|
|
|
#elif defined (NL_OS_UNIX)
|
|
|
|
|
2010-07-12 19:52:35 +00:00
|
|
|
bool found = false;
|
|
|
|
int screen = DefaultScreen(_dpy);
|
|
|
|
|
|
|
|
#if defined(XRANDR)
|
|
|
|
if (!found && _xrandr_version >= 100)
|
|
|
|
{
|
|
|
|
XRRScreenConfiguration *screen_config = XRRGetScreenInfo(_dpy, RootWindow(_dpy, screen));
|
|
|
|
|
|
|
|
if (screen_config)
|
|
|
|
{
|
|
|
|
// retrieve the list of resolutions
|
|
|
|
int nsizes = 0;
|
|
|
|
XRRScreenSize *sizes = XRRConfigSizes(screen_config, &nsizes);
|
|
|
|
|
|
|
|
if (nsizes > 0)
|
|
|
|
{
|
|
|
|
nldebug("3D: %d available XRandR modes:", nsizes);
|
|
|
|
|
|
|
|
for (sint i = 0; i < nsizes; ++i)
|
|
|
|
{
|
|
|
|
// Add this mode
|
|
|
|
GfxMode mode;
|
|
|
|
mode.Width = sizes[i].width;
|
|
|
|
mode.Height = sizes[i].height;
|
|
|
|
mode.Frequency = 0;
|
|
|
|
modes.push_back(mode);
|
|
|
|
|
|
|
|
nldebug("3D: Mode %d: %dx%d", i, mode.Width, mode.Height);
|
|
|
|
}
|
|
|
|
|
|
|
|
found = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nlwarning("3D: No XRandR modes available");
|
|
|
|
}
|
|
|
|
|
|
|
|
XRRFreeScreenConfigInfo(screen_config);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nlwarning("3D: XRRGetScreenInfo failed");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef XF86VIDMODE
|
2010-06-08 16:58:58 +00:00
|
|
|
int nmodes;
|
|
|
|
XF86VidModeModeInfo **ms;
|
2010-07-12 19:52:35 +00:00
|
|
|
if (!found && XF86VidModeGetAllModeLines(_dpy, screen, &nmodes, &ms))
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
2010-07-12 19:52:35 +00:00
|
|
|
nlinfo("3D: %d available XF86VidMode modes:", nmodes);
|
2010-06-08 16:58:58 +00:00
|
|
|
for (int j = 0; j < nmodes; j++)
|
|
|
|
{
|
|
|
|
// Add this mode
|
|
|
|
GfxMode mode;
|
|
|
|
mode.Width = (uint16)ms[j]->hdisplay;
|
|
|
|
mode.Height = (uint16)ms[j]->vdisplay;
|
2010-07-12 19:52:35 +00:00
|
|
|
mode.Frequency = modeInfoToFrequency(ms[j]);
|
|
|
|
nlinfo("3D: Mode %d: %dx%d, %d Hz", j, mode.Width, mode.Height, mode.Frequency);
|
2010-06-08 16:58:58 +00:00
|
|
|
modes.push_back (mode);
|
|
|
|
}
|
|
|
|
XFree(ms);
|
|
|
|
}
|
2010-07-12 19:52:35 +00:00
|
|
|
#endif // XF86VIDMODE
|
|
|
|
|
|
|
|
if (!found)
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
2010-07-12 19:52:35 +00:00
|
|
|
// Add current screen mode
|
|
|
|
GfxMode mode;
|
|
|
|
mode.Width = DisplayWidth(_dpy, screen);
|
|
|
|
mode.Height = DisplayHeight(_dpy, screen);
|
|
|
|
mode.Frequency = 0;
|
|
|
|
modes.push_back(mode);
|
|
|
|
|
|
|
|
nldebug("3D: X11 available mode:");
|
|
|
|
nldebug("3D: %dx%d", mode.Width, mode.Height);
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------
|
|
|
|
bool CDriverGL::getCurrentScreenMode(GfxMode &mode)
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_getCurrentScreenMode)
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#ifdef NL_OS_WINDOWS
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
DEVMODE devmode;
|
2010-06-12 13:34:20 +00:00
|
|
|
devmode.dmSize = sizeof(DEVMODE);
|
|
|
|
devmode.dmDriverExtra = 0;
|
2010-06-08 16:58:58 +00:00
|
|
|
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devmode);
|
|
|
|
|
2010-06-12 13:34:20 +00:00
|
|
|
mode.Windowed = !_FullScreen;
|
|
|
|
mode.OffScreen = false;
|
|
|
|
mode.Depth = (uint8)devmode.dmBitsPerPel;
|
|
|
|
mode.Frequency = devmode.dmDisplayFrequency,
|
|
|
|
mode.Width = (uint16)devmode.dmPelsWidth;
|
|
|
|
mode.Height = (uint16)devmode.dmPelsHeight;
|
2010-06-12 20:22:32 +00:00
|
|
|
mode.AntiAlias = _AntiAliasing;
|
2010-06-22 06:12:31 +00:00
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
2010-06-13 18:24:58 +00:00
|
|
|
|
2010-06-23 21:37:19 +00:00
|
|
|
NL3D::MAC::getCurrentScreenMode(_win, mode);
|
2010-06-08 16:58:58 +00:00
|
|
|
|
|
|
|
#elif defined(NL_OS_MAC)
|
|
|
|
/*
|
|
|
|
TODO this is just a hack to get the ryzom client running on mac os x x11.
|
|
|
|
the implementation below relies on the vidmode extension which is not
|
2010-06-23 06:59:03 +00:00
|
|
|
available on mac os x's x11. for that reason the color depth value is
|
2010-06-08 16:58:58 +00:00
|
|
|
hard coded here.
|
|
|
|
FIXME replace this hack by native cocoa color depth retrieval
|
|
|
|
*/
|
|
|
|
nlwarning("FIXME: returning hardcoded color depth of 24bit");
|
|
|
|
mode.Depth= 24;
|
|
|
|
|
|
|
|
#elif defined(NL_OS_UNIX)
|
|
|
|
|
2010-07-12 19:52:35 +00:00
|
|
|
bool found = false;
|
|
|
|
int screen = DefaultScreen(_dpy);
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-07-12 19:52:35 +00:00
|
|
|
// x11 fullscreen is not working on mac os x
|
|
|
|
#if defined(NL_OS_MAC)
|
|
|
|
mode.Windowed = true;
|
|
|
|
found = true;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef XRANDR
|
|
|
|
|
|
|
|
if (!found && _xrandr_version > 0)
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
2010-07-12 19:52:35 +00:00
|
|
|
XRRScreenConfiguration *screen_config = XRRGetScreenInfo(_dpy, RootWindow(_dpy, screen));
|
|
|
|
|
|
|
|
if (screen_config)
|
|
|
|
{
|
|
|
|
int nsizes;
|
|
|
|
XRRScreenSize *sizes = XRRConfigSizes(screen_config, &nsizes);
|
|
|
|
if (nsizes > 0)
|
|
|
|
{
|
|
|
|
Rotation cur_rotation;
|
|
|
|
SizeID size = XRRConfigCurrentConfiguration(screen_config, &cur_rotation);
|
|
|
|
|
|
|
|
mode.Windowed = !_FullScreen;
|
|
|
|
mode.OffScreen = false;
|
|
|
|
mode.Depth = (uint) DefaultDepth(_dpy, screen);
|
|
|
|
mode.Frequency = 0;
|
|
|
|
mode.Width = sizes[size].width;
|
|
|
|
mode.Height = sizes[size].height;
|
|
|
|
|
|
|
|
found = true;
|
|
|
|
|
|
|
|
nlinfo("3D: Current XRandR mode %d: %dx%d, %dbit", size, mode.Width, mode.Height, mode.Depth);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nlwarning("3D: No XRandR modes available");
|
|
|
|
}
|
|
|
|
|
|
|
|
XRRFreeScreenConfigInfo(screen_config);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nlwarning("3D: XRRGetScreenInfo failed");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // XRANDR
|
|
|
|
|
|
|
|
#ifdef XF86VIDMODE
|
|
|
|
|
|
|
|
if (!found && _xvidmode_version > 0)
|
|
|
|
{
|
|
|
|
sint pixelClock;
|
|
|
|
XF86VidModeModeLine xmode;
|
|
|
|
|
|
|
|
if (XF86VidModeGetModeLine(_dpy, screen, &pixelClock, &xmode))
|
|
|
|
{
|
|
|
|
mode.Windowed = !_FullScreen;
|
|
|
|
mode.OffScreen = false;
|
|
|
|
mode.Depth = (uint) DefaultDepth(_dpy, screen);
|
|
|
|
mode.Frequency = 1000 * pixelClock / (xmode.htotal * xmode.vtotal) ;
|
|
|
|
mode.Width = xmode.hdisplay;
|
|
|
|
mode.Height = xmode.vdisplay;
|
|
|
|
nlinfo("3D: Current XF86VidMode mode: %dx%d, %d Hz, %dbit", mode.Width, mode.Height, mode.Frequency, mode.Depth);
|
|
|
|
|
|
|
|
found = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nlwarning("3D: XF86VidModeGetModeLine failed, cannot get current video mode");
|
|
|
|
}
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
|
2010-06-11 15:12:19 +00:00
|
|
|
#endif
|
|
|
|
|
2010-07-12 19:52:35 +00:00
|
|
|
if (!found)
|
|
|
|
{
|
|
|
|
mode.Windowed = !_FullScreen;
|
|
|
|
mode.OffScreen = _OffScreen;
|
|
|
|
mode.Depth = (uint) DefaultDepth(_dpy, screen);
|
|
|
|
mode.Frequency = 0;
|
|
|
|
mode.Width = DisplayWidth(_dpy, screen);
|
|
|
|
mode.Height = DisplayHeight(_dpy, screen);
|
2010-06-08 16:58:58 +00:00
|
|
|
|
2010-07-12 19:52:35 +00:00
|
|
|
found = true;
|
|
|
|
|
|
|
|
nldebug("Current mode: %dx%d, %d Hz, %dbit", mode.Width, mode.Height, mode.Frequency, mode.Depth);
|
|
|
|
}
|
2010-06-08 16:58:58 +00:00
|
|
|
|
|
|
|
#endif
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------
|
|
|
|
void CDriverGL::setWindowTitle(const ucstring &title)
|
|
|
|
{
|
2010-07-24 21:09:43 +00:00
|
|
|
H_AUTO_OGL(CDriverGL_setWindowTitle)
|
|
|
|
|
|
|
|
if (_win == EmptyWindow)
|
|
|
|
return;
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#ifdef NL_OS_WINDOWS
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-06-12 20:22:32 +00:00
|
|
|
SetWindowTextW(_win, (WCHAR*)title.c_str());
|
2010-06-08 16:58:58 +00:00
|
|
|
|
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-06-23 21:37:19 +00:00
|
|
|
NL3D::MAC::setWindowTitle(_win, title);
|
2010-06-08 16:58:58 +00:00
|
|
|
|
|
|
|
#elif defined (NL_OS_UNIX)
|
2010-06-12 13:34:20 +00:00
|
|
|
|
|
|
|
#ifdef X_HAVE_UTF8_STRING
|
|
|
|
Xutf8SetWMProperties (_dpy, _win, (char*)title.toUtf8().c_str(), (char*)title.toUtf8().c_str(), NULL, 0, NULL, NULL, NULL);
|
|
|
|
#else
|
2010-06-08 16:58:58 +00:00
|
|
|
XTextProperty text_property;
|
2010-06-12 13:34:20 +00:00
|
|
|
XStringListToTextProperty((char**)&title.toUtf8().c_str(), 1, &text_property);
|
|
|
|
XSetWMProperties (_dpy, _win, &text_property, &text_property, 0, 0, NULL, 0, 0);
|
|
|
|
#endif
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#endif // NL_OS_WINDOWS
|
|
|
|
}
|
|
|
|
|
|
|
|
// ***************************************************************************
|
2010-06-13 18:24:58 +00:00
|
|
|
void CDriverGL::setWindowPos(sint32 x, sint32 y)
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
2010-07-24 21:09:43 +00:00
|
|
|
H_AUTO_OGL(CDriverGL_setWindowPos)
|
|
|
|
|
2010-06-13 18:24:58 +00:00
|
|
|
_WindowX = x;
|
|
|
|
_WindowY = y;
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-07-31 09:09:09 +00:00
|
|
|
if (_win == EmptyWindow)
|
|
|
|
return;
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#ifdef NL_OS_WINDOWS
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-06-12 20:22:32 +00:00
|
|
|
SetWindowPos(_win, NULL, x, y, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE);
|
2010-06-08 16:58:58 +00:00
|
|
|
|
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-06-23 21:37:19 +00:00
|
|
|
NL3D::MAC::setWindowPos(_win, x, y);
|
2010-06-08 16:58:58 +00:00
|
|
|
|
|
|
|
#elif defined (NL_OS_UNIX)
|
2010-06-12 13:34:20 +00:00
|
|
|
|
|
|
|
XMoveWindow(_dpy, _win, x, y);
|
2010-06-08 16:58:58 +00:00
|
|
|
|
|
|
|
#endif // NL_OS_WINDOWS
|
|
|
|
}
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
void CDriverGL::showWindow(bool show)
|
|
|
|
{
|
2010-06-15 15:44:03 +00:00
|
|
|
H_AUTO_OGL(CDriverGL_showWindow)
|
|
|
|
|
|
|
|
// don't change window visibility, if we didn't create the window
|
2010-07-24 21:09:43 +00:00
|
|
|
if (_win == EmptyWindow || !_DestroyWindow)
|
2010-06-15 15:44:03 +00:00
|
|
|
return;
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#ifdef NL_OS_WINDOWS
|
2010-06-12 20:22:32 +00:00
|
|
|
ShowWindow (_win, show ? SW_SHOW:SW_HIDE);
|
2010-06-08 16:58:58 +00:00
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
|
|
|
|
2010-06-23 21:37:19 +00:00
|
|
|
MAC::showWindow(show);
|
2010-07-12 19:52:35 +00:00
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#elif defined (NL_OS_UNIX)
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
if (show)
|
2010-06-12 13:34:20 +00:00
|
|
|
{
|
|
|
|
XMapWindow(_dpy, _win);
|
|
|
|
// XMapRaised(_dpy, _win);
|
|
|
|
}
|
2010-06-08 16:58:58 +00:00
|
|
|
else
|
2010-06-12 13:34:20 +00:00
|
|
|
{
|
|
|
|
XUnmapWindow(_dpy, _win);
|
|
|
|
}
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#endif // NL_OS_WINDOWS
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------
|
|
|
|
emptyProc CDriverGL::getWindowProc()
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_getWindowProc)
|
2010-06-15 15:44:03 +00:00
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
return (emptyProc)GlWndProc;
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------
|
|
|
|
bool CDriverGL::activate()
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_activate)
|
2010-07-31 09:09:09 +00:00
|
|
|
|
|
|
|
if (_win == EmptyWindow)
|
|
|
|
return false;
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#ifdef NL_OS_WINDOWS
|
|
|
|
|
2010-06-12 13:34:20 +00:00
|
|
|
HGLRC hglrc = wglGetCurrentContext();
|
|
|
|
|
|
|
|
if (hglrc != _hRC)
|
|
|
|
wglMakeCurrent(_hDC, _hRC);
|
2010-06-08 16:58:58 +00:00
|
|
|
|
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-06-23 21:37:19 +00:00
|
|
|
if(!MAC::activate(_win))
|
|
|
|
{
|
|
|
|
nlwarning("cannot activate");
|
|
|
|
return false;
|
|
|
|
}
|
2010-06-08 16:58:58 +00:00
|
|
|
|
|
|
|
#elif defined (NL_OS_UNIX)
|
2010-06-12 13:34:20 +00:00
|
|
|
|
|
|
|
GLXContext nctx = glXGetCurrentContext();
|
|
|
|
|
|
|
|
if (nctx != NULL && nctx != _ctx)
|
|
|
|
glXMakeCurrent(_dpy, _win, _ctx);
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#endif // NL_OS_WINDOWS
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------
|
|
|
|
IDriver::TMessageBoxId CDriverGL::systemMessageBox (const char* message, const char* title, IDriver::TMessageBoxType type, TMessageBoxIcon icon)
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_systemMessageBox)
|
|
|
|
#ifdef NL_OS_WINDOWS
|
|
|
|
switch (::MessageBox (NULL, message, title, ((type==retryCancelType)?MB_RETRYCANCEL:
|
|
|
|
(type==yesNoCancelType)?MB_YESNOCANCEL:
|
|
|
|
(type==okCancelType)?MB_OKCANCEL:
|
|
|
|
(type==abortRetryIgnoreType)?MB_ABORTRETRYIGNORE:
|
|
|
|
(type==yesNoType)?MB_YESNO|MB_ICONQUESTION:MB_OK)|
|
|
|
|
|
|
|
|
((icon==handIcon)?MB_ICONHAND:
|
|
|
|
(icon==questionIcon)?MB_ICONQUESTION:
|
|
|
|
(icon==exclamationIcon)?MB_ICONEXCLAMATION:
|
|
|
|
(icon==asteriskIcon)?MB_ICONASTERISK:
|
|
|
|
(icon==warningIcon)?MB_ICONWARNING:
|
|
|
|
(icon==errorIcon)?MB_ICONERROR:
|
|
|
|
(icon==informationIcon)?MB_ICONINFORMATION:
|
|
|
|
(icon==stopIcon)?MB_ICONSTOP:0)))
|
|
|
|
{
|
|
|
|
case IDOK:
|
|
|
|
return okId;
|
|
|
|
case IDCANCEL:
|
|
|
|
return cancelId;
|
|
|
|
case IDABORT:
|
|
|
|
return abortId;
|
|
|
|
case IDRETRY:
|
|
|
|
return retryId;
|
|
|
|
case IDIGNORE:
|
|
|
|
return ignoreId;
|
|
|
|
case IDYES:
|
|
|
|
return yesId;
|
|
|
|
case IDNO:
|
|
|
|
return noId;
|
|
|
|
}
|
|
|
|
nlstop;
|
|
|
|
#else // NL_OS_WINDOWS
|
|
|
|
// Call the console version!
|
|
|
|
IDriver::systemMessageBox (message, title, type, icon);
|
|
|
|
#endif // NL_OS_WINDOWS
|
|
|
|
return okId;
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------
|
|
|
|
void CDriverGL::showCursor(bool b)
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_showCursor)
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-07-31 09:09:09 +00:00
|
|
|
if (_win == EmptyWindow)
|
|
|
|
return;
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#ifdef NL_OS_WINDOWS
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
if (b)
|
|
|
|
{
|
|
|
|
while (ShowCursor(b) < 0)
|
|
|
|
;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
while (ShowCursor(b) >= 0)
|
|
|
|
;
|
|
|
|
}
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
2010-06-09 21:15:14 +00:00
|
|
|
|
|
|
|
NL3D::MAC::showCursor(b);
|
2010-06-08 16:58:58 +00:00
|
|
|
|
|
|
|
#elif defined (NL_OS_UNIX)
|
|
|
|
|
|
|
|
if (b)
|
|
|
|
{
|
2010-06-12 13:34:20 +00:00
|
|
|
if (_cursor != None)
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
2010-06-12 13:34:20 +00:00
|
|
|
XFreeCursor(_dpy, _cursor);
|
|
|
|
_cursor = None;
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
2010-06-12 13:34:20 +00:00
|
|
|
XUndefineCursor(_dpy, _win);
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-06-12 13:34:20 +00:00
|
|
|
if (_cursor == None)
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
|
|
|
char bm_no_data[] = { 0,0,0,0, 0,0,0,0 };
|
2010-06-12 13:34:20 +00:00
|
|
|
Pixmap pixmap_no_data = XCreateBitmapFromData (_dpy, _win, bm_no_data, 8, 8);
|
2010-06-08 16:58:58 +00:00
|
|
|
XColor black;
|
|
|
|
memset(&black, 0, sizeof (XColor));
|
|
|
|
black.flags = DoRed | DoGreen | DoBlue;
|
2010-06-12 13:34:20 +00:00
|
|
|
_cursor = XCreatePixmapCursor (_dpy, pixmap_no_data, pixmap_no_data, &black, &black, 0, 0);
|
|
|
|
XFreePixmap(_dpy, pixmap_no_data);
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
2010-06-12 13:34:20 +00:00
|
|
|
XDefineCursor(_dpy, _win, _cursor);
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#endif // NL_OS_UNIX
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------
|
|
|
|
void CDriverGL::setMousePos(float x, float y)
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_setMousePos)
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-07-31 09:09:09 +00:00
|
|
|
if (_win == EmptyWindow)
|
|
|
|
return;
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#ifdef NL_OS_WINDOWS
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-07-31 09:09:09 +00:00
|
|
|
// NeL window coordinate to MSWindows coordinates
|
|
|
|
POINT pt;
|
|
|
|
pt.x = (sint)((float)(_WindowWidth)*x);
|
|
|
|
pt.y = (sint)((float)(_WindowHeight)*(1.0f-y));
|
|
|
|
ClientToScreen (_win, &pt);
|
|
|
|
SetCursorPos(pt.x, pt.y);
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
2010-06-09 21:15:14 +00:00
|
|
|
|
2010-06-23 21:37:19 +00:00
|
|
|
NL3D::MAC::setMousePos(_win, x, y);
|
2010-06-08 16:58:58 +00:00
|
|
|
|
|
|
|
#elif defined (NL_OS_UNIX)
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-07-24 21:09:43 +00:00
|
|
|
sint x1 = (sint)((float)_WindowWidth*x);
|
|
|
|
sint y1 = (sint)((float)_WindowHeight*(1.0f-y));
|
2010-06-12 13:34:20 +00:00
|
|
|
XWarpPointer (_dpy, None, _win, None, None, None, None, x1, y1);
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#endif // NL_OS_UNIX
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDriverGL::getWindowSize(uint32 &width, uint32 &height)
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_getWindowSize)
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-07-24 21:09:43 +00:00
|
|
|
#ifdef NL_MAC_NATIVE
|
|
|
|
|
|
|
|
NL3D::MAC::getWindowSize(_win, width, height);
|
|
|
|
|
|
|
|
#else
|
2010-06-12 13:34:20 +00:00
|
|
|
|
|
|
|
// Off-screen rendering ?
|
2010-06-08 16:58:58 +00:00
|
|
|
if (_OffScreen)
|
|
|
|
{
|
2010-07-24 21:09:43 +00:00
|
|
|
#ifdef NL_OS_WINDOWS
|
2010-06-08 16:58:58 +00:00
|
|
|
if (_PBuffer)
|
|
|
|
{
|
|
|
|
nwglQueryPbufferARB( _PBuffer, WGL_PBUFFER_WIDTH_ARB, (int*)&width );
|
|
|
|
nwglQueryPbufferARB( _PBuffer, WGL_PBUFFER_HEIGHT_ARB, (int*)&height );
|
|
|
|
}
|
2010-07-24 21:09:43 +00:00
|
|
|
#endif
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-06-12 20:22:32 +00:00
|
|
|
if (_win)
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
2010-07-24 21:09:43 +00:00
|
|
|
width = _WindowWidth;
|
|
|
|
height = _WindowHeight;
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
}
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-07-24 21:09:43 +00:00
|
|
|
#endif // NL_MAC_NATIVE
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
|
2010-06-13 19:00:19 +00:00
|
|
|
void CDriverGL::setWindowSize(uint32 width, uint32 height)
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_setWindowSize)
|
|
|
|
|
2010-07-31 09:09:09 +00:00
|
|
|
_WindowWidth = width;
|
|
|
|
_WindowHeight = height;
|
|
|
|
|
|
|
|
if (_win == EmptyWindow)
|
|
|
|
return;
|
|
|
|
|
2010-06-13 19:00:19 +00:00
|
|
|
#if defined(NL_OS_WINDOWS)
|
|
|
|
|
|
|
|
// resize the window
|
|
|
|
RECT rc;
|
|
|
|
SetRect (&rc, 0, 0, width, height);
|
|
|
|
AdjustWindowRectEx(&rc, GetWindowStyle(_win), GetMenu(_win) != NULL, GetWindowExStyle(_win));
|
|
|
|
UINT flags = SWP_NOZORDER | SWP_NOACTIVATE;
|
2010-06-14 19:54:58 +00:00
|
|
|
// set position to (0, 0) if fullscreen
|
2010-06-13 19:00:19 +00:00
|
|
|
if (!_FullScreen)
|
|
|
|
flags |= SWP_NOMOVE;
|
|
|
|
SetWindowPos(_win, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, flags);
|
|
|
|
|
|
|
|
// init window width and height
|
|
|
|
RECT clientRect;
|
|
|
|
GetClientRect(_win, &clientRect);
|
|
|
|
_WindowWidth = clientRect.right-clientRect.left;
|
|
|
|
_WindowHeight = clientRect.bottom-clientRect.top;
|
|
|
|
GetWindowRect(_win, &clientRect);
|
|
|
|
_WindowX = clientRect.left;
|
|
|
|
_WindowY = clientRect.top;
|
|
|
|
|
2010-06-23 21:37:19 +00:00
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
|
|
|
|
|
|
|
NL3D::MAC::setWindowSize(_win, width, height);
|
|
|
|
|
|
|
|
#elif defined(NL_OS_UNIX)
|
2010-06-13 19:00:19 +00:00
|
|
|
|
2010-06-16 07:38:29 +00:00
|
|
|
// Update WM hints (update size and allow resizing)
|
|
|
|
XSizeHints size_hints;
|
|
|
|
size_hints.width = width;
|
|
|
|
size_hints.height = height;
|
|
|
|
size_hints.flags = PSize;
|
|
|
|
|
2010-06-14 19:54:58 +00:00
|
|
|
if (!_Resizable)
|
2010-06-13 19:00:19 +00:00
|
|
|
{
|
2010-06-16 07:38:29 +00:00
|
|
|
size_hints.flags |= PMinSize | PMaxSize;
|
2010-06-13 19:46:50 +00:00
|
|
|
size_hints.min_width = width;
|
|
|
|
size_hints.min_height = height;
|
|
|
|
size_hints.max_width = width;
|
|
|
|
size_hints.max_height = height;
|
2010-06-13 19:00:19 +00:00
|
|
|
}
|
|
|
|
|
2010-06-16 07:38:29 +00:00
|
|
|
XSetWMNormalHints(_dpy, _win, &size_hints);
|
|
|
|
|
2010-07-12 19:52:35 +00:00
|
|
|
// resize the window
|
|
|
|
XResizeWindow(_dpy, _win, width, height);
|
2010-06-13 19:00:19 +00:00
|
|
|
|
|
|
|
#endif // NL_OS_WINDOWS
|
|
|
|
}
|
|
|
|
|
2010-06-13 18:24:58 +00:00
|
|
|
void CDriverGL::getWindowPos(sint32 &x, sint32 &y)
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_getWindowPos)
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-07-24 21:09:43 +00:00
|
|
|
#ifdef NL_MAC_NATIVE
|
|
|
|
|
|
|
|
NL3D::MAC::getWindowPos(_win, x, y);
|
|
|
|
|
|
|
|
#else
|
2010-06-12 13:34:20 +00:00
|
|
|
|
|
|
|
// Off-screen rendering ?
|
2010-06-08 16:58:58 +00:00
|
|
|
if (_OffScreen)
|
|
|
|
{
|
2010-07-24 21:09:43 +00:00
|
|
|
x = y = 0;
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-06-12 20:22:32 +00:00
|
|
|
if (_win)
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
2010-06-13 18:24:58 +00:00
|
|
|
x = _WindowX;
|
|
|
|
y = _WindowY;
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
}
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-07-24 21:09:43 +00:00
|
|
|
#endif // NL_MAC_NATIVE
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------
|
|
|
|
bool CDriverGL::isActive()
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_isActive)
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-07-31 09:09:09 +00:00
|
|
|
if (_win == EmptyWindow)
|
|
|
|
return false;
|
|
|
|
|
2010-06-12 13:34:20 +00:00
|
|
|
bool res = true;
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#ifdef NL_OS_WINDOWS
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-06-12 20:22:32 +00:00
|
|
|
res = (IsWindow(_win) != FALSE);
|
2010-06-12 13:34:20 +00:00
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
|
|
|
# warning "OpenGL Driver: Missing Mac Implementation"
|
|
|
|
// nlwarning("OpenGL Driver: Missing Mac Implementation");
|
|
|
|
|
|
|
|
#elif defined (NL_OS_UNIX)
|
|
|
|
|
|
|
|
#endif // NL_OS_UNIX
|
2010-06-12 13:34:20 +00:00
|
|
|
|
|
|
|
return res;
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CDriverGL::setCapture (bool b)
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_setCapture )
|
|
|
|
|
|
|
|
#ifdef NL_OS_WINDOWS
|
|
|
|
|
|
|
|
if (b)
|
|
|
|
{
|
|
|
|
RECT client;
|
2010-06-12 20:22:32 +00:00
|
|
|
GetClientRect (_win, &client);
|
2010-06-08 16:58:58 +00:00
|
|
|
POINT pt1,pt2;
|
|
|
|
pt1.x = client.left;
|
|
|
|
pt1.y = client.top;
|
2010-06-12 20:22:32 +00:00
|
|
|
ClientToScreen (_win, &pt1);
|
2010-06-08 16:58:58 +00:00
|
|
|
pt2.x = client.right;
|
|
|
|
pt2.y = client.bottom;
|
2010-06-12 20:22:32 +00:00
|
|
|
ClientToScreen (_win, &pt2);
|
2010-06-08 16:58:58 +00:00
|
|
|
client.bottom = pt2.y;
|
|
|
|
client.top = pt1.y;
|
|
|
|
client.left = pt1.x;
|
|
|
|
client.right = pt2.x;
|
|
|
|
ClipCursor (&client);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ClipCursor (NULL);
|
|
|
|
|
|
|
|
/*
|
|
|
|
if (b)
|
|
|
|
SetCapture (_hWnd);
|
|
|
|
else
|
|
|
|
ReleaseCapture ();
|
|
|
|
*/
|
|
|
|
|
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
2010-06-09 21:15:14 +00:00
|
|
|
|
|
|
|
NL3D::MAC::setCapture(b);
|
2010-06-08 16:58:58 +00:00
|
|
|
|
|
|
|
#elif defined (NL_OS_UNIX)
|
|
|
|
|
|
|
|
/*
|
|
|
|
TODO x11 funtion: setCapture
|
|
|
|
*/
|
|
|
|
|
|
|
|
if(b) // capture the cursor.
|
|
|
|
{
|
2010-06-12 13:34:20 +00:00
|
|
|
XGrabPointer(_dpy, _win, True, 0, GrabModeAsync, GrabModeAsync, _win, None, CurrentTime);
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
else // release the cursor.
|
|
|
|
{
|
2010-06-12 13:34:20 +00:00
|
|
|
XUngrabPointer(_dpy, CurrentTime);
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif // NL_OS_UNIX
|
|
|
|
}
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
NLMISC::IMouseDevice* CDriverGL::enableLowLevelMouse(bool enable, bool exclusive)
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_enableLowLevelMouse)
|
|
|
|
|
2010-06-12 14:31:39 +00:00
|
|
|
NLMISC::IMouseDevice *res = NULL;
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#ifdef NL_OS_WINDOWS
|
2010-06-12 14:31:39 +00:00
|
|
|
|
|
|
|
NLMISC::CDIEventEmitter *diee = NULL;
|
|
|
|
|
|
|
|
if (_EventEmitter.getNumEmitters() > 1)
|
|
|
|
diee = NLMISC::safe_cast<CDIEventEmitter *>(_EventEmitter.getEmitter(1));
|
|
|
|
|
|
|
|
if (enable)
|
|
|
|
{
|
|
|
|
try
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
2010-06-12 14:31:39 +00:00
|
|
|
if (diee)
|
|
|
|
res = diee->getMouseDevice(exclusive);
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
2010-06-12 14:31:39 +00:00
|
|
|
catch (EDirectInput &)
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
|
|
|
}
|
2010-06-12 14:31:39 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (diee)
|
|
|
|
diee->releaseMouse();
|
|
|
|
}
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
|
|
|
# warning "OpenGL Driver: Missing Mac Implementation"
|
|
|
|
nlwarning("OpenGL Driver: Missing Mac Implementation");
|
|
|
|
|
|
|
|
#elif defined (NL_OS_UNIX)
|
|
|
|
|
|
|
|
#endif
|
2010-06-12 14:31:39 +00:00
|
|
|
|
|
|
|
return res;
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
NLMISC::IKeyboardDevice* CDriverGL::enableLowLevelKeyboard(bool enable)
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_enableLowLevelKeyboard)
|
2010-06-12 14:31:39 +00:00
|
|
|
|
|
|
|
NLMISC::IKeyboardDevice *res = NULL;
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#ifdef NL_OS_WINDOWS
|
2010-06-12 14:31:39 +00:00
|
|
|
|
|
|
|
NLMISC::CDIEventEmitter *diee = NULL;
|
|
|
|
|
|
|
|
if (_EventEmitter.getNumEmitters() > 1)
|
|
|
|
diee = NLMISC::safe_cast<NLMISC::CDIEventEmitter *>(_EventEmitter.getEmitter(1));
|
|
|
|
|
|
|
|
if (enable)
|
|
|
|
{
|
|
|
|
try
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
2010-06-12 14:31:39 +00:00
|
|
|
if (diee)
|
|
|
|
res = diee->getKeyboardDevice();
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
2010-06-12 14:31:39 +00:00
|
|
|
catch (EDirectInput &)
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
|
|
|
}
|
2010-06-12 14:31:39 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (diee)
|
|
|
|
diee->releaseKeyboard();
|
|
|
|
}
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
|
|
|
# warning "OpenGL Driver: Missing Mac Implementation"
|
|
|
|
nlwarning("OpenGL Driver: Missing Mac Implementation");
|
|
|
|
|
|
|
|
#elif defined (NL_OS_UNIX)
|
|
|
|
|
|
|
|
#endif
|
2010-06-12 14:31:39 +00:00
|
|
|
|
|
|
|
return res;
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
NLMISC::IInputDeviceManager* CDriverGL::getLowLevelInputDeviceManager()
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_getLowLevelInputDeviceManager)
|
2010-06-12 14:31:39 +00:00
|
|
|
|
|
|
|
NLMISC::IInputDeviceManager *res = NULL;
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#ifdef NL_OS_WINDOWS
|
2010-06-12 14:31:39 +00:00
|
|
|
|
|
|
|
if (_EventEmitter.getNumEmitters() > 1)
|
|
|
|
res = NLMISC::safe_cast<NLMISC::CDIEventEmitter *>(_EventEmitter.getEmitter(1));
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
|
|
|
# warning "OpenGL Driver: Missing Mac Implementation"
|
|
|
|
nlwarning("OpenGL Driver: Missing Mac Implementation");
|
|
|
|
|
|
|
|
#elif defined (NL_OS_UNIX)
|
|
|
|
|
|
|
|
#endif
|
2010-06-12 14:31:39 +00:00
|
|
|
|
|
|
|
return res;
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
uint CDriverGL::getDoubleClickDelay(bool hardwareMouse)
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_getDoubleClickDelay)
|
|
|
|
|
2010-06-12 14:31:39 +00:00
|
|
|
uint res = 250;
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#ifdef NL_OS_WINDOWS
|
2010-06-12 14:31:39 +00:00
|
|
|
|
|
|
|
NLMISC::IMouseDevice *md = NULL;
|
|
|
|
|
|
|
|
if (_EventEmitter.getNumEmitters() >= 2)
|
|
|
|
{
|
|
|
|
NLMISC::CDIEventEmitter *diee = NLMISC::safe_cast<CDIEventEmitter *>(_EventEmitter.getEmitter(1));
|
|
|
|
if (diee->isMouseCreated())
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
2010-06-12 14:31:39 +00:00
|
|
|
try
|
2010-06-08 16:58:58 +00:00
|
|
|
{
|
2010-06-12 14:31:39 +00:00
|
|
|
md = diee->getMouseDevice(hardwareMouse);
|
|
|
|
}
|
|
|
|
catch (EDirectInput &)
|
|
|
|
{
|
|
|
|
// could not get device ..
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
}
|
2010-06-12 14:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (md)
|
|
|
|
{
|
|
|
|
res = md->getDoubleClickDelay();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-06-08 16:58:58 +00:00
|
|
|
// try to read the good value from windows
|
2010-06-12 14:31:39 +00:00
|
|
|
res = ::GetDoubleClickTime();
|
|
|
|
}
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
|
|
|
# warning "OpenGL Driver: Missing Mac Implementation"
|
|
|
|
nlwarning("OpenGL Driver: Missing Mac Implementation");
|
|
|
|
|
|
|
|
#elif defined (NL_OS_UNIX)
|
2010-06-12 14:31:39 +00:00
|
|
|
|
|
|
|
// TODO for Linux
|
|
|
|
|
2010-06-08 16:58:58 +00:00
|
|
|
#endif
|
2010-06-12 14:31:39 +00:00
|
|
|
|
|
|
|
return res;
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
bool CDriverGL::setMonitorColorProperties (const CMonitorColorProperties &properties)
|
|
|
|
{
|
|
|
|
H_AUTO_OGL(CDriverGL_setMonitorColorProperties )
|
|
|
|
|
|
|
|
#ifdef NL_OS_WINDOWS
|
|
|
|
|
|
|
|
// Get a DC
|
|
|
|
HDC dc = CreateDC ("DISPLAY", NULL, NULL, NULL);
|
|
|
|
if (dc)
|
|
|
|
{
|
|
|
|
// The ramp
|
|
|
|
WORD ramp[256*3];
|
|
|
|
|
|
|
|
// For each composant
|
|
|
|
uint c;
|
|
|
|
for( c=0; c<3; c++ )
|
|
|
|
{
|
|
|
|
uint i;
|
|
|
|
for( i=0; i<256; i++ )
|
|
|
|
{
|
|
|
|
// Floating value
|
|
|
|
float value = (float)i / 256;
|
|
|
|
|
|
|
|
// Contrast
|
|
|
|
value = (float) max (0.0f, (value-0.5f) * (float) pow (3.f, properties.Contrast[c]) + 0.5f );
|
|
|
|
|
|
|
|
// Gamma
|
|
|
|
value = (float) pow (value, (properties.Gamma[c]>0) ? 1 - 3 * properties.Gamma[c] / 4 : 1 - properties.Gamma[c] );
|
|
|
|
|
|
|
|
// Luminosity
|
|
|
|
value = value + properties.Luminosity[c] / 2.f;
|
|
|
|
ramp[i+(c<<8)] = (WORD)min ((int)65535, max (0, (int)(value * 65535)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the ramp
|
|
|
|
bool result = SetDeviceGammaRamp (dc, ramp) != FALSE;
|
|
|
|
|
|
|
|
// Release the DC
|
|
|
|
ReleaseDC (NULL, dc);
|
|
|
|
|
|
|
|
// Returns result
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nlwarning ("(CDriverGL::setMonitorColorProperties): can't create DC");
|
|
|
|
}
|
|
|
|
|
|
|
|
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
|
|
|
|
# warning "OpenGL Driver: Missing Mac Implementation"
|
|
|
|
nlwarning("OpenGL Driver: Missing Mac Implementation");
|
|
|
|
|
|
|
|
#elif defined (NL_OS_UNIX)
|
|
|
|
|
|
|
|
// TODO for Linux: implement CDriverGL::setMonitorColorProperties
|
|
|
|
nlwarning ("CDriverGL::setMonitorColorProperties not implemented");
|
|
|
|
|
|
|
|
#endif
|
2010-06-12 13:34:20 +00:00
|
|
|
|
|
|
|
return false;
|
2010-06-08 16:58:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // NL3D
|