Changed: #1034 Implement CCustomMouse for Linux
This commit is contained in:
parent
22893f569e
commit
fef3219ca2
27 changed files with 1969 additions and 1372 deletions
|
@ -1,46 +0,0 @@
|
||||||
# - Locate XRandR library
|
|
||||||
# This module defines
|
|
||||||
# XRandR_LIBRARY, the library to link against
|
|
||||||
# XRandR_FOUND, if false, do not try to link to XRandR
|
|
||||||
# XRandR_INCLUDE_DIR, where to find headers.
|
|
||||||
|
|
||||||
IF(XRandR_LIBRARY AND XRandR_INCLUDE_DIR)
|
|
||||||
# in cache already
|
|
||||||
SET(XRandR_FIND_QUIETLY TRUE)
|
|
||||||
ENDIF(XRandR_LIBRARY AND XRandR_INCLUDE_DIR)
|
|
||||||
|
|
||||||
|
|
||||||
FIND_PATH(XRandR_INCLUDE_DIR
|
|
||||||
Xrandr.h
|
|
||||||
PATHS
|
|
||||||
$ENV{XRandR_DIR}/include
|
|
||||||
/usr/include/X11/
|
|
||||||
/usr/X11R6/include/
|
|
||||||
PATH_SUFFIXES extensions
|
|
||||||
)
|
|
||||||
|
|
||||||
FIND_LIBRARY(XRandR_LIBRARY
|
|
||||||
Xrandr
|
|
||||||
PATHS
|
|
||||||
$ENV{XRandR_DIR}/lib
|
|
||||||
/usr/X11R6/lib
|
|
||||||
/usr/lib
|
|
||||||
/sw/lib
|
|
||||||
/opt/local/lib
|
|
||||||
/opt/csw/lib
|
|
||||||
/opt/lib
|
|
||||||
/usr/freeware/lib64
|
|
||||||
)
|
|
||||||
|
|
||||||
IF(XRandR_LIBRARY AND XRandR_INCLUDE_DIR)
|
|
||||||
SET(XRandR_FOUND "YES")
|
|
||||||
SET(XRandR_DEFINITIONS -DXRANDR)
|
|
||||||
IF(NOT XRandR_FIND_QUIETLY)
|
|
||||||
MESSAGE(STATUS "Found XRandR: ${XRandR_LIBRARY}")
|
|
||||||
ENDIF(NOT XRandR_FIND_QUIETLY)
|
|
||||||
ELSE(XRandR_LIBRARY AND XRandR_INCLUDE_DIR)
|
|
||||||
IF(NOT XRandR_FIND_QUIETLY)
|
|
||||||
MESSAGE(STATUS "Warning: Unable to find XRandR!")
|
|
||||||
ENDIF(NOT XRandR_FIND_QUIETLY)
|
|
||||||
ENDIF(XRandR_LIBRARY AND XRandR_INCLUDE_DIR)
|
|
||||||
|
|
|
@ -746,6 +746,15 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void setCapture (bool b) = 0;
|
virtual void setCapture (bool b) = 0;
|
||||||
|
|
||||||
|
// see if system cursor is currently captured
|
||||||
|
virtual bool isSystemCursorCaptured() = 0;
|
||||||
|
|
||||||
|
// Add a new cursor (name is case unsensitive)
|
||||||
|
virtual void addCursor(const std::string &name, const NLMISC::CBitmap &bitmap) = 0;
|
||||||
|
|
||||||
|
// Display a cursor from its name (case unsensitive)
|
||||||
|
virtual void setCursor(const std::string &name, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY, bool forceRebuild = false) = 0;
|
||||||
|
|
||||||
/** Check whether there is a low level device manager available, and get its interface. Return NULL if not available
|
/** Check whether there is a low level device manager available, and get its interface. Return NULL if not available
|
||||||
* From this interface you can deal with mouse and keyboard as above, but you can also manage game device (joysticks, joypads ...)
|
* From this interface you can deal with mouse and keyboard as above, but you can also manage game device (joysticks, joypads ...)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -430,6 +430,16 @@ public:
|
||||||
virtual void setMousePos (float x, float y);
|
virtual void setMousePos (float x, float y);
|
||||||
/// If true, capture the mouse to force it to stay under the window.
|
/// If true, capture the mouse to force it to stay under the window.
|
||||||
virtual void setCapture (bool b);
|
virtual void setCapture (bool b);
|
||||||
|
|
||||||
|
// see if system cursor is currently captured
|
||||||
|
virtual bool isSystemCursorCaptured();
|
||||||
|
|
||||||
|
// Add a new cursor (name is case unsensitive)
|
||||||
|
virtual void addCursor(const std::string &name, const NLMISC::CBitmap &bitmap);
|
||||||
|
|
||||||
|
// Display a cursor from its name (case unsensitive)
|
||||||
|
virtual void setCursor(const std::string &name, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY, bool forceRebuild = false);
|
||||||
|
|
||||||
// @}
|
// @}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -594,6 +594,16 @@ public:
|
||||||
* NB : If a low level mouse is used, it does nothing
|
* NB : If a low level mouse is used, it does nothing
|
||||||
*/
|
*/
|
||||||
virtual void setCapture (bool b) = 0;
|
virtual void setCapture (bool b) = 0;
|
||||||
|
|
||||||
|
// see if system cursor is currently captured
|
||||||
|
virtual bool isSystemCursorCaptured() = 0;
|
||||||
|
|
||||||
|
// Add a new cursor (name is case unsensitive)
|
||||||
|
virtual void addCursor(const std::string &name, const NLMISC::CBitmap &bitmap) = 0;
|
||||||
|
|
||||||
|
// Display a cursor from its name (case unsensitive)
|
||||||
|
virtual void setCursor(const std::string &name, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY, bool forceRebuild = false) = 0;
|
||||||
|
|
||||||
// @}
|
// @}
|
||||||
|
|
||||||
/// \name Misc.
|
/// \name Misc.
|
||||||
|
|
|
@ -621,10 +621,6 @@ public:
|
||||||
|
|
||||||
void getDibData(uint8*& extractData);
|
void getDibData(uint8*& extractData);
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
HICON getHICON(sint iconWidth, sint iconHeight, sint iconDepth, const NLMISC::CRGBA &col = NLMISC::CRGBA::White, sint hotSpotX = 0, sint hotSpotY = 0, bool cursor = false) const;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CBitmap& operator= (const CBitmap& from)
|
CBitmap& operator= (const CBitmap& from)
|
||||||
{
|
{
|
||||||
if (&from == this)
|
if (&from == this)
|
||||||
|
|
|
@ -41,8 +41,6 @@
|
||||||
#include "string_common.h"
|
#include "string_common.h"
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
#ifdef NL_OS_WINDOWS
|
||||||
struct nameHICON__;
|
|
||||||
typedef struct HICON__ *HICON;
|
|
||||||
struct nameHWND__;
|
struct nameHWND__;
|
||||||
typedef struct HWND__ *HWND;
|
typedef struct HWND__ *HWND;
|
||||||
typedef HWND nlWindow;
|
typedef HWND nlWindow;
|
||||||
|
|
|
@ -77,9 +77,6 @@ public:
|
||||||
|
|
||||||
/// Get desktop current color depth without using UDriver.
|
/// Get desktop current color depth without using UDriver.
|
||||||
static uint getCurrentColorDepth();
|
static uint getCurrentColorDepth();
|
||||||
|
|
||||||
/// Check if mouse cursor is in client area.
|
|
||||||
static bool isSystemCursorInClientArea();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // NLMISC
|
} // NLMISC
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace NL3D
|
||||||
{
|
{
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
const uint32 IDriver::InterfaceVersion = 0x69; // added clipboard methods
|
const uint32 IDriver::InterfaceVersion = 0x6a; // added cursors methods
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
IDriver::IDriver() : _SyncTexDrvInfos( "IDriver::_SyncTexDrvInfos" )
|
IDriver::IDriver() : _SyncTexDrvInfos( "IDriver::_SyncTexDrvInfos" )
|
||||||
|
|
|
@ -162,6 +162,19 @@ CDriverD3D::CDriverD3D()
|
||||||
_WindowX = 0;
|
_WindowX = 0;
|
||||||
_WindowY = 0;
|
_WindowY = 0;
|
||||||
_FullScreen = false;
|
_FullScreen = false;
|
||||||
|
|
||||||
|
_ColorDepth = ColorDepth32;
|
||||||
|
|
||||||
|
_DefaultCursor = EmptyCursor;
|
||||||
|
|
||||||
|
_AlphaBlendedCursorSupported = false;
|
||||||
|
_AlphaBlendedCursorSupportRetrieved = false;
|
||||||
|
_CurrCol = CRGBA::White;
|
||||||
|
_CurrRot = 0;
|
||||||
|
_CurrHotSpotX = 0;
|
||||||
|
_CurrHotSpotY = 0;
|
||||||
|
_CursorScale = 0.85f;
|
||||||
|
|
||||||
_UserViewMtx.identity();
|
_UserViewMtx.identity();
|
||||||
_UserModelMtx.identity();
|
_UserModelMtx.identity();
|
||||||
_PZBCameraPos = CVector::Null;
|
_PZBCameraPos = CVector::Null;
|
||||||
|
@ -1214,6 +1227,8 @@ bool CDriverD3D::init (uint windowIcon, emptyProc exitFunc)
|
||||||
|
|
||||||
ExitFunc = exitFunc;
|
ExitFunc = exitFunc;
|
||||||
|
|
||||||
|
createCursors();
|
||||||
|
|
||||||
// Register a window class
|
// Register a window class
|
||||||
WNDCLASSW wc;
|
WNDCLASSW wc;
|
||||||
|
|
||||||
|
@ -1224,7 +1239,7 @@ bool CDriverD3D::init (uint windowIcon, emptyProc exitFunc)
|
||||||
wc.cbWndExtra = 0;
|
wc.cbWndExtra = 0;
|
||||||
wc.hInstance = GetModuleHandleW(NULL);
|
wc.hInstance = GetModuleHandleW(NULL);
|
||||||
wc.hIcon = (HICON)windowIcon;
|
wc.hIcon = (HICON)windowIcon;
|
||||||
wc.hCursor = LoadCursorW(NULL,(LPCWSTR)IDC_ARROW);
|
wc.hCursor = _DefaultCursor;
|
||||||
wc.hbrBackground = WHITE_BRUSH;
|
wc.hbrBackground = WHITE_BRUSH;
|
||||||
_WindowClass = "NLD3D" + toString(windowIcon);
|
_WindowClass = "NLD3D" + toString(windowIcon);
|
||||||
ucstring us = _WindowClass;
|
ucstring us = _WindowClass;
|
||||||
|
@ -1712,6 +1727,8 @@ bool CDriverD3D::release()
|
||||||
|
|
||||||
if (_HWnd)
|
if (_HWnd)
|
||||||
{
|
{
|
||||||
|
releaseCursors();
|
||||||
|
|
||||||
// make sure window icons are deleted
|
// make sure window icons are deleted
|
||||||
std::vector<NLMISC::CBitmap> bitmaps;
|
std::vector<NLMISC::CBitmap> bitmaps;
|
||||||
setWindowIcon(bitmaps);
|
setWindowIcon(bitmaps);
|
||||||
|
@ -2231,10 +2248,10 @@ void CDriverD3D::setWindowIcon(const std::vector<NLMISC::CBitmap> &bitmaps)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (smallIndex > -1)
|
if (smallIndex > -1)
|
||||||
winIconSmall = bitmaps[smallIndex].getHICON(smallWidth, smallHeight, 32);
|
convertBitmapToIcon(bitmaps[smallIndex], winIconSmall, smallWidth, smallHeight, 32);
|
||||||
|
|
||||||
if (bigIndex > -1)
|
if (bigIndex > -1)
|
||||||
winIconBig = bitmaps[bigIndex].getHICON(bigWidth, bigHeight, 32);
|
convertBitmapToIcon(bitmaps[bigIndex], winIconBig, bigWidth, bigHeight, 32);
|
||||||
|
|
||||||
if (winIconBig)
|
if (winIconBig)
|
||||||
{
|
{
|
||||||
|
@ -3840,4 +3857,84 @@ bool CDriverD3D::pasteTextFromClipboard(ucstring &text)
|
||||||
{
|
{
|
||||||
return _EventEmitter.pasteTextFromClipboard(text);
|
return _EventEmitter.pasteTextFromClipboard(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CDriverD3D::convertBitmapToIcon(const NLMISC::CBitmap &bitmap, HICON &icon, uint iconWidth, uint iconHeight, uint iconDepth, const NLMISC::CRGBA &col, sint hotSpotX, sint hotSpotY, bool cursor)
|
||||||
|
{
|
||||||
|
CBitmap src = bitmap;
|
||||||
|
// resample bitmap if necessary
|
||||||
|
if (src.getWidth() != iconWidth || src.getHeight() != iconHeight)
|
||||||
|
{
|
||||||
|
src.resample(iconWidth, iconHeight);
|
||||||
|
}
|
||||||
|
CBitmap colorBm;
|
||||||
|
colorBm.resize(iconWidth, iconHeight, CBitmap::RGBA);
|
||||||
|
const CRGBA *srcColorPtr = (CRGBA *) &(src.getPixels()[0]);
|
||||||
|
const CRGBA *srcColorPtrLast = srcColorPtr + (iconWidth * iconHeight);
|
||||||
|
CRGBA *destColorPtr = (CRGBA *) &(colorBm.getPixels()[0]);
|
||||||
|
static volatile uint8 alphaThreshold = 127;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
destColorPtr->modulateFromColor(*srcColorPtr, col);
|
||||||
|
std::swap(destColorPtr->R, destColorPtr->B);
|
||||||
|
++ srcColorPtr;
|
||||||
|
++ destColorPtr;
|
||||||
|
}
|
||||||
|
while (srcColorPtr != srcColorPtrLast);
|
||||||
|
//
|
||||||
|
HBITMAP colorHbm = NULL;
|
||||||
|
HBITMAP maskHbm = NULL;
|
||||||
|
//
|
||||||
|
if (iconDepth == 16)
|
||||||
|
{
|
||||||
|
std::vector<uint16> colorBm16(iconWidth * iconHeight);
|
||||||
|
const CRGBA *src32 = (const CRGBA *) &colorBm.getPixels(0)[0];
|
||||||
|
|
||||||
|
for (uint k = 0; k < colorBm16.size(); ++k)
|
||||||
|
{
|
||||||
|
colorBm16[k] = ((uint16)(src32[k].R&0xf8)>>3) | ((uint16)(src32[k].G&0xfc)<<3) | ((uint16)(src32[k].B & 0xf8)<<8);
|
||||||
|
}
|
||||||
|
|
||||||
|
colorHbm = CreateBitmap(iconWidth, iconHeight, 1, 16, &colorBm16[0]);
|
||||||
|
std::vector<uint8> bitMask((iconWidth * iconHeight + 7) / 8, 0);
|
||||||
|
|
||||||
|
for (uint k = 0;k < colorBm16.size(); ++k)
|
||||||
|
{
|
||||||
|
if (src32[k].A <= 120)
|
||||||
|
{
|
||||||
|
bitMask[k / 8] |= (0x80 >> (k & 7));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
maskHbm = CreateBitmap(iconWidth, iconHeight, 1, 1, &bitMask[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
colorHbm = CreateBitmap(iconWidth, iconHeight, 1, 32, &colorBm.getPixels(0)[0]);
|
||||||
|
maskHbm = CreateBitmap(iconWidth, iconHeight, 1, 32, &colorBm.getPixels(0)[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ICONINFO iconInfo;
|
||||||
|
iconInfo.fIcon = cursor ? FALSE:TRUE;
|
||||||
|
iconInfo.xHotspot = (DWORD) hotSpotX;
|
||||||
|
iconInfo.yHotspot = (DWORD) hotSpotY;
|
||||||
|
iconInfo.hbmMask = maskHbm;
|
||||||
|
iconInfo.hbmColor = colorHbm;
|
||||||
|
|
||||||
|
if (colorHbm && maskHbm)
|
||||||
|
{
|
||||||
|
icon = CreateIconIndirect(&iconInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (colorHbm) DeleteObject(colorHbm);
|
||||||
|
if (maskHbm) DeleteObject(maskHbm);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDriverD3D::convertBitmapToCursor(const NLMISC::CBitmap &bitmap, nlCursor &cursor, uint iconWidth, uint iconHeight, uint iconDepth, const NLMISC::CRGBA &col, sint hotSpotX, sint hotSpotY)
|
||||||
|
{
|
||||||
|
return convertBitmapToIcon(bitmap, cursor, iconWidth, iconHeight, iconDepth, col, hotSpotX, hotSpotY, true);
|
||||||
|
}
|
||||||
|
|
||||||
} // NL3D
|
} // NL3D
|
||||||
|
|
|
@ -46,6 +46,9 @@
|
||||||
//
|
//
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
typedef HCURSOR nlCursor;
|
||||||
|
#define EmptyCursor NULL
|
||||||
|
|
||||||
|
|
||||||
// *** DEBUG MACRO
|
// *** DEBUG MACRO
|
||||||
|
|
||||||
|
@ -916,6 +919,18 @@ public:
|
||||||
virtual void showCursor (bool b);
|
virtual void showCursor (bool b);
|
||||||
virtual void setMousePos(float x, float y);
|
virtual void setMousePos(float x, float y);
|
||||||
virtual void setCapture (bool b);
|
virtual void setCapture (bool b);
|
||||||
|
|
||||||
|
// see if system cursor is currently captured
|
||||||
|
virtual bool isSystemCursorCaptured();
|
||||||
|
|
||||||
|
virtual void setHardwareCursorScale(float scale) { _CursorScale = scale; }
|
||||||
|
|
||||||
|
// Add a new cursor (name is case unsensitive)
|
||||||
|
virtual void addCursor(const std::string &name, const NLMISC::CBitmap &bitmap);
|
||||||
|
|
||||||
|
// Display a cursor from its name (case unsensitive)
|
||||||
|
virtual void setCursor(const std::string &name, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY, bool forceRebuild = false);
|
||||||
|
|
||||||
virtual NLMISC::IMouseDevice *enableLowLevelMouse(bool enable, bool exclusive);
|
virtual NLMISC::IMouseDevice *enableLowLevelMouse(bool enable, bool exclusive);
|
||||||
virtual NLMISC::IKeyboardDevice *enableLowLevelKeyboard(bool enable);
|
virtual NLMISC::IKeyboardDevice *enableLowLevelKeyboard(bool enable);
|
||||||
virtual NLMISC::IInputDeviceManager *getLowLevelInputDeviceManager();
|
virtual NLMISC::IInputDeviceManager *getLowLevelInputDeviceManager();
|
||||||
|
@ -2075,6 +2090,58 @@ private:
|
||||||
uint _Interval;
|
uint _Interval;
|
||||||
bool _FullScreen;
|
bool _FullScreen;
|
||||||
|
|
||||||
|
// cursors
|
||||||
|
enum TColorDepth { ColorDepth16 = 0, ColorDepth32, ColorDepthCount };
|
||||||
|
|
||||||
|
TColorDepth _ColorDepth;
|
||||||
|
std::string _CurrName;
|
||||||
|
NLMISC::CRGBA _CurrCol;
|
||||||
|
uint8 _CurrRot;
|
||||||
|
uint _CurrHotSpotX;
|
||||||
|
uint _CurrHotSpotY;
|
||||||
|
float _CursorScale;
|
||||||
|
|
||||||
|
nlCursor _DefaultCursor;
|
||||||
|
|
||||||
|
bool _AlphaBlendedCursorSupported;
|
||||||
|
bool _AlphaBlendedCursorSupportRetrieved;
|
||||||
|
|
||||||
|
class CCursor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NLMISC::CBitmap Src;
|
||||||
|
TColorDepth ColorDepth;
|
||||||
|
uint OrigHeight;
|
||||||
|
float HotspotScale;
|
||||||
|
uint HotspotOffsetX;
|
||||||
|
uint HotspotOffsetY;
|
||||||
|
sint HotSpotX;
|
||||||
|
sint HotSpotY;
|
||||||
|
nlCursor Cursor;
|
||||||
|
NLMISC::CRGBA Col;
|
||||||
|
uint8 Rot;
|
||||||
|
#if defined(NL_OS_UNIX) && !defined(NL_OS_MAC)
|
||||||
|
Display *Dpy;
|
||||||
|
#endif
|
||||||
|
public:
|
||||||
|
CCursor();
|
||||||
|
~CCursor();
|
||||||
|
CCursor& operator= (const CCursor& from);
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CStrCaseUnsensitiveCmp
|
||||||
|
{
|
||||||
|
bool operator()(const std::string &lhs, const std::string &rhs) const
|
||||||
|
{
|
||||||
|
return NLMISC::nlstricmp(lhs, rhs) < 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::map<std::string, CCursor, CStrCaseUnsensitiveCmp> TCursorMap;
|
||||||
|
|
||||||
|
TCursorMap _Cursors;
|
||||||
|
|
||||||
// Directx
|
// Directx
|
||||||
uint32 _Adapter;
|
uint32 _Adapter;
|
||||||
|
@ -2393,6 +2460,34 @@ public:
|
||||||
// Build 16 bit index buffer for quad
|
// Build 16 bit index buffer for quad
|
||||||
bool buildQuadIndexBuffer();
|
bool buildQuadIndexBuffer();
|
||||||
|
|
||||||
|
// Test if cursor is in the client area. always true when software cursor is used and window visible
|
||||||
|
// (displayed in software when DirectInput is used)
|
||||||
|
bool isSystemCursorInClientArea();
|
||||||
|
|
||||||
|
// Check if RGBA cursors are supported
|
||||||
|
bool isAlphaBlendedCursorSupported();
|
||||||
|
|
||||||
|
// Update cursor appearance
|
||||||
|
void updateCursor(bool forceRebuild = false);
|
||||||
|
|
||||||
|
// Create default cursors
|
||||||
|
void createCursors();
|
||||||
|
|
||||||
|
// Release all cursors
|
||||||
|
void releaseCursors();
|
||||||
|
|
||||||
|
// Convert a NLMISC::CBitmap to nlCursor
|
||||||
|
bool convertBitmapToCursor(const NLMISC::CBitmap &bitmap, nlCursor &cursor, uint iconWidth, uint iconHeight, uint iconDepth, const NLMISC::CRGBA &col, sint hotSpotX, sint hotSpotY);
|
||||||
|
|
||||||
|
// build a cursor from src, src should have the same size that the hardware cursor
|
||||||
|
// or a assertion is thrown
|
||||||
|
nlCursor buildCursor(const NLMISC::CBitmap &src, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY);
|
||||||
|
|
||||||
|
// reset the cursor shape to the system arrow
|
||||||
|
void setSystemArrow();
|
||||||
|
|
||||||
|
bool convertBitmapToIcon(const NLMISC::CBitmap &bitmap, HICON &icon, uint iconWidth, uint iconHeight, uint iconDepth, const NLMISC::CRGBA &col = NLMISC::CRGBA::White, sint hotSpotX = 0, sint hotSpotY = 0, bool cursor = false);
|
||||||
|
|
||||||
virtual bool copyTextToClipboard(const ucstring &text);
|
virtual bool copyTextToClipboard(const ucstring &text);
|
||||||
virtual bool pasteTextFromClipboard(ucstring &text);
|
virtual bool pasteTextFromClipboard(ucstring &text);
|
||||||
|
|
||||||
|
|
|
@ -26,131 +26,529 @@ using namespace NLMISC;
|
||||||
namespace NL3D
|
namespace NL3D
|
||||||
{
|
{
|
||||||
|
|
||||||
// ***************************************************************************
|
// *************************************************************************************
|
||||||
|
CDriverD3D::CCursor::CCursor() : ColorDepth(CDriverD3D::ColorDepth32),
|
||||||
|
OrigHeight(32),
|
||||||
|
HotspotScale(1.f),
|
||||||
|
HotspotOffsetX(0),
|
||||||
|
HotspotOffsetY(0),
|
||||||
|
HotSpotX(0),
|
||||||
|
HotSpotY(0),
|
||||||
|
Cursor(EmptyCursor),
|
||||||
|
Col(CRGBA::White),
|
||||||
|
Rot(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void CDriverD3D::showCursor (bool b)
|
// *************************************************************************************
|
||||||
|
CDriverD3D::CCursor::~CCursor()
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
void CDriverD3D::CCursor::reset()
|
||||||
|
{
|
||||||
|
if (Cursor != EmptyCursor)
|
||||||
|
{
|
||||||
|
DestroyIcon(Cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
CDriverD3D::CCursor& CDriverD3D::CCursor::operator= (const CDriverD3D::CCursor& from)
|
||||||
|
{
|
||||||
|
if (&from == this)
|
||||||
|
return *this;
|
||||||
|
Src = from.Src; // requires more than a surface copy
|
||||||
|
OrigHeight = from.OrigHeight;
|
||||||
|
HotspotScale = from.HotspotScale;
|
||||||
|
HotspotOffsetX = from.HotspotOffsetX;
|
||||||
|
HotspotOffsetY = from.HotspotOffsetY;
|
||||||
|
HotSpotX = from.HotSpotX;
|
||||||
|
HotSpotY = from.HotSpotY;
|
||||||
|
Cursor = from.Cursor;
|
||||||
|
Col = from.Col;
|
||||||
|
Rot = from.Rot;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
bool CDriverD3D::isAlphaBlendedCursorSupported()
|
||||||
|
{
|
||||||
|
if (!_AlphaBlendedCursorSupportRetrieved)
|
||||||
|
{
|
||||||
|
// Support starts with windows 2000 (not only from XP as seen in most docs)
|
||||||
|
// NB : Additionnaly, could query D3D caps to know if
|
||||||
|
// color hardware cursor is supported, not only emulated,
|
||||||
|
// but can't be sure that using the win32 api 'SetCursor' uses the same resources
|
||||||
|
// So far, seems to be supported on any modern card used by the game anyway ...
|
||||||
|
OSVERSIONINFO osvi;
|
||||||
|
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||||
|
if (GetVersionEx(&osvi))
|
||||||
|
{
|
||||||
|
_AlphaBlendedCursorSupported = (osvi.dwMajorVersion >= 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
_AlphaBlendedCursorSupportRetrieved = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _AlphaBlendedCursorSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
void CDriverD3D::addCursor(const std::string &name, const NLMISC::CBitmap &cursorBitmap)
|
||||||
|
{
|
||||||
|
if (!isAlphaBlendedCursorSupported()) return;
|
||||||
|
|
||||||
|
nlassert(cursorBitmap.getWidth() != 0);
|
||||||
|
nlassert(cursorBitmap.getHeight() != 0);
|
||||||
|
|
||||||
|
// find used part base on alpha, to avoid too much shrinking
|
||||||
|
const CRGBA *pixels = (const CRGBA *) &cursorBitmap.getPixels()[0];
|
||||||
|
uint minX, maxX, minY, maxY;
|
||||||
|
uint width = cursorBitmap.getWidth();
|
||||||
|
uint height = cursorBitmap.getHeight();
|
||||||
|
//
|
||||||
|
minX = 0;
|
||||||
|
for (uint x = 0; x < width; ++x)
|
||||||
|
{
|
||||||
|
bool stop = false;
|
||||||
|
minX = x;
|
||||||
|
for (uint y = 0; y < height; ++y)
|
||||||
|
{
|
||||||
|
if(pixels[x + y * width].A != 0)
|
||||||
|
{
|
||||||
|
stop = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stop) break;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
maxX = width - 1;
|
||||||
|
for (sint x = width - 1; x >= 0; --x)
|
||||||
|
{
|
||||||
|
bool stop = false;
|
||||||
|
maxX = (uint) x;
|
||||||
|
for (uint y = 0; y < height; ++y)
|
||||||
|
{
|
||||||
|
if(pixels[x + y * width].A != 0)
|
||||||
|
{
|
||||||
|
stop = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stop) break;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
minY = 0;
|
||||||
|
for (uint y = 0; y < height; ++y)
|
||||||
|
{
|
||||||
|
bool stop = false;
|
||||||
|
minY = y;
|
||||||
|
for (uint x = 0; x < width; ++x)
|
||||||
|
{
|
||||||
|
if(pixels[x + y * width].A != 0)
|
||||||
|
{
|
||||||
|
stop = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stop) break;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
maxY = height - 1;
|
||||||
|
for (sint y = height - 1; y >= 0; --y)
|
||||||
|
{
|
||||||
|
bool stop = false;
|
||||||
|
maxY = (uint) y;
|
||||||
|
for (uint x = 0; x < width; ++x)
|
||||||
|
{
|
||||||
|
if(pixels[x + y * width].A != 0)
|
||||||
|
{
|
||||||
|
stop = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stop) break;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
CCursor &curs = _Cursors[name];
|
||||||
|
curs = CCursor(); // erase possible previous cursor
|
||||||
|
|
||||||
|
uint destWidth;
|
||||||
|
uint destHeight;
|
||||||
|
|
||||||
|
destWidth = GetSystemMetrics(SM_CXCURSOR);
|
||||||
|
destHeight = GetSystemMetrics(SM_CYCURSOR);
|
||||||
|
|
||||||
|
// build a square bitmap
|
||||||
|
uint tmpSize = std::max(maxX - minX + 1, maxY - minY + 1);
|
||||||
|
curs.Src.resize(tmpSize, tmpSize);
|
||||||
|
// blit at top left corner
|
||||||
|
curs.Src.blit(cursorBitmap, minX, minY, maxX - minX + 1, maxY - minY + 1, 0, 0);
|
||||||
|
|
||||||
|
curs.OrigHeight = cursorBitmap.getHeight();
|
||||||
|
curs.HotspotOffsetX = minX;
|
||||||
|
curs.HotspotOffsetY = minY;
|
||||||
|
//
|
||||||
|
curs.HotspotScale = _CursorScale;
|
||||||
|
clamp(curs.HotspotScale, 0.f, 1.f);
|
||||||
|
// first resampling, same for all cursors
|
||||||
|
tmpSize = (uint) (tmpSize * curs.HotspotScale);
|
||||||
|
if (tmpSize == 0) tmpSize = 1;
|
||||||
|
/*
|
||||||
|
curs.Src.resample(tmpSize, tmpSize);
|
||||||
|
*/
|
||||||
|
// shrink if necessary
|
||||||
|
if (tmpSize > destWidth || tmpSize > destHeight) // need to shrink ?
|
||||||
|
{
|
||||||
|
// constraint proportions
|
||||||
|
curs.HotspotScale *= std::min(float(destWidth) / tmpSize, float(destHeight) / tmpSize);
|
||||||
|
curs.Src.resample(destWidth, destHeight);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CBitmap final;
|
||||||
|
final.resize(destWidth, destHeight);
|
||||||
|
final.blit(&curs.Src, 0, 0);
|
||||||
|
curs.Src.swap(final);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name == _CurrName)
|
||||||
|
{
|
||||||
|
updateCursor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
void CDriverD3D::createCursors()
|
||||||
|
{
|
||||||
|
_DefaultCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
void CDriverD3D::releaseCursors()
|
||||||
|
{
|
||||||
|
SetClassLongPtr(_HWnd, GCLP_HCURSOR, 0);
|
||||||
|
|
||||||
|
_Cursors.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
void CDriverD3D::updateCursor(bool forceRebuild)
|
||||||
|
{
|
||||||
|
setCursor(_CurrName, _CurrCol, _CurrRot, _CurrHotSpotX, _CurrHotSpotY, forceRebuild);
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
void CDriverD3D::setCursor(const std::string &name, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY, bool forceRebuild)
|
||||||
|
{
|
||||||
|
// don't update cursor if it's hidden or if custom cursors are not suppported
|
||||||
|
if (!isAlphaBlendedCursorSupported() || _CurrName == "none") return;
|
||||||
|
|
||||||
|
_CurrName = name;
|
||||||
|
_CurrCol = col;
|
||||||
|
_CurrRot = rot;
|
||||||
|
_CurrHotSpotX = hotSpotX;
|
||||||
|
_CurrHotSpotY = hotSpotY;
|
||||||
|
|
||||||
|
// cursor has to be changed next time
|
||||||
|
if (_CurrName.empty()) return;
|
||||||
|
|
||||||
|
if (rot > 3) rot = 3; // same than 'CViewRenderer::drawRotFlipBitmapTiled
|
||||||
|
|
||||||
|
TCursorMap::iterator it = _Cursors.find(name);
|
||||||
|
|
||||||
|
nlCursor cursorHandle = _DefaultCursor;
|
||||||
|
|
||||||
|
if (it != _Cursors.end())
|
||||||
|
{
|
||||||
|
// Update cursor if modified or not already built
|
||||||
|
CCursor &curs = it->second;
|
||||||
|
hotSpotX = (sint) (curs.HotspotScale * (hotSpotX - curs.HotspotOffsetX));
|
||||||
|
hotSpotY = (sint) (curs.HotspotScale * ((curs.OrigHeight - hotSpotY) - curs.HotspotOffsetY));
|
||||||
|
if (curs.Cursor == EmptyCursor ||
|
||||||
|
curs.HotSpotX != hotSpotX ||
|
||||||
|
curs.HotSpotY != hotSpotY ||
|
||||||
|
curs.Col != col ||
|
||||||
|
curs.Rot != rot ||
|
||||||
|
curs.ColorDepth != _ColorDepth ||
|
||||||
|
forceRebuild
|
||||||
|
)
|
||||||
|
{
|
||||||
|
curs.reset();
|
||||||
|
curs.Cursor = buildCursor(curs.Src, col, rot, hotSpotX, hotSpotY);
|
||||||
|
curs.Col = col;
|
||||||
|
curs.Rot = rot;
|
||||||
|
curs.HotSpotX = hotSpotX;
|
||||||
|
curs.HotSpotY = hotSpotY;
|
||||||
|
curs.ColorDepth = _ColorDepth;
|
||||||
|
}
|
||||||
|
cursorHandle = curs.Cursor ? curs.Cursor : _DefaultCursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSystemCursorInClientArea() || isSystemCursorCaptured() || forceRebuild)
|
||||||
|
{
|
||||||
|
// if (CInputHandlerManager::getInstance()->hasFocus())
|
||||||
|
{
|
||||||
|
::SetCursor(cursorHandle);
|
||||||
|
SetClassLongPtr(_HWnd, GCLP_HCURSOR, (LONG_PTR) cursorHandle); // set default mouse icon to the last one
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
nlCursor CDriverD3D::buildCursor(const CBitmap &src, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY)
|
||||||
|
{
|
||||||
|
nlassert(isAlphaBlendedCursorSupported());
|
||||||
|
|
||||||
|
uint mouseW;
|
||||||
|
uint mouseH;
|
||||||
|
|
||||||
|
// use cursor size from system
|
||||||
|
mouseW = GetSystemMetrics(SM_CXCURSOR);
|
||||||
|
mouseH = GetSystemMetrics(SM_CYCURSOR);
|
||||||
|
|
||||||
|
CBitmap rotSrc = src;
|
||||||
|
if (rot > 3) rot = 3; // mimic behavior of 'CViewRenderer::drawRotFlipBitmapTiled' (why not rot & 3 ??? ...)
|
||||||
|
switch(rot)
|
||||||
|
{
|
||||||
|
case 0: break;
|
||||||
|
case 1: rotSrc.rot90CW(); break;
|
||||||
|
case 2: rotSrc.rot90CW(); rotSrc.rot90CW(); break;
|
||||||
|
case 3: rotSrc.rot90CCW(); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a cursor from bitmap
|
||||||
|
nlCursor result = NULL;
|
||||||
|
convertBitmapToCursor(rotSrc, result, mouseW, mouseH, _ColorDepth == ColorDepth16 ? 16:32, col, hotSpotX, hotSpotY);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
void CDriverD3D::setSystemArrow()
|
||||||
|
{
|
||||||
|
H_AUTO_D3D(CDriverD3D_setSystemArrow);
|
||||||
|
|
||||||
|
if (isSystemCursorInClientArea() || isSystemCursorCaptured())
|
||||||
|
{
|
||||||
|
SetCursor(_DefaultCursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set default mouse icon to the default one
|
||||||
|
SetClassLongPtr(_HWnd, GCLP_HCURSOR, (LONG_PTR) _DefaultCursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
void CDriverD3D::showCursor(bool b)
|
||||||
{
|
{
|
||||||
H_AUTO_D3D(CDriverD3D_showCursor);
|
H_AUTO_D3D(CDriverD3D_showCursor);
|
||||||
|
|
||||||
|
if (_HWnd == EmptyWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
if (b)
|
if (b)
|
||||||
{
|
{
|
||||||
while (ShowCursor(b) < 0) {}
|
// update current hardware icon to avoid to have the plain arrow
|
||||||
|
updateCursor(true);
|
||||||
|
|
||||||
|
while (ShowCursor(b) < 0)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while (ShowCursor(b) >= 0) {}
|
while (ShowCursor(b) >= 0)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
|
||||||
void CDriverD3D::setMousePos(float x, float y)
|
void CDriverD3D::setMousePos(float x, float y)
|
||||||
{
|
{
|
||||||
H_AUTO_D3D(CDriver3D_setMousePos);
|
H_AUTO_D3D(CDriverD3D_setMousePos);
|
||||||
if (_HWnd)
|
|
||||||
{
|
if (_HWnd == EmptyWindow)
|
||||||
// NeL window coordinate to MSWindows coordinates
|
return;
|
||||||
POINT pt;
|
|
||||||
pt.x = (int)((float)(_CurrentMode.Width)*x);
|
sint x1 = (sint)((float)_CurrentMode.Width*x);
|
||||||
pt.y = (int)((float)(_CurrentMode.Height)*(1.0f-y));
|
sint y1 = (sint)((float)_CurrentMode.Height*(1.0f-y));
|
||||||
ClientToScreen (_HWnd, &pt);
|
|
||||||
SetCursorPos(pt.x, pt.y);
|
// NeL window coordinate to MSWindows coordinates
|
||||||
}
|
POINT pt;
|
||||||
|
pt.x = x1;
|
||||||
|
pt.y = y1;
|
||||||
|
ClientToScreen (_HWnd, &pt);
|
||||||
|
SetCursorPos(pt.x, pt.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
bool CDriverD3D::isSystemCursorInClientArea()
|
||||||
|
{
|
||||||
|
if (_FullScreen /* || !IsMouseCursorHardware() */)
|
||||||
|
{
|
||||||
|
return IsWindowVisible(_HWnd) != FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
POINT cursPos;
|
||||||
|
// the mouse should be in the client area of the window
|
||||||
|
if (!GetCursorPos(&cursPos))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
HWND wnd = WindowFromPoint(cursPos);
|
||||||
|
if (wnd != _HWnd)
|
||||||
|
{
|
||||||
|
return false; // not the same window
|
||||||
|
}
|
||||||
|
// want that the mouse be in the client area
|
||||||
|
RECT clientRect;
|
||||||
|
if (!GetClientRect(_HWnd, &clientRect))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
POINT tl, br;
|
||||||
|
tl.x = clientRect.left;
|
||||||
|
tl.y = clientRect.top;
|
||||||
|
br.x = clientRect.right;
|
||||||
|
br.y = clientRect.bottom;
|
||||||
|
if (!ClientToScreen(_HWnd, &tl))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!ClientToScreen(_HWnd, &br))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((cursPos.x < tl.x) || (cursPos.x >= br.x) || (cursPos.y < tl.y) || (cursPos.y >= br.y))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
void CDriverD3D::setCapture (bool b)
|
void CDriverD3D::setCapture (bool b)
|
||||||
{
|
{
|
||||||
if (b)
|
H_AUTO_D3D(CDriverD3D_setCapture);
|
||||||
|
|
||||||
|
if (b && isSystemCursorInClientArea() && !isSystemCursorCaptured())
|
||||||
{
|
{
|
||||||
RECT client;
|
SetCapture(_HWnd);
|
||||||
GetClientRect (_HWnd, &client);
|
}
|
||||||
POINT pt1,pt2;
|
else if (!b && isSystemCursorCaptured())
|
||||||
pt1.x = client.left;
|
{
|
||||||
pt1.y = client.top;
|
// if hardware mouse and not in client area, then force to update its aspect by updating its pos
|
||||||
ClientToScreen (_HWnd, &pt1);
|
if (!isSystemCursorInClientArea())
|
||||||
pt2.x = client.right;
|
{
|
||||||
pt2.y = client.bottom;
|
// force update
|
||||||
ClientToScreen (_HWnd, &pt2);
|
showCursor(true);
|
||||||
client.bottom = pt2.y;
|
}
|
||||||
client.top = pt1.y;
|
|
||||||
client.left = pt1.x;
|
ReleaseCapture();
|
||||||
client.right = pt2.x;
|
|
||||||
ClipCursor (&client);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
ClipCursor (NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
bool CDriverD3D::isSystemCursorCaptured()
|
||||||
|
{
|
||||||
|
H_AUTO_D3D(CDriverD3D_isSystemCursorCaptured);
|
||||||
|
|
||||||
NLMISC::IMouseDevice *CDriverD3D::enableLowLevelMouse(bool enable, bool exclusive)
|
return GetCapture() == _HWnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
NLMISC::IMouseDevice* CDriverD3D::enableLowLevelMouse(bool enable, bool exclusive)
|
||||||
{
|
{
|
||||||
H_AUTO_D3D(CDriverD3D_enableLowLevelMouse);
|
H_AUTO_D3D(CDriverD3D_enableLowLevelMouse);
|
||||||
if (_EventEmitter.getNumEmitters() < 2)
|
|
||||||
return NULL;
|
NLMISC::IMouseDevice *res = NULL;
|
||||||
NLMISC::CDIEventEmitter *diee = NLMISC::safe_cast<CDIEventEmitter *>(_EventEmitter.getEmitter(1));
|
|
||||||
|
NLMISC::CDIEventEmitter *diee = NULL;
|
||||||
|
|
||||||
|
if (_EventEmitter.getNumEmitters() > 1)
|
||||||
|
diee = NLMISC::safe_cast<CDIEventEmitter *>(_EventEmitter.getEmitter(1));
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
NLMISC::IMouseDevice *md = diee->getMouseDevice(exclusive);
|
if (diee)
|
||||||
return md;
|
res = diee->getMouseDevice(exclusive);
|
||||||
}
|
}
|
||||||
catch (EDirectInput &)
|
catch (EDirectInput &)
|
||||||
{
|
{
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
diee->releaseMouse();
|
if (diee)
|
||||||
return NULL;
|
diee->releaseMouse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
NLMISC::IKeyboardDevice* CDriverD3D::enableLowLevelKeyboard(bool enable)
|
||||||
NLMISC::IKeyboardDevice *CDriverD3D::enableLowLevelKeyboard(bool enable)
|
|
||||||
{
|
{
|
||||||
H_AUTO_D3D(CDriverD3D_enableLowLevelKeyboard);
|
H_AUTO_D3D(CDriverD3D_enableLowLevelKeyboard);
|
||||||
if (_EventEmitter.getNumEmitters() < 2) return NULL;
|
|
||||||
NLMISC::CDIEventEmitter *diee = NLMISC::safe_cast<NLMISC::CDIEventEmitter *>(_EventEmitter.getEmitter(1));
|
NLMISC::IKeyboardDevice *res = NULL;
|
||||||
|
|
||||||
|
NLMISC::CDIEventEmitter *diee = NULL;
|
||||||
|
|
||||||
|
if (_EventEmitter.getNumEmitters() > 1)
|
||||||
|
diee = NLMISC::safe_cast<NLMISC::CDIEventEmitter *>(_EventEmitter.getEmitter(1));
|
||||||
|
|
||||||
if (enable)
|
if (enable)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
NLMISC::IKeyboardDevice *md = diee->getKeyboardDevice();
|
if (diee)
|
||||||
return md;
|
res = diee->getKeyboardDevice();
|
||||||
}
|
}
|
||||||
catch (EDirectInput &)
|
catch (EDirectInput &)
|
||||||
{
|
{
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
diee->releaseKeyboard();
|
if (diee)
|
||||||
return NULL;
|
diee->releaseKeyboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
NLMISC::IInputDeviceManager* CDriverD3D::getLowLevelInputDeviceManager()
|
||||||
NLMISC::IInputDeviceManager *CDriverD3D::getLowLevelInputDeviceManager()
|
|
||||||
{
|
{
|
||||||
H_AUTO_D3D(CDriverD3D_getLowLevelInputDeviceManager);
|
H_AUTO_D3D(CDriverD3D_getLowLevelInputDeviceManager);
|
||||||
if (_EventEmitter.getNumEmitters() < 2) return NULL;
|
|
||||||
NLMISC::CDIEventEmitter *diee = NLMISC::safe_cast<NLMISC::CDIEventEmitter *>(_EventEmitter.getEmitter(1));
|
NLMISC::IInputDeviceManager *res = NULL;
|
||||||
return diee;
|
|
||||||
|
if (_EventEmitter.getNumEmitters() > 1)
|
||||||
|
res = NLMISC::safe_cast<NLMISC::CDIEventEmitter *>(_EventEmitter.getEmitter(1));
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
|
||||||
uint CDriverD3D::getDoubleClickDelay(bool hardwareMouse)
|
uint CDriverD3D::getDoubleClickDelay(bool hardwareMouse)
|
||||||
{
|
{
|
||||||
H_AUTO_D3D(CDriverD3D_getDoubleClickDelay);
|
H_AUTO_D3D(CDriverD3D_getDoubleClickDelay);
|
||||||
|
|
||||||
|
uint res = 250;
|
||||||
|
|
||||||
NLMISC::IMouseDevice *md = NULL;
|
NLMISC::IMouseDevice *md = NULL;
|
||||||
|
|
||||||
if (_EventEmitter.getNumEmitters() >= 2)
|
if (_EventEmitter.getNumEmitters() >= 2)
|
||||||
{
|
{
|
||||||
NLMISC::CDIEventEmitter *diee = NLMISC::safe_cast<CDIEventEmitter *>(_EventEmitter.getEmitter(1));
|
NLMISC::CDIEventEmitter *diee = NLMISC::safe_cast<CDIEventEmitter *>(_EventEmitter.getEmitter(1));
|
||||||
|
@ -166,14 +564,18 @@ uint CDriverD3D::getDoubleClickDelay(bool hardwareMouse)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (md)
|
if (md)
|
||||||
{
|
{
|
||||||
return md->getDoubleClickDelay();
|
res = md->getDoubleClickDelay();
|
||||||
}
|
}
|
||||||
// try to read the good value from windows
|
else
|
||||||
return ::GetDoubleClickTime();
|
{
|
||||||
|
// try to read the good value from windows
|
||||||
|
res = ::GetDoubleClickTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
|
|
||||||
} // NL3D
|
} // NL3D
|
||||||
|
|
|
@ -202,7 +202,6 @@ CDriverGL::CDriverGL()
|
||||||
|
|
||||||
#elif defined (NL_OS_UNIX)
|
#elif defined (NL_OS_UNIX)
|
||||||
|
|
||||||
_cursor = None;
|
|
||||||
_dpy = 0;
|
_dpy = 0;
|
||||||
_visual_info = NULL;
|
_visual_info = NULL;
|
||||||
|
|
||||||
|
@ -213,6 +212,20 @@ CDriverGL::CDriverGL()
|
||||||
|
|
||||||
#endif // NL_OS_UNIX
|
#endif // NL_OS_UNIX
|
||||||
|
|
||||||
|
_ColorDepth = ColorDepth32;
|
||||||
|
|
||||||
|
_DefaultCursor = EmptyCursor;
|
||||||
|
_BlankCursor = EmptyCursor;
|
||||||
|
|
||||||
|
_AlphaBlendedCursorSupported = false;
|
||||||
|
_AlphaBlendedCursorSupportRetrieved = false;
|
||||||
|
_CurrCol = CRGBA::White;
|
||||||
|
_CurrRot = 0;
|
||||||
|
_CurrHotSpotX = 0;
|
||||||
|
_CurrHotSpotY = 0;
|
||||||
|
_CursorScale = 0.85f;
|
||||||
|
_MouseCaptured = false;
|
||||||
|
|
||||||
_NeedToRestaureGammaRamp = false;
|
_NeedToRestaureGammaRamp = false;
|
||||||
_Interval = 1;
|
_Interval = 1;
|
||||||
|
|
||||||
|
|
|
@ -116,14 +116,20 @@ class COcclusionQueryGL;
|
||||||
#ifdef NL_OS_WINDOWS
|
#ifdef NL_OS_WINDOWS
|
||||||
|
|
||||||
bool GlWndProc(CDriverGL *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
bool GlWndProc(CDriverGL *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
|
typedef HCURSOR nlCursor;
|
||||||
|
#define EmptyCursor NULL
|
||||||
|
|
||||||
#elif defined (NL_OS_MAC)
|
#elif defined (NL_OS_MAC)
|
||||||
|
|
||||||
bool GlWndProc(CDriverGL *driver, const void* e);
|
bool GlWndProc(CDriverGL *driver, const void* e);
|
||||||
|
typedef void* nlCursor;
|
||||||
|
#define EmptyCursor NULL
|
||||||
|
|
||||||
#elif defined (NL_OS_UNIX)
|
#elif defined (NL_OS_UNIX)
|
||||||
|
|
||||||
bool GlWndProc(CDriverGL *driver, XEvent &e);
|
bool GlWndProc(CDriverGL *driver, XEvent &e);
|
||||||
|
typedef Cursor nlCursor;
|
||||||
|
#define EmptyCursor None
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -514,6 +520,17 @@ public:
|
||||||
|
|
||||||
virtual void setCapture (bool b);
|
virtual void setCapture (bool b);
|
||||||
|
|
||||||
|
// see if system cursor is currently captured
|
||||||
|
virtual bool isSystemCursorCaptured();
|
||||||
|
|
||||||
|
virtual void setHardwareCursorScale(float scale) { _CursorScale = scale; }
|
||||||
|
|
||||||
|
// Add a new cursor (name is case unsensitive)
|
||||||
|
virtual void addCursor(const std::string &name, const NLMISC::CBitmap &bitmap);
|
||||||
|
|
||||||
|
// Display a cursor from its name (case unsensitive)
|
||||||
|
virtual void setCursor(const std::string &name, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY, bool forceRebuild = false);
|
||||||
|
|
||||||
virtual NLMISC::IMouseDevice *enableLowLevelMouse(bool enable, bool exclusive);
|
virtual NLMISC::IMouseDevice *enableLowLevelMouse(bool enable, bool exclusive);
|
||||||
|
|
||||||
virtual NLMISC::IKeyboardDevice *enableLowLevelKeyboard(bool enable);
|
virtual NLMISC::IKeyboardDevice *enableLowLevelKeyboard(bool enable);
|
||||||
|
@ -692,8 +709,65 @@ private:
|
||||||
sint32 _DecorationWidth;
|
sint32 _DecorationWidth;
|
||||||
sint32 _DecorationHeight;
|
sint32 _DecorationHeight;
|
||||||
|
|
||||||
|
// cursors
|
||||||
|
enum TColorDepth { ColorDepth16 = 0, ColorDepth32, ColorDepthCount };
|
||||||
|
|
||||||
|
TColorDepth _ColorDepth;
|
||||||
|
std::string _CurrName;
|
||||||
|
NLMISC::CRGBA _CurrCol;
|
||||||
|
uint8 _CurrRot;
|
||||||
|
uint _CurrHotSpotX;
|
||||||
|
uint _CurrHotSpotY;
|
||||||
|
float _CursorScale;
|
||||||
|
bool _MouseCaptured;
|
||||||
|
|
||||||
|
nlCursor _DefaultCursor;
|
||||||
|
nlCursor _BlankCursor;
|
||||||
|
|
||||||
|
bool _AlphaBlendedCursorSupported;
|
||||||
|
bool _AlphaBlendedCursorSupportRetrieved;
|
||||||
|
|
||||||
|
class CCursor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NLMISC::CBitmap Src;
|
||||||
|
TColorDepth ColorDepth;
|
||||||
|
uint OrigHeight;
|
||||||
|
float HotspotScale;
|
||||||
|
uint HotspotOffsetX;
|
||||||
|
uint HotspotOffsetY;
|
||||||
|
sint HotSpotX;
|
||||||
|
sint HotSpotY;
|
||||||
|
nlCursor Cursor;
|
||||||
|
NLMISC::CRGBA Col;
|
||||||
|
uint8 Rot;
|
||||||
|
#if defined(NL_OS_UNIX) && !defined(NL_OS_MAC)
|
||||||
|
Display *Dpy;
|
||||||
|
#endif
|
||||||
|
public:
|
||||||
|
CCursor();
|
||||||
|
~CCursor();
|
||||||
|
CCursor& operator= (const CCursor& from);
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CStrCaseUnsensitiveCmp
|
||||||
|
{
|
||||||
|
bool operator()(const std::string &lhs, const std::string &rhs) const
|
||||||
|
{
|
||||||
|
return NLMISC::nlstricmp(lhs, rhs) < 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::map<std::string, CCursor, CStrCaseUnsensitiveCmp> TCursorMap;
|
||||||
|
|
||||||
|
TCursorMap _Cursors;
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
#ifdef NL_OS_WINDOWS
|
||||||
|
|
||||||
|
bool convertBitmapToIcon(const NLMISC::CBitmap &bitmap, HICON &icon, uint iconWidth, uint iconHeight, uint iconDepth, const NLMISC::CRGBA &col = NLMISC::CRGBA::White, sint hotSpotX = 0, sint hotSpotY = 0, bool cursor = false);
|
||||||
|
|
||||||
friend bool GlWndProc(CDriverGL *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
friend bool GlWndProc(CDriverGL *driver, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
HDC _hDC;
|
HDC _hDC;
|
||||||
|
@ -724,11 +798,12 @@ private:
|
||||||
|
|
||||||
#elif defined (NL_OS_UNIX)
|
#elif defined (NL_OS_UNIX)
|
||||||
|
|
||||||
|
bool convertBitmapToIcon(const NLMISC::CBitmap &bitmap, std::vector<long> &icon);
|
||||||
|
|
||||||
friend bool GlWndProc(CDriverGL *driver, XEvent &e);
|
friend bool GlWndProc(CDriverGL *driver, XEvent &e);
|
||||||
|
|
||||||
Display* _dpy;
|
Display* _dpy;
|
||||||
GLXContext _ctx;
|
GLXContext _ctx;
|
||||||
Cursor _cursor;
|
|
||||||
NLMISC::CUnixEventEmitter _EventEmitter;
|
NLMISC::CUnixEventEmitter _EventEmitter;
|
||||||
XVisualInfo* _visual_info;
|
XVisualInfo* _visual_info;
|
||||||
uint32 _xrandr_version;
|
uint32 _xrandr_version;
|
||||||
|
@ -908,6 +983,32 @@ private:
|
||||||
bool saveScreenMode();
|
bool saveScreenMode();
|
||||||
bool setScreenMode(const GfxMode &mode);
|
bool setScreenMode(const GfxMode &mode);
|
||||||
|
|
||||||
|
// Test if cursor is in the client area. always true when software cursor is used and window visible
|
||||||
|
// (displayed in software when DirectInput is used)
|
||||||
|
bool isSystemCursorInClientArea();
|
||||||
|
|
||||||
|
// Check if RGBA cursors are supported
|
||||||
|
bool isAlphaBlendedCursorSupported();
|
||||||
|
|
||||||
|
// Update cursor appearance
|
||||||
|
void updateCursor(bool forceRebuild = false);
|
||||||
|
|
||||||
|
// Create default cursors
|
||||||
|
void createCursors();
|
||||||
|
|
||||||
|
// Release all cursors
|
||||||
|
void releaseCursors();
|
||||||
|
|
||||||
|
// Convert a NLMISC::CBitmap to nlCursor
|
||||||
|
bool convertBitmapToCursor(const NLMISC::CBitmap &bitmap, nlCursor &cursor, uint iconWidth, uint iconHeight, uint iconDepth, const NLMISC::CRGBA &col, sint hotSpotX, sint hotSpotY);
|
||||||
|
|
||||||
|
// build a cursor from src, src should have the same size that the hardware cursor
|
||||||
|
// or a assertion is thrown
|
||||||
|
nlCursor buildCursor(const NLMISC::CBitmap &src, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY);
|
||||||
|
|
||||||
|
// reset the cursor shape to the system arrow
|
||||||
|
void setSystemArrow();
|
||||||
|
|
||||||
// Get the proj matrix setupped in GL
|
// Get the proj matrix setupped in GL
|
||||||
void refreshProjMatrixFromGL();
|
void refreshProjMatrixFromGL();
|
||||||
|
|
||||||
|
|
808
code/nel/src/3d/driver/opengl/driver_opengl_inputs.cpp
Normal file
808
code/nel/src/3d/driver/opengl/driver_opengl_inputs.cpp
Normal file
|
@ -0,0 +1,808 @@
|
||||||
|
// 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"
|
||||||
|
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
# include <windowsx.h>
|
||||||
|
#elif defined(NL_OS_MAC)
|
||||||
|
#elif defined (NL_OS_UNIX)
|
||||||
|
# include <GL/gl.h>
|
||||||
|
# include <GL/glx.h>
|
||||||
|
# include <X11/Xatom.h>
|
||||||
|
#endif // NL_OS_UNIX
|
||||||
|
|
||||||
|
#include "nel/misc/mouse_device.h"
|
||||||
|
#include "nel/misc/di_event_emitter.h"
|
||||||
|
#include "nel/3d/u_driver.h"
|
||||||
|
#include "nel/misc/file.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace NLMISC;
|
||||||
|
|
||||||
|
namespace NL3D
|
||||||
|
{
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
CDriverGL::CCursor::CCursor() : ColorDepth(CDriverGL::ColorDepth32),
|
||||||
|
OrigHeight(32),
|
||||||
|
HotspotScale(1.f),
|
||||||
|
HotspotOffsetX(0),
|
||||||
|
HotspotOffsetY(0),
|
||||||
|
HotSpotX(0),
|
||||||
|
HotSpotY(0),
|
||||||
|
Cursor(EmptyCursor),
|
||||||
|
Col(CRGBA::White),
|
||||||
|
Rot(0)
|
||||||
|
{
|
||||||
|
#if defined(NL_OS_UNIX) && !defined(NL_OS_MAC)
|
||||||
|
Dpy = NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
CDriverGL::CCursor::~CCursor()
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
void CDriverGL::CCursor::reset()
|
||||||
|
{
|
||||||
|
if (Cursor != EmptyCursor)
|
||||||
|
{
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
DestroyIcon(Cursor);
|
||||||
|
#elif defined(NL_OS_MAC)
|
||||||
|
#elif defined(NL_OS_UNIX)
|
||||||
|
XFreeCursor(Dpy, Cursor);
|
||||||
|
XSync(Dpy, False);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
CDriverGL::CCursor& CDriverGL::CCursor::operator= (const CDriverGL::CCursor& from)
|
||||||
|
{
|
||||||
|
if (&from == this)
|
||||||
|
return *this;
|
||||||
|
Src = from.Src; // requires more than a surface copy
|
||||||
|
OrigHeight = from.OrigHeight;
|
||||||
|
HotspotScale = from.HotspotScale;
|
||||||
|
HotspotOffsetX = from.HotspotOffsetX;
|
||||||
|
HotspotOffsetY = from.HotspotOffsetY;
|
||||||
|
HotSpotX = from.HotSpotX;
|
||||||
|
HotSpotY = from.HotSpotY;
|
||||||
|
Cursor = from.Cursor;
|
||||||
|
Col = from.Col;
|
||||||
|
Rot = from.Rot;
|
||||||
|
#if defined(NL_OS_UNIX) && !defined(NL_OS_MAC)
|
||||||
|
Dpy = from.Dpy;
|
||||||
|
#endif
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
bool CDriverGL::isAlphaBlendedCursorSupported()
|
||||||
|
{
|
||||||
|
if (!_AlphaBlendedCursorSupportRetrieved)
|
||||||
|
{
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
// Support starts with windows 2000 (not only from XP as seen in most docs)
|
||||||
|
// NB : Additionnaly, could query D3D caps to know if
|
||||||
|
// color hardware cursor is supported, not only emulated,
|
||||||
|
// but can't be sure that using the win32 api 'SetCursor' uses the same resources
|
||||||
|
// So far, seems to be supported on any modern card used by the game anyway ...
|
||||||
|
OSVERSIONINFO osvi;
|
||||||
|
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||||
|
if (GetVersionEx(&osvi))
|
||||||
|
{
|
||||||
|
_AlphaBlendedCursorSupported = (osvi.dwMajorVersion >= 5);
|
||||||
|
}
|
||||||
|
#elif defined(NL_OS_MAC)
|
||||||
|
#elif defined(NL_OS_UNIX)
|
||||||
|
_AlphaBlendedCursorSupported = _xrender_version > 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_AlphaBlendedCursorSupportRetrieved = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _AlphaBlendedCursorSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
void CDriverGL::addCursor(const std::string &name, const NLMISC::CBitmap &cursorBitmap)
|
||||||
|
{
|
||||||
|
if (!isAlphaBlendedCursorSupported()) return;
|
||||||
|
|
||||||
|
nlassert(cursorBitmap.getWidth() != 0);
|
||||||
|
nlassert(cursorBitmap.getHeight() != 0);
|
||||||
|
|
||||||
|
// find used part base on alpha, to avoid too much shrinking
|
||||||
|
const CRGBA *pixels = (const CRGBA *) &cursorBitmap.getPixels()[0];
|
||||||
|
uint minX, maxX, minY, maxY;
|
||||||
|
uint width = cursorBitmap.getWidth();
|
||||||
|
uint height = cursorBitmap.getHeight();
|
||||||
|
//
|
||||||
|
minX = 0;
|
||||||
|
for (uint x = 0; x < width; ++x)
|
||||||
|
{
|
||||||
|
bool stop = false;
|
||||||
|
minX = x;
|
||||||
|
for (uint y = 0; y < height; ++y)
|
||||||
|
{
|
||||||
|
if(pixels[x + y * width].A != 0)
|
||||||
|
{
|
||||||
|
stop = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stop) break;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
maxX = width - 1;
|
||||||
|
for (sint x = width - 1; x >= 0; --x)
|
||||||
|
{
|
||||||
|
bool stop = false;
|
||||||
|
maxX = (uint) x;
|
||||||
|
for (uint y = 0; y < height; ++y)
|
||||||
|
{
|
||||||
|
if(pixels[x + y * width].A != 0)
|
||||||
|
{
|
||||||
|
stop = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stop) break;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
minY = 0;
|
||||||
|
for (uint y = 0; y < height; ++y)
|
||||||
|
{
|
||||||
|
bool stop = false;
|
||||||
|
minY = y;
|
||||||
|
for (uint x = 0; x < width; ++x)
|
||||||
|
{
|
||||||
|
if(pixels[x + y * width].A != 0)
|
||||||
|
{
|
||||||
|
stop = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stop) break;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
maxY = height - 1;
|
||||||
|
for (sint y = height - 1; y >= 0; --y)
|
||||||
|
{
|
||||||
|
bool stop = false;
|
||||||
|
maxY = (uint) y;
|
||||||
|
for (uint x = 0; x < width; ++x)
|
||||||
|
{
|
||||||
|
if(pixels[x + y * width].A != 0)
|
||||||
|
{
|
||||||
|
stop = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stop) break;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
CCursor &curs = _Cursors[name];
|
||||||
|
curs = CCursor(); // erase possible previous cursor
|
||||||
|
|
||||||
|
uint destWidth;
|
||||||
|
uint destHeight;
|
||||||
|
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
|
||||||
|
destWidth = GetSystemMetrics(SM_CXCURSOR);
|
||||||
|
destHeight = GetSystemMetrics(SM_CYCURSOR);
|
||||||
|
|
||||||
|
#elif defined(NL_OS_MAC)
|
||||||
|
#elif defined(NL_OS_UNIX)
|
||||||
|
|
||||||
|
Status res = XQueryBestCursor(_dpy, _win, width, height, &destWidth, &destHeight);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// build a square bitmap
|
||||||
|
uint tmpSize = std::max(maxX - minX + 1, maxY - minY + 1);
|
||||||
|
curs.Src.resize(tmpSize, tmpSize);
|
||||||
|
// blit at top left corner
|
||||||
|
curs.Src.blit(cursorBitmap, minX, minY, maxX - minX + 1, maxY - minY + 1, 0, 0);
|
||||||
|
|
||||||
|
curs.OrigHeight = cursorBitmap.getHeight();
|
||||||
|
curs.HotspotOffsetX = minX;
|
||||||
|
curs.HotspotOffsetY = minY;
|
||||||
|
//
|
||||||
|
curs.HotspotScale = _CursorScale;
|
||||||
|
clamp(curs.HotspotScale, 0.f, 1.f);
|
||||||
|
// first resampling, same for all cursors
|
||||||
|
tmpSize = (uint) (tmpSize * curs.HotspotScale);
|
||||||
|
if (tmpSize == 0) tmpSize = 1;
|
||||||
|
/*
|
||||||
|
curs.Src.resample(tmpSize, tmpSize);
|
||||||
|
*/
|
||||||
|
// shrink if necessary
|
||||||
|
if (tmpSize > destWidth || tmpSize > destHeight) // need to shrink ?
|
||||||
|
{
|
||||||
|
// constraint proportions
|
||||||
|
curs.HotspotScale *= std::min(float(destWidth) / tmpSize, float(destHeight) / tmpSize);
|
||||||
|
curs.Src.resample(destWidth, destHeight);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CBitmap final;
|
||||||
|
final.resize(destWidth, destHeight);
|
||||||
|
final.blit(&curs.Src, 0, 0);
|
||||||
|
curs.Src.swap(final);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name == _CurrName)
|
||||||
|
{
|
||||||
|
updateCursor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
void CDriverGL::createCursors()
|
||||||
|
{
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
_DefaultCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
|
_BlankCursor = NULL;
|
||||||
|
#elif defined(NL_OS_MAC)
|
||||||
|
#elif defined(NL_OS_UNIX)
|
||||||
|
_DefaultCursor = None;
|
||||||
|
|
||||||
|
// create blank cursor
|
||||||
|
char bm_no_data[] = { 0,0,0,0,0,0,0,0 };
|
||||||
|
Pixmap pixmap_no_data = XCreateBitmapFromData (_dpy, _win, bm_no_data, 8, 8);
|
||||||
|
XColor black;
|
||||||
|
memset(&black, 0, sizeof (XColor));
|
||||||
|
black.flags = DoRed | DoGreen | DoBlue;
|
||||||
|
_BlankCursor = XCreatePixmapCursor (_dpy, pixmap_no_data, pixmap_no_data, &black, &black, 0, 0);
|
||||||
|
XFreePixmap(_dpy, pixmap_no_data);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
void CDriverGL::releaseCursors()
|
||||||
|
{
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
SetClassLongPtr(_win, GCLP_HCURSOR, 0);
|
||||||
|
#elif defined(NL_OS_MAC)
|
||||||
|
#elif defined(NL_OS_UNIX)
|
||||||
|
XUndefineCursor(_dpy, _win);
|
||||||
|
XFreeCursor(_dpy, _BlankCursor);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_Cursors.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
void CDriverGL::updateCursor(bool forceRebuild)
|
||||||
|
{
|
||||||
|
setCursor(_CurrName, _CurrCol, _CurrRot, _CurrHotSpotX, _CurrHotSpotY, forceRebuild);
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
void CDriverGL::setCursor(const std::string &name, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY, bool forceRebuild)
|
||||||
|
{
|
||||||
|
// don't update cursor if it's hidden or if custom cursors are not suppported
|
||||||
|
if (!isAlphaBlendedCursorSupported() || _CurrName == "none") return;
|
||||||
|
|
||||||
|
_CurrName = name;
|
||||||
|
_CurrCol = col;
|
||||||
|
_CurrRot = rot;
|
||||||
|
_CurrHotSpotX = hotSpotX;
|
||||||
|
_CurrHotSpotY = hotSpotY;
|
||||||
|
|
||||||
|
// cursor has to be changed next time
|
||||||
|
if (_CurrName.empty()) return;
|
||||||
|
|
||||||
|
if (rot > 3) rot = 3; // same than 'CViewRenderer::drawRotFlipBitmapTiled
|
||||||
|
|
||||||
|
TCursorMap::iterator it = _Cursors.find(name);
|
||||||
|
|
||||||
|
nlCursor cursorHandle = _DefaultCursor;
|
||||||
|
|
||||||
|
if (it != _Cursors.end())
|
||||||
|
{
|
||||||
|
// Update cursor if modified or not already built
|
||||||
|
CCursor &curs = it->second;
|
||||||
|
hotSpotX = (sint) (curs.HotspotScale * (hotSpotX - curs.HotspotOffsetX));
|
||||||
|
hotSpotY = (sint) (curs.HotspotScale * ((curs.OrigHeight - hotSpotY) - curs.HotspotOffsetY));
|
||||||
|
if (curs.Cursor == EmptyCursor ||
|
||||||
|
curs.HotSpotX != hotSpotX ||
|
||||||
|
curs.HotSpotY != hotSpotY ||
|
||||||
|
curs.Col != col ||
|
||||||
|
curs.Rot != rot ||
|
||||||
|
curs.ColorDepth != _ColorDepth ||
|
||||||
|
forceRebuild
|
||||||
|
)
|
||||||
|
{
|
||||||
|
curs.reset();
|
||||||
|
curs.Cursor = buildCursor(curs.Src, col, rot, hotSpotX, hotSpotY);
|
||||||
|
curs.Col = col;
|
||||||
|
curs.Rot = rot;
|
||||||
|
curs.HotSpotX = hotSpotX;
|
||||||
|
curs.HotSpotY = hotSpotY;
|
||||||
|
curs.ColorDepth = _ColorDepth;
|
||||||
|
#if defined(NL_OS_UNIX) && !defined(NL_OS_MAC)
|
||||||
|
curs.Dpy = _dpy;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
cursorHandle = curs.Cursor ? curs.Cursor : _DefaultCursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSystemCursorInClientArea() || isSystemCursorCaptured() || forceRebuild)
|
||||||
|
{
|
||||||
|
// if (CInputHandlerManager::getInstance()->hasFocus())
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
{
|
||||||
|
::SetCursor(cursorHandle);
|
||||||
|
SetClassLongPtr(_win, GCLP_HCURSOR, (LONG_PTR) cursorHandle); // set default mouse icon to the last one
|
||||||
|
}
|
||||||
|
#elif defined(NL_OS_MAC)
|
||||||
|
#elif defined(NL_OS_UNIX)
|
||||||
|
if (cursorHandle == _DefaultCursor)
|
||||||
|
{
|
||||||
|
XUndefineCursor(_dpy, _win);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XDefineCursor(_dpy, _win, cursorHandle);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
nlCursor CDriverGL::buildCursor(const CBitmap &src, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY)
|
||||||
|
{
|
||||||
|
nlassert(isAlphaBlendedCursorSupported());
|
||||||
|
|
||||||
|
uint mouseW;
|
||||||
|
uint mouseH;
|
||||||
|
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
|
||||||
|
// use cursor size from system
|
||||||
|
mouseW = GetSystemMetrics(SM_CXCURSOR);
|
||||||
|
mouseH = GetSystemMetrics(SM_CYCURSOR);
|
||||||
|
|
||||||
|
#elif defined(NL_OS_MAC)
|
||||||
|
#elif defined(NL_OS_UNIX)
|
||||||
|
|
||||||
|
// use best cursor size for bitmap
|
||||||
|
Status res = XQueryBestCursor(_dpy, _win, src.getWidth(), src.getHeight(), &mouseW, &mouseH);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CBitmap rotSrc = src;
|
||||||
|
if (rot > 3) rot = 3; // mimic behavior of 'CViewRenderer::drawRotFlipBitmapTiled' (why not rot & 3 ??? ...)
|
||||||
|
switch(rot)
|
||||||
|
{
|
||||||
|
case 0: break;
|
||||||
|
case 1: rotSrc.rot90CW(); break;
|
||||||
|
case 2: rotSrc.rot90CW(); rotSrc.rot90CW(); break;
|
||||||
|
case 3: rotSrc.rot90CCW(); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a cursor from bitmap
|
||||||
|
nlCursor result = NULL;
|
||||||
|
convertBitmapToCursor(rotSrc, result, mouseW, mouseH, _ColorDepth == ColorDepth16 ? 16:32, col, hotSpotX, hotSpotY);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// *************************************************************************************
|
||||||
|
void CDriverGL::setSystemArrow()
|
||||||
|
{
|
||||||
|
H_AUTO_OGL(CDriverGL_setSystemArrow);
|
||||||
|
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
if (isSystemCursorInClientArea() || isSystemCursorCaptured())
|
||||||
|
{
|
||||||
|
SetCursor(_DefaultCursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set default mouse icon to the default one
|
||||||
|
SetClassLongPtr(_win, GCLP_HCURSOR, (LONG_PTR) _DefaultCursor);
|
||||||
|
#elif defined(NL_OS_MAC)
|
||||||
|
#elif defined(NL_OS_UNIX)
|
||||||
|
XUndefineCursor(_dpy, _win);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
void CDriverGL::showCursor(bool b)
|
||||||
|
{
|
||||||
|
H_AUTO_OGL(CDriverGL_showCursor);
|
||||||
|
|
||||||
|
if (_win == EmptyWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
|
||||||
|
if (b)
|
||||||
|
{
|
||||||
|
// update current hardware icon to avoid to have the plain arrow
|
||||||
|
updateCursor(true);
|
||||||
|
|
||||||
|
while (ShowCursor(b) < 0)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (ShowCursor(b) >= 0)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(NL_OS_MAC)
|
||||||
|
|
||||||
|
// Mac OS manages a show/hide counter for the cursor, so hiding the cursor
|
||||||
|
// twice requires two calls to "show" to make the cursor visible again.
|
||||||
|
// Since other platforms seem to not do this, the functionality is masked here
|
||||||
|
// by only calling hide if the cursor is visible and only calling show if
|
||||||
|
// the cursor was hidden.
|
||||||
|
|
||||||
|
CGDisplayErr error = kCGErrorSuccess;
|
||||||
|
static bool visible = true;
|
||||||
|
|
||||||
|
if(b && !visible)
|
||||||
|
{
|
||||||
|
error = CGDisplayShowCursor(kCGDirectMainDisplay);
|
||||||
|
visible = true;
|
||||||
|
}
|
||||||
|
else if(!b && visible)
|
||||||
|
{
|
||||||
|
error = CGDisplayHideCursor(kCGDirectMainDisplay);
|
||||||
|
visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(error != kCGErrorSuccess)
|
||||||
|
nlerror("cannot show / hide cursor");
|
||||||
|
|
||||||
|
#elif defined (NL_OS_UNIX)
|
||||||
|
|
||||||
|
if (!b)
|
||||||
|
{
|
||||||
|
XDefineCursor(_dpy, _win, _BlankCursor);
|
||||||
|
_CurrName = "none";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_CurrName = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// update current hardware icon to avoid to have the plain arrow
|
||||||
|
updateCursor(true);
|
||||||
|
|
||||||
|
#endif // NL_OS_UNIX
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
void CDriverGL::setMousePos(float x, float y)
|
||||||
|
{
|
||||||
|
H_AUTO_OGL(CDriverGL_setMousePos)
|
||||||
|
|
||||||
|
if (_win == EmptyWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sint x1 = (sint)((float)_CurrentMode.Width*x);
|
||||||
|
sint y1 = (sint)((float)_CurrentMode.Height*(1.0f-y));
|
||||||
|
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
|
||||||
|
// NeL window coordinate to MSWindows coordinates
|
||||||
|
POINT pt;
|
||||||
|
pt.x = x1;
|
||||||
|
pt.y = y1;
|
||||||
|
ClientToScreen (_win, &pt);
|
||||||
|
SetCursorPos(pt.x, pt.y);
|
||||||
|
|
||||||
|
#elif defined(NL_OS_MAC)
|
||||||
|
|
||||||
|
// CG wants absolute coordinates related to first screen's top left
|
||||||
|
|
||||||
|
// get the first screen's (conaints menubar) rect (this is not mainScreen)
|
||||||
|
NSRect firstScreenRect = [[[NSScreen screens] objectAtIndex:0] frame];
|
||||||
|
|
||||||
|
// get the rect (position, size) of the window
|
||||||
|
NSRect windowRect;
|
||||||
|
if([containerView() isInFullScreenMode])
|
||||||
|
windowRect = [[[containerView() window] screen] frame];
|
||||||
|
else
|
||||||
|
windowRect = [[containerView() window] frame];
|
||||||
|
|
||||||
|
// get the view's rect for height and width
|
||||||
|
NSRect viewRect = [containerView() frame];
|
||||||
|
|
||||||
|
// set the cursor position
|
||||||
|
CGDisplayErr error = CGDisplayMoveCursorToPoint(
|
||||||
|
kCGDirectMainDisplay, CGPointMake(
|
||||||
|
windowRect.origin.x + (viewRect.size.width * x),
|
||||||
|
firstScreenRect.size.height - windowRect.origin.y -
|
||||||
|
viewRect.size.height + ((1.0 - y) * viewRect.size.height)));
|
||||||
|
|
||||||
|
if(error != kCGErrorSuccess)
|
||||||
|
nlerror("cannot set mouse position");
|
||||||
|
|
||||||
|
#elif defined (NL_OS_UNIX)
|
||||||
|
|
||||||
|
XWarpPointer (_dpy, None, _win, None, None, None, None, x1, y1);
|
||||||
|
|
||||||
|
#endif // NL_OS_UNIX
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDriverGL::setCapture (bool b)
|
||||||
|
{
|
||||||
|
H_AUTO_OGL(CDriverGL_setCapture )
|
||||||
|
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
|
||||||
|
if (b && isSystemCursorInClientArea() && !isSystemCursorCaptured())
|
||||||
|
{
|
||||||
|
SetCapture(_win);
|
||||||
|
}
|
||||||
|
else if (!b && isSystemCursorCaptured())
|
||||||
|
{
|
||||||
|
// if hardware mouse and not in client area, then force to update its aspect by updating its pos
|
||||||
|
if (!isSystemCursorInClientArea())
|
||||||
|
{
|
||||||
|
// force update
|
||||||
|
showCursor(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseCapture();
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(NL_OS_MAC)
|
||||||
|
|
||||||
|
// no need to capture
|
||||||
|
_MouseCaptured = b;
|
||||||
|
|
||||||
|
#elif defined (NL_OS_UNIX)
|
||||||
|
|
||||||
|
if(b /* && isSystemCursorInClientArea() && !isSystemCursorCaptured()*/) // capture the cursor.
|
||||||
|
{
|
||||||
|
// capture the cursor
|
||||||
|
XGrabPointer(_dpy, _win, True, 0, GrabModeAsync, GrabModeAsync, _win, None, CurrentTime);
|
||||||
|
_MouseCaptured = true;
|
||||||
|
}
|
||||||
|
else if (!b/* && isSystemCursorCaptured()*/)
|
||||||
|
{
|
||||||
|
// release the cursor
|
||||||
|
XUngrabPointer(_dpy, CurrentTime);
|
||||||
|
_MouseCaptured = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // NL_OS_UNIX
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDriverGL::isSystemCursorInClientArea()
|
||||||
|
{
|
||||||
|
if (_FullScreen /* || !IsMouseCursorHardware() */)
|
||||||
|
{
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
return IsWindowVisible(_win) != FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
POINT cursPos;
|
||||||
|
// the mouse should be in the client area of the window
|
||||||
|
if (!GetCursorPos(&cursPos))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
HWND wnd = WindowFromPoint(cursPos);
|
||||||
|
if (wnd != _win)
|
||||||
|
{
|
||||||
|
return false; // not the same window
|
||||||
|
}
|
||||||
|
// want that the mouse be in the client area
|
||||||
|
RECT clientRect;
|
||||||
|
if (!GetClientRect(_win, &clientRect))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
POINT tl, br;
|
||||||
|
tl.x = clientRect.left;
|
||||||
|
tl.y = clientRect.top;
|
||||||
|
br.x = clientRect.right;
|
||||||
|
br.y = clientRect.bottom;
|
||||||
|
if (!ClientToScreen(_win, &tl))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!ClientToScreen(_win, &br))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((cursPos.x < tl.x) || (cursPos.x >= br.x) || (cursPos.y < tl.y) || (cursPos.y >= br.y))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
bool CDriverGL::isSystemCursorCaptured()
|
||||||
|
{
|
||||||
|
H_AUTO_OGL(CDriverGL_isSystemCursorCaptured);
|
||||||
|
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
return GetCapture() == _win;
|
||||||
|
#else
|
||||||
|
return _MouseCaptured;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
NLMISC::IMouseDevice* CDriverGL::enableLowLevelMouse(bool enable, bool exclusive)
|
||||||
|
{
|
||||||
|
H_AUTO_OGL(CDriverGL_enableLowLevelMouse);
|
||||||
|
|
||||||
|
NLMISC::IMouseDevice *res = NULL;
|
||||||
|
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
|
||||||
|
NLMISC::CDIEventEmitter *diee = NULL;
|
||||||
|
|
||||||
|
if (_EventEmitter.getNumEmitters() > 1)
|
||||||
|
diee = NLMISC::safe_cast<CDIEventEmitter *>(_EventEmitter.getEmitter(1));
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (diee)
|
||||||
|
res = diee->getMouseDevice(exclusive);
|
||||||
|
}
|
||||||
|
catch (EDirectInput &)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (diee)
|
||||||
|
diee->releaseMouse();
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(NL_OS_MAC)
|
||||||
|
#elif defined (NL_OS_UNIX)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
NLMISC::IKeyboardDevice* CDriverGL::enableLowLevelKeyboard(bool enable)
|
||||||
|
{
|
||||||
|
H_AUTO_OGL(CDriverGL_enableLowLevelKeyboard);
|
||||||
|
|
||||||
|
NLMISC::IKeyboardDevice *res = NULL;
|
||||||
|
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
|
||||||
|
NLMISC::CDIEventEmitter *diee = NULL;
|
||||||
|
|
||||||
|
if (_EventEmitter.getNumEmitters() > 1)
|
||||||
|
diee = NLMISC::safe_cast<NLMISC::CDIEventEmitter *>(_EventEmitter.getEmitter(1));
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (diee)
|
||||||
|
res = diee->getKeyboardDevice();
|
||||||
|
}
|
||||||
|
catch (EDirectInput &)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (diee)
|
||||||
|
diee->releaseKeyboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(NL_OS_MAC)
|
||||||
|
#elif defined (NL_OS_UNIX)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
NLMISC::IInputDeviceManager* CDriverGL::getLowLevelInputDeviceManager()
|
||||||
|
{
|
||||||
|
H_AUTO_OGL(CDriverGL_getLowLevelInputDeviceManager);
|
||||||
|
|
||||||
|
NLMISC::IInputDeviceManager *res = NULL;
|
||||||
|
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
|
||||||
|
if (_EventEmitter.getNumEmitters() > 1)
|
||||||
|
res = NLMISC::safe_cast<NLMISC::CDIEventEmitter *>(_EventEmitter.getEmitter(1));
|
||||||
|
|
||||||
|
#elif defined(NL_OS_MAC)
|
||||||
|
#elif defined (NL_OS_UNIX)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
uint CDriverGL::getDoubleClickDelay(bool hardwareMouse)
|
||||||
|
{
|
||||||
|
H_AUTO_OGL(CDriverGL_getDoubleClickDelay);
|
||||||
|
|
||||||
|
uint res = 250;
|
||||||
|
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
|
||||||
|
NLMISC::IMouseDevice *md = NULL;
|
||||||
|
|
||||||
|
if (_EventEmitter.getNumEmitters() >= 2)
|
||||||
|
{
|
||||||
|
NLMISC::CDIEventEmitter *diee = NLMISC::safe_cast<CDIEventEmitter *>(_EventEmitter.getEmitter(1));
|
||||||
|
if (diee->isMouseCreated())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
md = diee->getMouseDevice(hardwareMouse);
|
||||||
|
}
|
||||||
|
catch (EDirectInput &)
|
||||||
|
{
|
||||||
|
// could not get device ..
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (md)
|
||||||
|
{
|
||||||
|
res = md->getDoubleClickDelay();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// try to read the good value from windows
|
||||||
|
res = ::GetDoubleClickTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(NL_OS_MAC)
|
||||||
|
# warning "OpenGL Driver: Missing Mac Implementation for getDoubleClickDelay"
|
||||||
|
nlwarning("OpenGL Driver: Missing Mac Implementation for getDoubleClickDelay");
|
||||||
|
|
||||||
|
#elif defined (NL_OS_UNIX)
|
||||||
|
|
||||||
|
// TODO for Linux
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // NL3D
|
|
@ -272,6 +272,8 @@ bool CDriverGL::init (uint windowIcon, emptyProc exitFunc)
|
||||||
|
|
||||||
ExitFunc = exitFunc;
|
ExitFunc = exitFunc;
|
||||||
|
|
||||||
|
createCursors();
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
#ifdef NL_OS_WINDOWS
|
||||||
WNDCLASSW wc;
|
WNDCLASSW wc;
|
||||||
|
|
||||||
|
@ -284,7 +286,7 @@ bool CDriverGL::init (uint windowIcon, emptyProc exitFunc)
|
||||||
wc.cbWndExtra = 0;
|
wc.cbWndExtra = 0;
|
||||||
wc.hInstance = GetModuleHandle(NULL);
|
wc.hInstance = GetModuleHandle(NULL);
|
||||||
wc.hIcon = (HICON)windowIcon;
|
wc.hIcon = (HICON)windowIcon;
|
||||||
wc.hCursor = LoadCursorA(NULL, IDC_ARROW);
|
wc.hCursor = _DefaultCursor;
|
||||||
wc.hbrBackground = WHITE_BRUSH;
|
wc.hbrBackground = WHITE_BRUSH;
|
||||||
wc.lpszClassName = L"NLClass";
|
wc.lpszClassName = L"NLClass";
|
||||||
wc.lpszMenuName = NULL;
|
wc.lpszMenuName = NULL;
|
||||||
|
@ -478,10 +480,10 @@ void CDriverGL::setWindowIcon(const std::vector<NLMISC::CBitmap> &bitmaps)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (smallIndex > -1)
|
if (smallIndex > -1)
|
||||||
winIconSmall = bitmaps[smallIndex].getHICON(smallWidth, smallHeight, 32);
|
convertBitmapToIcon(bitmaps[smallIndex], winIconSmall, smallWidth, smallHeight, 32);
|
||||||
|
|
||||||
if (bigIndex > -1)
|
if (bigIndex > -1)
|
||||||
winIconBig = bitmaps[bigIndex].getHICON(bigWidth, bigHeight, 32);
|
convertBitmapToIcon(bitmaps[bigIndex], winIconBig, bigWidth, bigHeight, 32);
|
||||||
|
|
||||||
if (winIconBig)
|
if (winIconBig)
|
||||||
{
|
{
|
||||||
|
@ -507,24 +509,7 @@ void CDriverGL::setWindowIcon(const std::vector<NLMISC::CBitmap> &bitmaps)
|
||||||
// process each bitmap
|
// process each bitmap
|
||||||
for(uint i = 0; i < bitmaps.size(); ++i)
|
for(uint i = 0; i < bitmaps.size(); ++i)
|
||||||
{
|
{
|
||||||
// get bitmap width and height
|
convertBitmapToIcon(bitmaps[i], icon_data);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1502,6 +1487,8 @@ bool CDriverGL::createWindow(const GfxMode &mode)
|
||||||
|
|
||||||
setWindowTitle(ucstring("NeL window"));
|
setWindowTitle(ucstring("NeL window"));
|
||||||
|
|
||||||
|
createCursors();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1511,6 +1498,8 @@ bool CDriverGL::destroyWindow()
|
||||||
{
|
{
|
||||||
H_AUTO_OGL(CDriverGL_destroyWindow)
|
H_AUTO_OGL(CDriverGL_destroyWindow)
|
||||||
|
|
||||||
|
releaseCursors();
|
||||||
|
|
||||||
// make sure window icons are deleted
|
// make sure window icons are deleted
|
||||||
std::vector<NLMISC::CBitmap> bitmaps;
|
std::vector<NLMISC::CBitmap> bitmaps;
|
||||||
setWindowIcon(bitmaps);
|
setWindowIcon(bitmaps);
|
||||||
|
@ -1770,6 +1759,16 @@ bool CDriverGL::setMode(const GfxMode& mode)
|
||||||
setWindowSize(mode.Width, mode.Height);
|
setWindowSize(mode.Width, mode.Height);
|
||||||
setWindowPos(_WindowX, _WindowY);
|
setWindowPos(_WindowX, _WindowY);
|
||||||
|
|
||||||
|
switch (_Depth)
|
||||||
|
{
|
||||||
|
case 16: _ColorDepth = ColorDepth16; break;
|
||||||
|
case 24:
|
||||||
|
case 32: _ColorDepth = ColorDepth32; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set color depth for custom cursor
|
||||||
|
updateCursor(true);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2322,135 +2321,6 @@ IDriver::TMessageBoxId CDriverGL::systemMessageBox (const char* message, const c
|
||||||
return okId;
|
return okId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------
|
|
||||||
void CDriverGL::showCursor(bool b)
|
|
||||||
{
|
|
||||||
H_AUTO_OGL(CDriverGL_showCursor)
|
|
||||||
|
|
||||||
if (_win == EmptyWindow)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
|
|
||||||
if (b)
|
|
||||||
{
|
|
||||||
while (ShowCursor(b) < 0)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (ShowCursor(b) >= 0)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined(NL_OS_MAC)
|
|
||||||
|
|
||||||
// Mac OS manages a show/hide counter for the cursor, so hiding the cursor
|
|
||||||
// twice requires two calls to "show" to make the cursor visible again.
|
|
||||||
// Since other platforms seem to not do this, the functionality is masked here
|
|
||||||
// by only calling hide if the cursor is visible and only calling show if
|
|
||||||
// the cursor was hidden.
|
|
||||||
|
|
||||||
CGDisplayErr error = kCGErrorSuccess;
|
|
||||||
static bool visible = true;
|
|
||||||
|
|
||||||
if(b && !visible)
|
|
||||||
{
|
|
||||||
error = CGDisplayShowCursor(kCGDirectMainDisplay);
|
|
||||||
visible = true;
|
|
||||||
}
|
|
||||||
else if(!b && visible)
|
|
||||||
{
|
|
||||||
error = CGDisplayHideCursor(kCGDirectMainDisplay);
|
|
||||||
visible = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(error != kCGErrorSuccess)
|
|
||||||
nlerror("cannot show / hide cursor");
|
|
||||||
|
|
||||||
#elif defined (NL_OS_UNIX)
|
|
||||||
|
|
||||||
if (b)
|
|
||||||
{
|
|
||||||
if (_cursor != None)
|
|
||||||
{
|
|
||||||
XFreeCursor(_dpy, _cursor);
|
|
||||||
_cursor = None;
|
|
||||||
}
|
|
||||||
XUndefineCursor(_dpy, _win);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (_cursor == None)
|
|
||||||
{
|
|
||||||
char bm_no_data[] = { 0,0,0,0, 0,0,0,0 };
|
|
||||||
Pixmap pixmap_no_data = XCreateBitmapFromData (_dpy, _win, bm_no_data, 8, 8);
|
|
||||||
XColor black;
|
|
||||||
memset(&black, 0, sizeof (XColor));
|
|
||||||
black.flags = DoRed | DoGreen | DoBlue;
|
|
||||||
_cursor = XCreatePixmapCursor (_dpy, pixmap_no_data, pixmap_no_data, &black, &black, 0, 0);
|
|
||||||
XFreePixmap(_dpy, pixmap_no_data);
|
|
||||||
}
|
|
||||||
XDefineCursor(_dpy, _win, _cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // NL_OS_UNIX
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------
|
|
||||||
void CDriverGL::setMousePos(float x, float y)
|
|
||||||
{
|
|
||||||
H_AUTO_OGL(CDriverGL_setMousePos)
|
|
||||||
|
|
||||||
if (_win == EmptyWindow)
|
|
||||||
return;
|
|
||||||
|
|
||||||
sint x1 = (sint)((float)_WindowWidth*x);
|
|
||||||
sint y1 = (sint)((float)_WindowHeight*(1.0f-y));
|
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
|
|
||||||
// NeL window coordinate to MSWindows coordinates
|
|
||||||
POINT pt;
|
|
||||||
pt.x = x1;
|
|
||||||
pt.y = y1;
|
|
||||||
ClientToScreen (_win, &pt);
|
|
||||||
SetCursorPos(pt.x, pt.y);
|
|
||||||
|
|
||||||
#elif defined(NL_OS_MAC)
|
|
||||||
|
|
||||||
// CG wants absolute coordinates related to first screen's top left
|
|
||||||
|
|
||||||
// get the first screen's (conaints menubar) rect (this is not mainScreen)
|
|
||||||
NSRect firstScreenRect = [[[NSScreen screens] objectAtIndex:0] frame];
|
|
||||||
|
|
||||||
// get the rect (position, size) of the window
|
|
||||||
NSRect windowRect;
|
|
||||||
if([containerView() isInFullScreenMode])
|
|
||||||
windowRect = [[[containerView() window] screen] frame];
|
|
||||||
else
|
|
||||||
windowRect = [[containerView() window] frame];
|
|
||||||
|
|
||||||
// get the view's rect for height and width
|
|
||||||
NSRect viewRect = [containerView() frame];
|
|
||||||
|
|
||||||
// set the cursor position
|
|
||||||
CGDisplayErr error = CGDisplayMoveCursorToPoint(
|
|
||||||
kCGDirectMainDisplay, CGPointMake(
|
|
||||||
windowRect.origin.x + (viewRect.size.width * x),
|
|
||||||
firstScreenRect.size.height - windowRect.origin.y -
|
|
||||||
viewRect.size.height + ((1.0 - y) * viewRect.size.height)));
|
|
||||||
|
|
||||||
if(error != kCGErrorSuccess)
|
|
||||||
nlerror("cannot set mouse position");
|
|
||||||
|
|
||||||
#elif defined (NL_OS_UNIX)
|
|
||||||
|
|
||||||
XWarpPointer (_dpy, None, _win, None, None, None, None, x1, y1);
|
|
||||||
|
|
||||||
#endif // NL_OS_UNIX
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDriverGL::getWindowSize(uint32 &width, uint32 &height)
|
void CDriverGL::getWindowSize(uint32 &width, uint32 &height)
|
||||||
{
|
{
|
||||||
H_AUTO_OGL(CDriverGL_getWindowSize)
|
H_AUTO_OGL(CDriverGL_getWindowSize)
|
||||||
|
@ -2622,206 +2492,6 @@ bool CDriverGL::isActive()
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDriverGL::setCapture (bool b)
|
|
||||||
{
|
|
||||||
H_AUTO_OGL(CDriverGL_setCapture )
|
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
|
|
||||||
if (b)
|
|
||||||
{
|
|
||||||
RECT client;
|
|
||||||
GetClientRect (_win, &client);
|
|
||||||
POINT pt1,pt2;
|
|
||||||
pt1.x = client.left;
|
|
||||||
pt1.y = client.top;
|
|
||||||
ClientToScreen (_win, &pt1);
|
|
||||||
pt2.x = client.right;
|
|
||||||
pt2.y = client.bottom;
|
|
||||||
ClientToScreen (_win, &pt2);
|
|
||||||
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)
|
|
||||||
|
|
||||||
// no need to capture
|
|
||||||
|
|
||||||
#elif defined (NL_OS_UNIX)
|
|
||||||
|
|
||||||
/*
|
|
||||||
TODO x11 funtion: setCapture
|
|
||||||
*/
|
|
||||||
|
|
||||||
if(b) // capture the cursor.
|
|
||||||
{
|
|
||||||
XGrabPointer(_dpy, _win, True, 0, GrabModeAsync, GrabModeAsync, _win, None, CurrentTime);
|
|
||||||
}
|
|
||||||
else // release the cursor.
|
|
||||||
{
|
|
||||||
XUngrabPointer(_dpy, CurrentTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // NL_OS_UNIX
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
NLMISC::IMouseDevice* CDriverGL::enableLowLevelMouse(bool enable, bool exclusive)
|
|
||||||
{
|
|
||||||
H_AUTO_OGL(CDriverGL_enableLowLevelMouse)
|
|
||||||
|
|
||||||
NLMISC::IMouseDevice *res = NULL;
|
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
|
|
||||||
NLMISC::CDIEventEmitter *diee = NULL;
|
|
||||||
|
|
||||||
if (_EventEmitter.getNumEmitters() > 1)
|
|
||||||
diee = NLMISC::safe_cast<CDIEventEmitter *>(_EventEmitter.getEmitter(1));
|
|
||||||
|
|
||||||
if (enable)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (diee)
|
|
||||||
res = diee->getMouseDevice(exclusive);
|
|
||||||
}
|
|
||||||
catch (EDirectInput &)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (diee)
|
|
||||||
diee->releaseMouse();
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined(NL_OS_MAC)
|
|
||||||
#elif defined (NL_OS_UNIX)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
NLMISC::IKeyboardDevice* CDriverGL::enableLowLevelKeyboard(bool enable)
|
|
||||||
{
|
|
||||||
H_AUTO_OGL(CDriverGL_enableLowLevelKeyboard)
|
|
||||||
|
|
||||||
NLMISC::IKeyboardDevice *res = NULL;
|
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
|
|
||||||
NLMISC::CDIEventEmitter *diee = NULL;
|
|
||||||
|
|
||||||
if (_EventEmitter.getNumEmitters() > 1)
|
|
||||||
diee = NLMISC::safe_cast<NLMISC::CDIEventEmitter *>(_EventEmitter.getEmitter(1));
|
|
||||||
|
|
||||||
if (enable)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (diee)
|
|
||||||
res = diee->getKeyboardDevice();
|
|
||||||
}
|
|
||||||
catch (EDirectInput &)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (diee)
|
|
||||||
diee->releaseKeyboard();
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined(NL_OS_MAC)
|
|
||||||
#elif defined (NL_OS_UNIX)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
NLMISC::IInputDeviceManager* CDriverGL::getLowLevelInputDeviceManager()
|
|
||||||
{
|
|
||||||
H_AUTO_OGL(CDriverGL_getLowLevelInputDeviceManager)
|
|
||||||
|
|
||||||
NLMISC::IInputDeviceManager *res = NULL;
|
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
|
|
||||||
if (_EventEmitter.getNumEmitters() > 1)
|
|
||||||
res = NLMISC::safe_cast<NLMISC::CDIEventEmitter *>(_EventEmitter.getEmitter(1));
|
|
||||||
|
|
||||||
#elif defined(NL_OS_MAC)
|
|
||||||
#elif defined (NL_OS_UNIX)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
|
||||||
uint CDriverGL::getDoubleClickDelay(bool hardwareMouse)
|
|
||||||
{
|
|
||||||
H_AUTO_OGL(CDriverGL_getDoubleClickDelay)
|
|
||||||
|
|
||||||
uint res = 250;
|
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
|
|
||||||
NLMISC::IMouseDevice *md = NULL;
|
|
||||||
|
|
||||||
if (_EventEmitter.getNumEmitters() >= 2)
|
|
||||||
{
|
|
||||||
NLMISC::CDIEventEmitter *diee = NLMISC::safe_cast<CDIEventEmitter *>(_EventEmitter.getEmitter(1));
|
|
||||||
if (diee->isMouseCreated())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
md = diee->getMouseDevice(hardwareMouse);
|
|
||||||
}
|
|
||||||
catch (EDirectInput &)
|
|
||||||
{
|
|
||||||
// could not get device ..
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (md)
|
|
||||||
{
|
|
||||||
res = md->getDoubleClickDelay();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// try to read the good value from windows
|
|
||||||
res = ::GetDoubleClickTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined(NL_OS_MAC)
|
|
||||||
# warning "OpenGL Driver: Missing Mac Implementation for getDoubleClickDelay"
|
|
||||||
nlwarning("OpenGL Driver: Missing Mac Implementation for getDoubleClickDelay");
|
|
||||||
|
|
||||||
#elif defined (NL_OS_UNIX)
|
|
||||||
|
|
||||||
// TODO for Linux
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
bool CDriverGL::setMonitorColorProperties (const CMonitorColorProperties &properties)
|
bool CDriverGL::setMonitorColorProperties (const CMonitorColorProperties &properties)
|
||||||
{
|
{
|
||||||
|
@ -2955,4 +2625,281 @@ bool CDriverGL::pasteTextFromClipboard(ucstring &text)
|
||||||
return _EventEmitter.pasteTextFromClipboard(text);
|
return _EventEmitter.pasteTextFromClipboard(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef NL_OS_WINDOWS
|
||||||
|
|
||||||
|
bool CDriverGL::convertBitmapToIcon(const NLMISC::CBitmap &bitmap, HICON &icon, uint iconWidth, uint iconHeight, uint iconDepth, const NLMISC::CRGBA &col, sint hotSpotX, sint hotSpotY, bool cursor)
|
||||||
|
{
|
||||||
|
CBitmap src = bitmap;
|
||||||
|
// resample bitmap if necessary
|
||||||
|
if (src.getWidth() != iconWidth || src.getHeight() != iconHeight)
|
||||||
|
{
|
||||||
|
src.resample(iconWidth, iconHeight);
|
||||||
|
}
|
||||||
|
CBitmap colorBm;
|
||||||
|
colorBm.resize(iconWidth, iconHeight, CBitmap::RGBA);
|
||||||
|
const CRGBA *srcColorPtr = (CRGBA *) &(src.getPixels()[0]);
|
||||||
|
const CRGBA *srcColorPtrLast = srcColorPtr + (iconWidth * iconHeight);
|
||||||
|
CRGBA *destColorPtr = (CRGBA *) &(colorBm.getPixels()[0]);
|
||||||
|
static volatile uint8 alphaThreshold = 127;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
destColorPtr->modulateFromColor(*srcColorPtr, col);
|
||||||
|
std::swap(destColorPtr->R, destColorPtr->B);
|
||||||
|
++ srcColorPtr;
|
||||||
|
++ destColorPtr;
|
||||||
|
}
|
||||||
|
while (srcColorPtr != srcColorPtrLast);
|
||||||
|
//
|
||||||
|
HBITMAP colorHbm = NULL;
|
||||||
|
HBITMAP maskHbm = NULL;
|
||||||
|
//
|
||||||
|
if (iconDepth == 16)
|
||||||
|
{
|
||||||
|
std::vector<uint16> colorBm16(iconWidth * iconHeight);
|
||||||
|
const CRGBA *src32 = (const CRGBA *) &colorBm.getPixels(0)[0];
|
||||||
|
|
||||||
|
for (uint k = 0; k < colorBm16.size(); ++k)
|
||||||
|
{
|
||||||
|
colorBm16[k] = ((uint16)(src32[k].R&0xf8)>>3) | ((uint16)(src32[k].G&0xfc)<<3) | ((uint16)(src32[k].B & 0xf8)<<8);
|
||||||
|
}
|
||||||
|
|
||||||
|
colorHbm = CreateBitmap(iconWidth, iconHeight, 1, 16, &colorBm16[0]);
|
||||||
|
std::vector<uint8> bitMask((iconWidth * iconHeight + 7) / 8, 0);
|
||||||
|
|
||||||
|
for (uint k = 0;k < colorBm16.size(); ++k)
|
||||||
|
{
|
||||||
|
if (src32[k].A <= 120)
|
||||||
|
{
|
||||||
|
bitMask[k / 8] |= (0x80 >> (k & 7));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
maskHbm = CreateBitmap(iconWidth, iconHeight, 1, 1, &bitMask[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
colorHbm = CreateBitmap(iconWidth, iconHeight, 1, 32, &colorBm.getPixels(0)[0]);
|
||||||
|
maskHbm = CreateBitmap(iconWidth, iconHeight, 1, 32, &colorBm.getPixels(0)[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ICONINFO iconInfo;
|
||||||
|
iconInfo.fIcon = cursor ? FALSE:TRUE;
|
||||||
|
iconInfo.xHotspot = (DWORD) hotSpotX;
|
||||||
|
iconInfo.yHotspot = (DWORD) hotSpotY;
|
||||||
|
iconInfo.hbmMask = maskHbm;
|
||||||
|
iconInfo.hbmColor = colorHbm;
|
||||||
|
|
||||||
|
if (colorHbm && maskHbm)
|
||||||
|
{
|
||||||
|
icon = CreateIconIndirect(&iconInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
if (colorHbm) DeleteObject(colorHbm);
|
||||||
|
if (maskHbm) DeleteObject(maskHbm);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDriverGL::convertBitmapToCursor(const NLMISC::CBitmap &bitmap, nlCursor &cursor, uint iconWidth, uint iconHeight, uint iconDepth, const NLMISC::CRGBA &col, sint hotSpotX, sint hotSpotY)
|
||||||
|
{
|
||||||
|
return convertBitmapToIcon(bitmap, cursor, iconWidth, iconHeight, iconDepth, col, hotSpotX, hotSpotY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(NL_OS_MAC)
|
||||||
|
|
||||||
|
#elif defined(NL_OS_UNIX)
|
||||||
|
|
||||||
|
bool CDriverGL::convertBitmapToIcon(const NLMISC::CBitmap &bitmap, std::vector<long> &icon)
|
||||||
|
{
|
||||||
|
// get bitmap width and height
|
||||||
|
uint width = bitmap.getWidth();
|
||||||
|
uint height = bitmap.getHeight();
|
||||||
|
|
||||||
|
// icon position for bitmap
|
||||||
|
uint pos = (uint)icon.size();
|
||||||
|
|
||||||
|
// extend icon_data size for bitmap
|
||||||
|
icon.resize(pos + 2 + width*height);
|
||||||
|
|
||||||
|
// set bitmap width and height
|
||||||
|
icon[pos++] = width;
|
||||||
|
icon[pos++] = height;
|
||||||
|
|
||||||
|
// convert RGBA to ARGB
|
||||||
|
CObjectVector<uint8> pixels = bitmap.getPixels();
|
||||||
|
for(uint j = 0; j < pixels.size(); j+=4)
|
||||||
|
icon[pos++] = pixels[j] << 16 | pixels[j+1] << 8 | pixels[j+2] | pixels[j+3] << 24;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDriverGL::convertBitmapToCursor(const NLMISC::CBitmap &bitmap, Cursor &cursor, uint iconWidth, uint iconHeight, uint iconDepth, const NLMISC::CRGBA &col, sint hotSpotX, sint hotSpotY)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_XRENDER
|
||||||
|
|
||||||
|
CBitmap src = bitmap;
|
||||||
|
// resample bitmap if necessary
|
||||||
|
if (src.getWidth() != iconWidth || src.getHeight() != iconHeight)
|
||||||
|
{
|
||||||
|
src.resample(iconWidth, iconHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
CBitmap colorBm;
|
||||||
|
colorBm.resize(iconWidth, iconHeight, CBitmap::RGBA);
|
||||||
|
const CRGBA *srcColorPtr = (CRGBA *) &(src.getPixels()[0]);
|
||||||
|
const CRGBA *srcColorPtrLast = srcColorPtr + (iconWidth * iconHeight);
|
||||||
|
CRGBA *destColorPtr = (CRGBA *) &(colorBm.getPixels()[0]);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// colorize icon
|
||||||
|
destColorPtr->modulateFromColor(*srcColorPtr, col);
|
||||||
|
|
||||||
|
// X11 wants BGRA pixels : swap red and blue channels
|
||||||
|
std::swap(destColorPtr->R, destColorPtr->B);
|
||||||
|
|
||||||
|
// premultiplied alpha
|
||||||
|
if (destColorPtr->A < 255)
|
||||||
|
{
|
||||||
|
destColorPtr->R = (destColorPtr->R * destColorPtr->A) / 255;
|
||||||
|
destColorPtr->G = (destColorPtr->G * destColorPtr->A) / 255;
|
||||||
|
destColorPtr->B = (destColorPtr->B * destColorPtr->A) / 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
++ srcColorPtr;
|
||||||
|
++ destColorPtr;
|
||||||
|
}
|
||||||
|
while (srcColorPtr != srcColorPtrLast);
|
||||||
|
|
||||||
|
// use malloc() because X will free() data itself
|
||||||
|
CRGBA *src32 = (CRGBA*)malloc(colorBm.getSize()*4);
|
||||||
|
memcpy(src32, &colorBm.getPixels(0)[0], colorBm.getSize()*4);
|
||||||
|
|
||||||
|
uint size = iconWidth * iconHeight;
|
||||||
|
|
||||||
|
// Create the icon pixmap
|
||||||
|
sint screen = DefaultScreen(_dpy);
|
||||||
|
Visual* defVisual = DefaultVisual(_dpy, screen);
|
||||||
|
XImage* image = NULL;
|
||||||
|
|
||||||
|
// create the icon pixmap
|
||||||
|
if (iconDepth == 16)
|
||||||
|
{
|
||||||
|
std::vector<uint16> colorBm16(iconWidth * iconHeight);
|
||||||
|
|
||||||
|
for (uint k = 0; k < colorBm16.size(); ++k)
|
||||||
|
{
|
||||||
|
colorBm16[k] = ((uint16)(src32[k].R&0xf8)>>3) | ((uint16)(src32[k].G&0xfc)<<3) | ((uint16)(src32[k].B & 0xf8)<<8);
|
||||||
|
}
|
||||||
|
|
||||||
|
image = XCreateImage(_dpy, defVisual, 16, ZPixmap, 0, (char*)colorBm16[0], iconWidth, iconHeight, 16, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
image = XCreateImage(_dpy, defVisual, 32, ZPixmap, 0, (char*)src32, iconWidth, iconHeight, 32, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!image)
|
||||||
|
{
|
||||||
|
nlwarning("Failed to set the window's icon");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pixmap iconPixmap = XCreatePixmap(_dpy, _win, iconWidth, iconHeight, 32 /* defDepth */);
|
||||||
|
GC gc = XCreateGC(_dpy, iconPixmap, 0, NULL);
|
||||||
|
XPutImage(_dpy, iconPixmap, gc, image, 0, 0, 0, 0, iconWidth, iconHeight);
|
||||||
|
XFreeGC(_dpy, gc);
|
||||||
|
|
||||||
|
if (image->data)
|
||||||
|
{
|
||||||
|
free(image->data);
|
||||||
|
image->data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
XDestroyImage(image);
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Send our new icon to the window through the WMHints
|
||||||
|
XWMHints* Hints = XAllocWMHints();
|
||||||
|
Hints->flags = IconPixmapHint | IconMaskHint;
|
||||||
|
Hints->icon_pixmap = iconPixmap;
|
||||||
|
Hints->icon_mask = maskPixmap;
|
||||||
|
XSetWMHints(ourDisplay, myWindow, Hints);
|
||||||
|
XFree(Hints);
|
||||||
|
*/
|
||||||
|
|
||||||
|
XRenderPictFormat *format = XRenderFindStandardFormat (_dpy, PictStandardARGB32);
|
||||||
|
Picture picture = XRenderCreatePicture (_dpy, iconPixmap, format, 0, 0);
|
||||||
|
|
||||||
|
cursor = XRenderCreateCursor(_dpy, picture, (uint)hotSpotX, (uint)hotSpotY);
|
||||||
|
|
||||||
|
XRenderFreePicture(_dpy, picture);
|
||||||
|
XFreePixmap(_dpy, iconPixmap);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
XRenderPictFormat* format = None;
|
||||||
|
|
||||||
|
{
|
||||||
|
XRenderPictFormat alpha_format;
|
||||||
|
unsigned long mask = PictFormatType|PictFormatDepth|PictFormatAlpha|PictFormatAlphaMask;
|
||||||
|
alpha_format.type = PictTypeDirect;
|
||||||
|
alpha_format.depth = 8;
|
||||||
|
alpha_format.direct.alpha = 0;
|
||||||
|
alpha_format.direct.alphaMask = 0xff;
|
||||||
|
|
||||||
|
format = XRenderFindFormat(dpy, mask, &alpha_format, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!format) {
|
||||||
|
printf("%s", "error, couldnt find valid format for alpha.\n");
|
||||||
|
XFreePixmap(dpy, dst_pm);
|
||||||
|
XFreePixmap(dpy, src_pm);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
{ /* fill the alpha-picture */
|
||||||
|
Pixmap alpha_pm = None;
|
||||||
|
|
||||||
|
XRenderColor alpha_color;
|
||||||
|
XRenderPictureAttributes alpha_attr;
|
||||||
|
|
||||||
|
alpha_color.alpha = 0xffff * (shade)/100;
|
||||||
|
|
||||||
|
alpha_attr.repeat = True;
|
||||||
|
|
||||||
|
alpha_pm = XCreatePixmap(dpy, src_pm, 1, 1, 8);
|
||||||
|
alpha_pic = XRenderCreatePicture(dpy, alpha_pm, format, CPRepeat, &alpha_attr);
|
||||||
|
XRenderFillRectangle(dpy, PictOpSrc, alpha_pic, &alpha_color, 0, 0, 1, 1);
|
||||||
|
XFreePixmap(dpy, alpha_pm);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ /* blend all together */
|
||||||
|
Picture src_pic;
|
||||||
|
Picture dst_pic;
|
||||||
|
|
||||||
|
format = XRenderFindVisualFormat(dpy, vis);
|
||||||
|
|
||||||
|
src_pic = XRenderCreatePicture(dpy, src_pm, format, 0, 0);
|
||||||
|
dst_pic = XRenderCreatePicture(dpy, dst_pm, format, 0, 0);
|
||||||
|
|
||||||
|
XRenderComposite(dpy, PictOpOver,
|
||||||
|
src_pic, alpha_pic, dst_pic,
|
||||||
|
src_x, src_y, 0, 0, dst_x, dst_y, width, height);
|
||||||
|
XRenderFreePicture(dpy, src_pic);
|
||||||
|
XRenderFreePicture(dpy, dst_pic);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
} // NL3D
|
} // NL3D
|
||||||
|
|
|
@ -1643,6 +1643,26 @@ void CDriverUser::setCapture (bool b)
|
||||||
_Driver->setCapture (b);
|
_Driver->setCapture (b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CDriverUser::isSystemCursorCaptured()
|
||||||
|
{
|
||||||
|
NL3D_HAUTO_UI_DRIVER;
|
||||||
|
|
||||||
|
return _Driver->isSystemCursorCaptured();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDriverUser::addCursor(const std::string &name, const NLMISC::CBitmap &bitmap)
|
||||||
|
{
|
||||||
|
NL3D_HAUTO_UI_DRIVER;
|
||||||
|
|
||||||
|
_Driver->addCursor(name, bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDriverUser::setCursor(const std::string &name, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY, bool forceRebuild)
|
||||||
|
{
|
||||||
|
NL3D_HAUTO_UI_DRIVER;
|
||||||
|
|
||||||
|
_Driver->setCursor(name, col, rot, hotSpotX, hotSpotY, forceRebuild);
|
||||||
|
}
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
|
|
@ -1614,9 +1614,6 @@ void CBitmap::releaseMipMaps()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TempMaxVerboseResample = false;
|
|
||||||
#define logResample if (TempMaxVerboseResample) nldebug
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------*\
|
/*-------------------------------------------------------------------*\
|
||||||
resample
|
resample
|
||||||
\*-------------------------------------------------------------------*/
|
\*-------------------------------------------------------------------*/
|
||||||
|
@ -4107,84 +4104,5 @@ void CBitmap::getDibData(uint8*& extractData)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
|
|
||||||
HICON CBitmap::getHICON(sint iconWidth, sint iconHeight, sint iconDepth, const NLMISC::CRGBA &col, sint hotSpotX, sint hotSpotY, bool cursor) const
|
|
||||||
{
|
|
||||||
HICON result = NULL;
|
|
||||||
CBitmap src = *this;
|
|
||||||
// resample bitmap if necessary
|
|
||||||
if (_Width != iconWidth || _Height != iconHeight)
|
|
||||||
{
|
|
||||||
src.resample(iconWidth, iconHeight);
|
|
||||||
}
|
|
||||||
CBitmap colorBm;
|
|
||||||
colorBm.resize(iconWidth, iconHeight, CBitmap::RGBA);
|
|
||||||
const CRGBA *srcColorPtr = (CRGBA *) &(src.getPixels()[0]);
|
|
||||||
const CRGBA *srcColorPtrLast = srcColorPtr + (iconWidth * iconHeight);
|
|
||||||
CRGBA *destColorPtr = (CRGBA *) &(colorBm.getPixels()[0]);
|
|
||||||
static volatile uint8 alphaThreshold = 127;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
destColorPtr->modulateFromColor(*srcColorPtr, col);
|
|
||||||
std::swap(destColorPtr->R, destColorPtr->B);
|
|
||||||
++ srcColorPtr;
|
|
||||||
++ destColorPtr;
|
|
||||||
}
|
|
||||||
while (srcColorPtr != srcColorPtrLast);
|
|
||||||
//
|
|
||||||
HBITMAP colorHbm = NULL;
|
|
||||||
HBITMAP maskHbm = NULL;
|
|
||||||
//
|
|
||||||
if (iconDepth == 16)
|
|
||||||
{
|
|
||||||
std::vector<uint16> colorBm16(iconWidth * iconHeight);
|
|
||||||
const CRGBA *src32 = (const CRGBA *) &colorBm.getPixels(0)[0];
|
|
||||||
|
|
||||||
for (uint k = 0; k < colorBm16.size(); ++k)
|
|
||||||
{
|
|
||||||
colorBm16[k] = ((uint16)(src32[k].R&0xf8)>>3) | ((uint16)(src32[k].G&0xfc)<<3) | ((uint16)(src32[k].B & 0xf8)<<8);
|
|
||||||
}
|
|
||||||
|
|
||||||
colorHbm = CreateBitmap(iconWidth, iconHeight, 1, 16, &colorBm16[0]);
|
|
||||||
std::vector<uint8> bitMask((iconWidth * iconHeight + 7) / 8, 0);
|
|
||||||
|
|
||||||
for (uint k = 0;k < colorBm16.size(); ++k)
|
|
||||||
{
|
|
||||||
if (src32[k].A <= 120)
|
|
||||||
{
|
|
||||||
bitMask[k / 8] |= (0x80 >> (k & 7));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
maskHbm = CreateBitmap(iconWidth, iconHeight, 1, 1, &bitMask[0]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
colorHbm = CreateBitmap(iconWidth, iconHeight, 1, 32, &colorBm.getPixels(0)[0]);
|
|
||||||
maskHbm = CreateBitmap(iconWidth, iconHeight, 1, 32, &colorBm.getPixels(0)[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
ICONINFO iconInfo;
|
|
||||||
iconInfo.fIcon = cursor ? FALSE:TRUE;
|
|
||||||
iconInfo.xHotspot = (DWORD) hotSpotX;
|
|
||||||
iconInfo.yHotspot = (DWORD) hotSpotY;
|
|
||||||
iconInfo.hbmMask = maskHbm;
|
|
||||||
iconInfo.hbmColor = colorHbm;
|
|
||||||
|
|
||||||
if (colorHbm && maskHbm)
|
|
||||||
{
|
|
||||||
result = CreateIconIndirect(&iconInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
if (colorHbm) DeleteObject(colorHbm);
|
|
||||||
if (maskHbm) DeleteObject(maskHbm);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // NLMISC
|
} // NLMISC
|
||||||
|
|
||||||
|
|
|
@ -352,56 +352,4 @@ uint CSystemUtils::getCurrentColorDepth()
|
||||||
return depth;
|
return depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSystemUtils::isSystemCursorInClientArea()
|
|
||||||
{
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
if (s_window == NULL)
|
|
||||||
{
|
|
||||||
nlwarning("No window has be set with CSystemUtils::setWindow()");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
POINT cursPos;
|
|
||||||
// the mouse should be in the client area of the window
|
|
||||||
if (!GetCursorPos(&cursPos))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
HWND wnd = WindowFromPoint(cursPos);
|
|
||||||
if (wnd != s_window)
|
|
||||||
{
|
|
||||||
return false; // not the same window
|
|
||||||
}
|
|
||||||
// want that the mouse be in the client area
|
|
||||||
RECT clientRect;
|
|
||||||
if (!GetClientRect(s_window, &clientRect))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
POINT tl, br;
|
|
||||||
tl.x = clientRect.left;
|
|
||||||
tl.y = clientRect.top;
|
|
||||||
br.x = clientRect.right;
|
|
||||||
br.y = clientRect.bottom;
|
|
||||||
if (!ClientToScreen(s_window, &tl))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!ClientToScreen(s_window, &br))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (cursPos.x < tl.x ||
|
|
||||||
cursPos.x >= br.x ||
|
|
||||||
cursPos.y < tl.y ||
|
|
||||||
cursPos.y >= br.y)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// TODO for Linux and Mac OS
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // NLMISC
|
} // NLMISC
|
||||||
|
|
|
@ -90,8 +90,6 @@
|
||||||
|
|
||||||
#include "login_progress_post_thread.h"
|
#include "login_progress_post_thread.h"
|
||||||
|
|
||||||
#include "interface_v3/custom_mouse.h"
|
|
||||||
|
|
||||||
#include "browse_faq.h"
|
#include "browse_faq.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -789,16 +787,6 @@ void prelogInit()
|
||||||
|
|
||||||
FPU_CHECKER_ONCE
|
FPU_CHECKER_ONCE
|
||||||
|
|
||||||
switch (getCurrentColorDepth())
|
|
||||||
{
|
|
||||||
case 16: CustomMouse.setColorDepth(CCustomMouse::ColorDepth16); break;
|
|
||||||
case 24:
|
|
||||||
case 32: CustomMouse.setColorDepth(CCustomMouse::ColorDepth32); break;
|
|
||||||
default:
|
|
||||||
ExitClientError(CI18N::get("uiUnsupportedColorDepth").toUtf8().c_str());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check driver version
|
// Check driver version
|
||||||
checkDriverVersion();
|
checkDriverVersion();
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include "interface_v3/input_handler_manager.h"
|
#include "interface_v3/input_handler_manager.h"
|
||||||
#include "client_cfg.h"
|
#include "client_cfg.h"
|
||||||
#include "time_client.h"
|
#include "time_client.h"
|
||||||
#include "interface_v3/custom_mouse.h"
|
|
||||||
// 3D
|
// 3D
|
||||||
#include "nel/3d/u_driver.h"
|
#include "nel/3d/u_driver.h"
|
||||||
// Misc
|
// Misc
|
||||||
|
@ -66,11 +65,6 @@ bool SetMousePosFirstTime = true;
|
||||||
// mask for mouse buttons that are known to be down
|
// mask for mouse buttons that are known to be down
|
||||||
uint DownMouseButtons = 0;
|
uint DownMouseButtons = 0;
|
||||||
|
|
||||||
#ifdef NL_OS_UNIX
|
|
||||||
// on X11 and cocoa, store whether the mouse was captured or not
|
|
||||||
bool MouseCapture = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//////////////
|
//////////////
|
||||||
// FUNCTION //
|
// FUNCTION //
|
||||||
//////////////
|
//////////////
|
||||||
|
@ -128,12 +122,14 @@ bool InitMouseWithCursor (bool hardware)
|
||||||
// Get the current mouse position
|
// Get the current mouse position
|
||||||
if (hardware)
|
if (hardware)
|
||||||
{
|
{
|
||||||
if (CInterfaceManager::getInstance()->getPointer())
|
Driver->showCursor(true);
|
||||||
|
|
||||||
|
CViewPointer *pointer = CInterfaceManager::getInstance()->getPointer();
|
||||||
|
if (pointer)
|
||||||
{
|
{
|
||||||
float x = (float)CInterfaceManager::getInstance()->getPointer()->getX()/(float)Driver->getWindowWidth();
|
float x = (float)pointer->getX()/(float)Driver->getWindowWidth();
|
||||||
float y = (float)CInterfaceManager::getInstance()->getPointer()->getY()/(float)Driver->getWindowHeight();
|
float y = (float)pointer->getY()/(float)Driver->getWindowHeight();
|
||||||
CustomMouse.updateCursor(); // update current hardware icon to avoid to have the plain arrow
|
|
||||||
Driver->showCursor(true);
|
|
||||||
if (SetMousePosFirstTime)
|
if (SetMousePosFirstTime)
|
||||||
{
|
{
|
||||||
SetMousePosFirstTime = false;
|
SetMousePosFirstTime = false;
|
||||||
|
@ -141,12 +137,9 @@ bool InitMouseWithCursor (bool hardware)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Driver->setMousePos(x, y);
|
Driver->setMousePos(x, y);
|
||||||
|
nlwarning("mouse pos %f,%f", x, y);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CustomMouse.updateCursor(); // update current hardware icon to avoid to have the plain arrow
|
|
||||||
Driver->showCursor(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -232,7 +225,7 @@ void UpdateMouse ()
|
||||||
Driver->emulateMouseRawMode(false);
|
Driver->emulateMouseRawMode(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!IsSystemCursorCaptured())
|
if (!Driver->isSystemCursorCaptured())
|
||||||
{
|
{
|
||||||
DownMouseButtons = 0;
|
DownMouseButtons = 0;
|
||||||
}
|
}
|
||||||
|
@ -246,7 +239,9 @@ void SetMouseFreeLook ()
|
||||||
{
|
{
|
||||||
MouseFreeLook = true;
|
MouseFreeLook = true;
|
||||||
if (MouseHardware)
|
if (MouseHardware)
|
||||||
|
{
|
||||||
Driver->showCursor(false);
|
Driver->showCursor(false);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CInterfaceManager *im = CInterfaceManager::getInstance();
|
CInterfaceManager *im = CInterfaceManager::getInstance();
|
||||||
|
@ -306,9 +301,13 @@ void SetMouseCursor (bool updatePos)
|
||||||
if (updatePos)
|
if (updatePos)
|
||||||
{
|
{
|
||||||
if (MouseDevice)
|
if (MouseDevice)
|
||||||
|
{
|
||||||
MouseDevice->setMousePos((float)ix, (float)iy);
|
MouseDevice->setMousePos((float)ix, (float)iy);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
Driver->setMousePos(x, y);
|
Driver->setMousePos(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
if (MouseHardware)
|
if (MouseHardware)
|
||||||
{
|
{
|
||||||
|
@ -367,53 +366,6 @@ void SetMouseAcceleration (uint accel)
|
||||||
UpdateMouse ();
|
UpdateMouse ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// *********************************************************************************
|
|
||||||
void CaptureSystemCursor()
|
|
||||||
{
|
|
||||||
if (IsSystemCursorCaptured()) return;
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
HWND drvWnd = Driver->getDisplay();
|
|
||||||
if (!drvWnd) return;
|
|
||||||
SetCapture(drvWnd);
|
|
||||||
#else
|
|
||||||
// on X11 and cocoa, set driver mouse capture on and store it locally as well
|
|
||||||
Driver->setCapture(MouseCapture = true);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// *********************************************************************************
|
|
||||||
void ReleaseSystemCursor()
|
|
||||||
{
|
|
||||||
if (!IsSystemCursorCaptured()) return;
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
// if hardware mouse and not in client area, then force to update its aspect by updating its pos
|
|
||||||
if (!IsSystemCursorInClientArea())
|
|
||||||
{
|
|
||||||
// force update
|
|
||||||
ShowCursor(FALSE);
|
|
||||||
ShowCursor(TRUE);
|
|
||||||
}
|
|
||||||
ReleaseCapture();
|
|
||||||
#else
|
|
||||||
// on X11 and cocoa, set driver mouse capture off and store it locally as well
|
|
||||||
Driver->setCapture(MouseCapture = false);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// *********************************************************************************
|
|
||||||
bool IsSystemCursorCaptured()
|
|
||||||
{
|
|
||||||
if (!Driver) return false;
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
return GetCapture() == Driver->getDisplay();
|
|
||||||
#else
|
|
||||||
/*
|
|
||||||
TODO there should be a way to ask the driver if capturing is on or off
|
|
||||||
*/
|
|
||||||
return MouseCapture;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// *********************************************************************************
|
// *********************************************************************************
|
||||||
void HandleSystemCursorCapture(const CEvent &event)
|
void HandleSystemCursorCapture(const CEvent &event)
|
||||||
{
|
{
|
||||||
|
@ -421,10 +373,7 @@ void HandleSystemCursorCapture(const CEvent &event)
|
||||||
{
|
{
|
||||||
CEventMouseDown &em = (CEventMouseDown &) event;
|
CEventMouseDown &em = (CEventMouseDown &) event;
|
||||||
DownMouseButtons |= em.Button & (leftButton | middleButton | rightButton);
|
DownMouseButtons |= em.Button & (leftButton | middleButton | rightButton);
|
||||||
if (IsSystemCursorInClientArea())
|
Driver->setCapture(true);
|
||||||
{
|
|
||||||
CaptureSystemCursor();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event == EventMouseUpId)
|
if (event == EventMouseUpId)
|
||||||
|
@ -434,7 +383,7 @@ void HandleSystemCursorCapture(const CEvent &event)
|
||||||
DownMouseButtons &= ~(em.Button & (leftButton | middleButton | rightButton));
|
DownMouseButtons &= ~(em.Button & (leftButton | middleButton | rightButton));
|
||||||
if (DownMouseButtons == 0)
|
if (DownMouseButtons == 0)
|
||||||
{
|
{
|
||||||
ReleaseSystemCursor();
|
Driver->setCapture(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,66 +394,6 @@ void HandleSystemCursorCapture(const CEvent &event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// *********************************************************************************
|
|
||||||
bool IsSystemCursorInClientArea()
|
|
||||||
{
|
|
||||||
if (!Driver) return false;
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
HWND drvWnd = Driver->getDisplay();
|
|
||||||
if (!drvWnd) return false;
|
|
||||||
UDriver::CMode videoMode;
|
|
||||||
Driver->getCurrentScreenMode(videoMode);
|
|
||||||
if (!videoMode.Windowed || !IsMouseCursorHardware())
|
|
||||||
{
|
|
||||||
// just test visibility
|
|
||||||
return IsWindowVisible(drvWnd) != FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
POINT cursPos;
|
|
||||||
// the mouse should be in the client area of the window
|
|
||||||
if (!GetCursorPos(&cursPos))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
HWND wnd = WindowFromPoint(cursPos);
|
|
||||||
if (wnd != drvWnd)
|
|
||||||
{
|
|
||||||
return false; // not the same window
|
|
||||||
}
|
|
||||||
// want that the mouse be in the client area
|
|
||||||
RECT clientRect;
|
|
||||||
if (!GetClientRect(drvWnd, &clientRect))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
POINT tl, br;
|
|
||||||
tl.x = clientRect.left;
|
|
||||||
tl.y = clientRect.top;
|
|
||||||
br.x = clientRect.right;
|
|
||||||
br.y = clientRect.bottom;
|
|
||||||
if (!ClientToScreen(drvWnd, &tl))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!ClientToScreen(drvWnd, &br))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (cursPos.x < tl.x ||
|
|
||||||
cursPos.x >= br.x ||
|
|
||||||
cursPos.y < tl.y ||
|
|
||||||
cursPos.y >= br.y)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// TODO for Linux and Mac OS
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
sint CNiceInputAuto::_Count = 0;
|
sint CNiceInputAuto::_Count = 0;
|
||||||
|
|
||||||
|
|
||||||
|
@ -516,7 +405,7 @@ CNiceInputAuto::CNiceInputAuto()
|
||||||
Driver->enableLowLevelMouse(false, false); // but ignore direct input (win 32 msg only)
|
Driver->enableLowLevelMouse(false, false); // but ignore direct input (win 32 msg only)
|
||||||
|
|
||||||
|
|
||||||
CustomMouse.setCursor("curs_default.tga", CRGBA::White, 0, 0x15, 0x18);
|
Driver->setCursor("curs_default.tga", CRGBA::White, 0, 0x15, 0x18);
|
||||||
Driver->showCursor(true); // keep cursor visible in windowed mode
|
Driver->showCursor(true); // keep cursor visible in windowed mode
|
||||||
MouseDevice = NULL;
|
MouseDevice = NULL;
|
||||||
Driver->enableLowLevelKeyboard (false);
|
Driver->enableLowLevelKeyboard (false);
|
||||||
|
|
|
@ -62,22 +62,9 @@ void SetMouseSpeed (float speed);
|
||||||
// Use this method to set the cursor acceleration
|
// Use this method to set the cursor acceleration
|
||||||
void SetMouseAcceleration (uint accel);
|
void SetMouseAcceleration (uint accel);
|
||||||
|
|
||||||
// capture the system cursor
|
|
||||||
void CaptureSystemCursor();
|
|
||||||
|
|
||||||
// release the system cursor
|
|
||||||
void ReleaseSystemCursor();
|
|
||||||
|
|
||||||
// see if system cursor is currently captured
|
|
||||||
bool IsSystemCursorCaptured();
|
|
||||||
|
|
||||||
// handle capturing of mouse on button up / button down
|
// handle capturing of mouse on button up / button down
|
||||||
void HandleSystemCursorCapture(const NLMISC::CEvent &event);
|
void HandleSystemCursorCapture(const NLMISC::CEvent &event);
|
||||||
|
|
||||||
// Test if cursor is in the client area. always true when software cursor is used and window visible
|
|
||||||
// (displayed in software when DirectInput is used)
|
|
||||||
bool IsSystemCursorInClientArea();
|
|
||||||
|
|
||||||
// get state of mouse button, as a bitfield formatted like NLMISC::TMouseButton (modifier keys are not included)
|
// get state of mouse button, as a bitfield formatted like NLMISC::TMouseButton (modifier keys are not included)
|
||||||
uint GetMouseButtonsState();
|
uint GetMouseButtonsState();
|
||||||
|
|
||||||
|
|
|
@ -1,458 +0,0 @@
|
||||||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
|
||||||
// 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 "stdpch.h"
|
|
||||||
#include "custom_mouse.h"
|
|
||||||
//
|
|
||||||
#include "../global.h"
|
|
||||||
#include "../input.h"
|
|
||||||
#include "input_handler_manager.h"
|
|
||||||
|
|
||||||
|
|
||||||
CCustomMouse CustomMouse;
|
|
||||||
|
|
||||||
using namespace NLMISC;
|
|
||||||
using namespace NL3D;
|
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
|
|
||||||
// *************************************************************************************
|
|
||||||
CCustomMouse::CCursor::CCursor() : ColorDepth(CCustomMouse::ColorDepth32),
|
|
||||||
OrigHeight(32),
|
|
||||||
HotspotScale(1.f),
|
|
||||||
HotspotOffsetX(0),
|
|
||||||
HotspotOffsetY(0),
|
|
||||||
HotSpotX(0),
|
|
||||||
HotSpotY(0),
|
|
||||||
Icon(0),
|
|
||||||
Col(CRGBA::White),
|
|
||||||
Rot(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// *************************************************************************************
|
|
||||||
CCustomMouse::CCursor::~CCursor()
|
|
||||||
{
|
|
||||||
if (Icon)
|
|
||||||
{
|
|
||||||
DestroyIcon(Icon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// *************************************************************************************
|
|
||||||
CCustomMouse::CCustomMouse()
|
|
||||||
{
|
|
||||||
_ColorDepth = CCustomMouse::ColorDepth32;
|
|
||||||
_DefaultCursor = LoadCursor(NULL, IDC_ARROW);
|
|
||||||
_AlphaBlendedCursorSupported = false;
|
|
||||||
_AlphaBlendedCursorSupportRetrieved = false;
|
|
||||||
_CurrCol = CRGBA::White;
|
|
||||||
_CurrRot = 0;
|
|
||||||
_CurrHotSpotX = 0;
|
|
||||||
_CurrHotSpotY = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// *************************************************************************************
|
|
||||||
bool CCustomMouse::isAlphaBlendedCursorSupported()
|
|
||||||
{
|
|
||||||
if (!_AlphaBlendedCursorSupportRetrieved)
|
|
||||||
{
|
|
||||||
// Support starts with windows 2000 (not only from XP as seen in most docs)
|
|
||||||
// NB : Additionnaly, could query D3D caps to know if
|
|
||||||
// color hardware cursor is supported, not only emulated,
|
|
||||||
// but can't be sure that using the win32 api 'SetCursor' uses the same resources
|
|
||||||
// So far, seems to be supported on any modern card used by the game anyway ...
|
|
||||||
OSVERSIONINFO osvi;
|
|
||||||
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
||||||
if (GetVersionEx(&osvi))
|
|
||||||
{
|
|
||||||
_AlphaBlendedCursorSupported = (osvi.dwMajorVersion >= 5);
|
|
||||||
}
|
|
||||||
_AlphaBlendedCursorSupportRetrieved = true;
|
|
||||||
}
|
|
||||||
return _AlphaBlendedCursorSupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VerboseCursorRT12516 = true;
|
|
||||||
|
|
||||||
namespace NLMISC
|
|
||||||
{
|
|
||||||
extern bool TempMaxVerboseResample;
|
|
||||||
}
|
|
||||||
|
|
||||||
// *************************************************************************************
|
|
||||||
void CCustomMouse::addCursor(const std::string &name, const NLMISC::CBitmap &cursorBitmap)
|
|
||||||
{
|
|
||||||
if (!isAlphaBlendedCursorSupported()) return;
|
|
||||||
nlassert(cursorBitmap.getWidth() != 0);
|
|
||||||
nlassert(cursorBitmap.getHeight() != 0);
|
|
||||||
// find used part base on alpha, to avoid too much shrinking
|
|
||||||
const CRGBA *pixels = (const CRGBA *) &cursorBitmap.getPixels()[0];
|
|
||||||
uint minX, maxX, minY, maxY;
|
|
||||||
uint width = cursorBitmap.getWidth();
|
|
||||||
uint height = cursorBitmap.getHeight();
|
|
||||||
//
|
|
||||||
minX = 0;
|
|
||||||
for (uint x = 0; x < width; ++x)
|
|
||||||
{
|
|
||||||
bool stop = false;
|
|
||||||
minX = x;
|
|
||||||
for (uint y = 0; y < height; ++y)
|
|
||||||
{
|
|
||||||
if(pixels[x + y * width].A != 0)
|
|
||||||
{
|
|
||||||
stop = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (stop) break;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
maxX = width - 1;
|
|
||||||
for (sint x = width - 1; x >= 0; --x)
|
|
||||||
{
|
|
||||||
bool stop = false;
|
|
||||||
maxX = (uint) x;
|
|
||||||
for (uint y = 0; y < height; ++y)
|
|
||||||
{
|
|
||||||
if(pixels[x + y * width].A != 0)
|
|
||||||
{
|
|
||||||
stop = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (stop) break;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
minY = 0;
|
|
||||||
for (uint y = 0; y < height; ++y)
|
|
||||||
{
|
|
||||||
bool stop = false;
|
|
||||||
minY = y;
|
|
||||||
for (uint x = 0; x < width; ++x)
|
|
||||||
{
|
|
||||||
if(pixels[x + y * width].A != 0)
|
|
||||||
{
|
|
||||||
stop = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (stop) break;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
maxY = height - 1;
|
|
||||||
for (sint y = height - 1; y >= 0; --y)
|
|
||||||
{
|
|
||||||
bool stop = false;
|
|
||||||
maxY = (uint) y;
|
|
||||||
for (uint x = 0; x < width; ++x)
|
|
||||||
{
|
|
||||||
if(pixels[x + y * width].A != 0)
|
|
||||||
{
|
|
||||||
stop = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (stop) break;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
CCursor &curs = _Cursors[name];
|
|
||||||
curs = CCursor(); // erase possible previous cursor
|
|
||||||
|
|
||||||
uint destWidth = GetSystemMetrics(SM_CXCURSOR);
|
|
||||||
uint destHeight = GetSystemMetrics(SM_CYCURSOR);
|
|
||||||
// build a square bitmap
|
|
||||||
uint tmpSize = std::max(maxX - minX + 1, maxY - minY + 1);
|
|
||||||
curs.Src.resize(tmpSize, tmpSize),
|
|
||||||
// blit at top left corner
|
|
||||||
curs.Src.blit(cursorBitmap, minX, minY, maxX - minX + 1, maxY - minY + 1, 0, 0);
|
|
||||||
|
|
||||||
curs.OrigHeight = cursorBitmap.getHeight();
|
|
||||||
curs.HotspotOffsetX = minX;
|
|
||||||
curs.HotspotOffsetY = minY;
|
|
||||||
//
|
|
||||||
curs.HotspotScale = ClientCfg.HardwareCursorScale;
|
|
||||||
clamp(curs.HotspotScale, 0.f, 1.f);
|
|
||||||
// first resampling, same for all cursors
|
|
||||||
tmpSize = (uint) (tmpSize * curs.HotspotScale);
|
|
||||||
if (tmpSize == 0) tmpSize = 1;
|
|
||||||
|
|
||||||
if (VerboseCursorRT12516 && ((name == "curs_stop.tga") || (name == "curs_pick_dup.tga")))
|
|
||||||
TempMaxVerboseResample = true;
|
|
||||||
|
|
||||||
if (TempMaxVerboseResample)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//nldebug("RT12516: BEFORE FIRST RESAMPLE");
|
|
||||||
//nldebug("RT12516: %s: curs=%p curs.Src=%p curs.Src.PixelPtr=%p", name.c_str(), &curs, &(curs.Src), &curs.Src.getPixels(0)[0]);
|
|
||||||
//nldebug("RT12516: %s: curs.Src.PixelSize=%u", name.c_str(), curs.Src.getPixels(0).size());
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
//nldebug("RT12516: An exception occurred!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TMP for RT 12406
|
|
||||||
/* nlwarning("Resampling mouse %s cursor : initial size = %d x %d, new size = %d x %d",
|
|
||||||
name.c_str(),
|
|
||||||
curs.Src.getWidth(),
|
|
||||||
curs.Src.getHeight(),
|
|
||||||
tmpSize,
|
|
||||||
tmpSize
|
|
||||||
);*/
|
|
||||||
curs.Src.resample(tmpSize, tmpSize);
|
|
||||||
|
|
||||||
if (TempMaxVerboseResample)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//nldebug("RT12516: AFTER FIRST RESAMPLE");
|
|
||||||
//nldebug("RT12516: %s: curs=%p curs.Src=%p curs.Src.PixelPtr=%p", name.c_str(), &curs, &(curs.Src), &curs.Src.getPixels(0)[0]);
|
|
||||||
//nldebug("RT12516: %s: curs.Src.PixelSize=%u", name.c_str(), curs.Src.getPixels(0).size());
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
//nldebug("RT12516: An exception occurred!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// shrink if necessary
|
|
||||||
if (tmpSize > destWidth || tmpSize > destHeight) // need to shrink ?
|
|
||||||
{
|
|
||||||
// constraint proportions
|
|
||||||
curs.HotspotScale *= std::min(float(destWidth) / tmpSize, float(destHeight) / tmpSize);
|
|
||||||
// TMP for RT 12406
|
|
||||||
/* nlwarning("Resampling mouse %s cursor : initial size = %d x %d, new size = %d x %d",
|
|
||||||
name.c_str(),
|
|
||||||
curs.Src.getWidth(),
|
|
||||||
curs.Src.getHeight(),
|
|
||||||
destWidth,
|
|
||||||
destHeight
|
|
||||||
);*/
|
|
||||||
curs.Src.resample(destWidth, destHeight);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CBitmap final;
|
|
||||||
final.resize(destWidth, destHeight);
|
|
||||||
final.blit(&curs.Src, 0, 0);
|
|
||||||
curs.Src.swap(final);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TempMaxVerboseResample)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//nldebug("RT12516: AFTER SECOND RESAMPLE");
|
|
||||||
//nldebug("RT12516: %s: curs=%p curs.Src=%p curs.Src.PixelPtr=%p", name.c_str(), &curs, &(curs.Src), &curs.Src.getPixels(0)[0]);
|
|
||||||
//nldebug("RT12516: %s: curs.Src.PixelSize=%u", name.c_str(), curs.Src.getPixels(0).size());
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
//nldebug("RT12516: An exception occurred!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name == _CurrName)
|
|
||||||
{
|
|
||||||
updateCursor();
|
|
||||||
}
|
|
||||||
TempMaxVerboseResample = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// *************************************************************************************
|
|
||||||
void CCustomMouse::release()
|
|
||||||
{
|
|
||||||
if (!isAlphaBlendedCursorSupported()) return;
|
|
||||||
nlassert(Driver);
|
|
||||||
HWND drvWnd = Driver->getDisplay();
|
|
||||||
if (drvWnd)
|
|
||||||
{
|
|
||||||
SetClassLongPtr(drvWnd, GCLP_HCURSOR, 0);
|
|
||||||
}
|
|
||||||
_Cursors.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// *************************************************************************************
|
|
||||||
void CCustomMouse::setColorDepth(TColorDepth colorDepth)
|
|
||||||
{
|
|
||||||
if (colorDepth == _ColorDepth) return;
|
|
||||||
_ColorDepth = colorDepth;
|
|
||||||
updateCursor(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// *************************************************************************************
|
|
||||||
void CCustomMouse::updateCursor(bool forceRebuild)
|
|
||||||
{
|
|
||||||
if (!Driver) return;
|
|
||||||
setCursor(_CurrName, _CurrCol, _CurrRot, _CurrHotSpotX, _CurrHotSpotY, forceRebuild);
|
|
||||||
}
|
|
||||||
|
|
||||||
// *************************************************************************************
|
|
||||||
void CCustomMouse::setCursor(const std::string &name, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY, bool forceRebuild)
|
|
||||||
{
|
|
||||||
if (!isAlphaBlendedCursorSupported()) return;
|
|
||||||
_CurrName = name;
|
|
||||||
_CurrCol = col;
|
|
||||||
_CurrRot = rot;
|
|
||||||
_CurrHotSpotX = hotSpotX;
|
|
||||||
_CurrHotSpotY = hotSpotY;
|
|
||||||
//
|
|
||||||
if (rot > 3) rot = 3; // same than 'CViewRenderer::drawRotFlipBitmapTiled
|
|
||||||
TIconMap::iterator it = _Cursors.find(name);
|
|
||||||
HCURSOR cursorHandle = _DefaultCursor;
|
|
||||||
if (it != _Cursors.end())
|
|
||||||
{
|
|
||||||
// Update cursor if modified or not already built
|
|
||||||
CCursor &curs = it->second;
|
|
||||||
hotSpotX = (sint) (curs.HotspotScale * (hotSpotX - curs.HotspotOffsetX));
|
|
||||||
hotSpotY = (sint) (curs.HotspotScale * ((curs.OrigHeight - hotSpotY) - curs.HotspotOffsetY));
|
|
||||||
if (curs.Icon == 0 ||
|
|
||||||
curs.HotSpotX != hotSpotX ||
|
|
||||||
curs.HotSpotY != hotSpotY ||
|
|
||||||
curs.Col != col ||
|
|
||||||
curs.Rot != rot ||
|
|
||||||
curs.ColorDepth != _ColorDepth ||
|
|
||||||
forceRebuild
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (curs.Icon != 0)
|
|
||||||
{
|
|
||||||
DestroyIcon(curs.Icon);
|
|
||||||
}
|
|
||||||
curs.Icon = buildCursor(curs.Src, col, rot, hotSpotX, hotSpotY);
|
|
||||||
curs.Col = col;
|
|
||||||
curs.Rot = rot;
|
|
||||||
curs.HotSpotX = hotSpotX;
|
|
||||||
curs.HotSpotY = hotSpotY;
|
|
||||||
curs.ColorDepth = _ColorDepth;
|
|
||||||
}
|
|
||||||
cursorHandle = curs.Icon ? (HCURSOR) curs.Icon : _DefaultCursor;
|
|
||||||
}
|
|
||||||
if (IsSystemCursorInClientArea() || IsSystemCursorCaptured() || forceRebuild)
|
|
||||||
{
|
|
||||||
if (CInputHandlerManager::getInstance()->hasFocus())
|
|
||||||
{
|
|
||||||
::SetCursor(cursorHandle);
|
|
||||||
HWND drvWnd = Driver->getDisplay();
|
|
||||||
if (drvWnd)
|
|
||||||
{
|
|
||||||
SetClassLongPtr(drvWnd, GCLP_HCURSOR, (LONG_PTR) cursorHandle); // set default mouse icon to the last one
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// *************************************************************************************
|
|
||||||
HICON CCustomMouse::buildCursor(const CBitmap &src, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY)
|
|
||||||
{
|
|
||||||
nlassert(isAlphaBlendedCursorSupported());
|
|
||||||
uint mouseW = GetSystemMetrics(SM_CXCURSOR);
|
|
||||||
uint mouseH = GetSystemMetrics(SM_CYCURSOR);
|
|
||||||
nlassert(src.getWidth() == mouseW);
|
|
||||||
nlassert(src.getHeight() == mouseH);
|
|
||||||
CBitmap rotSrc = src;
|
|
||||||
if (rot > 3) rot = 3; // mimic behavior of 'CViewRenderer::drawRotFlipBitmapTiled' (why not rot & 3 ??? ...)
|
|
||||||
switch(rot)
|
|
||||||
{
|
|
||||||
case 0: break;
|
|
||||||
case 1: rotSrc.rot90CW(); break;
|
|
||||||
case 2: rotSrc.rot90CW(); rotSrc.rot90CW(); break;
|
|
||||||
case 3: rotSrc.rot90CCW(); break;
|
|
||||||
}
|
|
||||||
return rotSrc.getHICON(mouseW, mouseH, _ColorDepth == ColorDepth16 ? 16:32, col, hotSpotX, hotSpotY, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// *************************************************************************************
|
|
||||||
void CCustomMouse::setSystemArrow()
|
|
||||||
{
|
|
||||||
extern HINSTANCE HInstance;
|
|
||||||
HCURSOR arrow = LoadCursor(NULL, IDC_ARROW);
|
|
||||||
if (IsSystemCursorInClientArea() || IsSystemCursorCaptured())
|
|
||||||
{
|
|
||||||
::SetCursor(arrow);
|
|
||||||
}
|
|
||||||
HWND drvWnd = Driver->getDisplay();
|
|
||||||
if (drvWnd)
|
|
||||||
{
|
|
||||||
SetClassLongPtr(drvWnd, GCLP_HCURSOR, (LONG_PTR) arrow); // set default mouse icon to the last one
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// not implemented yet for other OS
|
|
||||||
|
|
||||||
// *************************************************************************************
|
|
||||||
CCustomMouse::CCustomMouse()
|
|
||||||
{
|
|
||||||
// NOT IMPLEMENTED
|
|
||||||
}
|
|
||||||
|
|
||||||
// *************************************************************************************
|
|
||||||
void CCustomMouse::setCursor(const std::string &name, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY, bool forceRebuild)
|
|
||||||
{
|
|
||||||
// NOT IMPLEMENTED
|
|
||||||
}
|
|
||||||
|
|
||||||
// *************************************************************************************
|
|
||||||
void CCustomMouse::release()
|
|
||||||
{
|
|
||||||
// NOT IMPLEMENTED
|
|
||||||
}
|
|
||||||
|
|
||||||
// *************************************************************************************
|
|
||||||
bool CCustomMouse::isAlphaBlendedCursorSupported()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// *************************************************************************************
|
|
||||||
void CCustomMouse::setSystemArrow()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCustomMouse::addCursor(const std::string &name, const NLMISC::CBitmap &cursorBitmap)
|
|
||||||
{
|
|
||||||
// TODO for Linux
|
|
||||||
}
|
|
||||||
|
|
||||||
// *************************************************************************************
|
|
||||||
void CCustomMouse::setColorDepth(TColorDepth colorDepth)
|
|
||||||
{
|
|
||||||
// TODO for Linux
|
|
||||||
}
|
|
||||||
|
|
||||||
// *************************************************************************************
|
|
||||||
void CCustomMouse::updateCursor(bool forceRebuild)
|
|
||||||
{
|
|
||||||
// TODO for Linux
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // NL_OS_WINDOWS
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,116 +0,0 @@
|
||||||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
|
||||||
// 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/>.
|
|
||||||
|
|
||||||
#ifndef RY_CUSTOM_MOUSE_H
|
|
||||||
#define RY_CUSTOM_MOUSE_H
|
|
||||||
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
#include <windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "nel/misc/rgba.h"
|
|
||||||
#include "nel/misc/bitmap.h"
|
|
||||||
#include "nel/misc/common.h"
|
|
||||||
|
|
||||||
namespace NL3D
|
|
||||||
{
|
|
||||||
class UTexture;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TMP Nico : made a separate class to avoid a lot of compilation until it works
|
|
||||||
class CCustomMouse
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum TColorDepth { ColorDepth16 = 0, ColorDepth32, ColorDepthCount };
|
|
||||||
CCustomMouse();
|
|
||||||
/** Signal a change of color depth (of desktop if windowed, or video mode if fullscreen)
|
|
||||||
* This is necessary to have the cursor built with good format
|
|
||||||
*/
|
|
||||||
void setColorDepth(TColorDepth colorDepth);
|
|
||||||
// Add a new cursor (name is case unsensitive)
|
|
||||||
void addCursor(const std::string &name, const NLMISC::CBitmap &cursorBitmap);
|
|
||||||
// Display a cursor from its name (case unsensitive)
|
|
||||||
void setCursor(const std::string &name, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY, bool forceRebuild = false);
|
|
||||||
void updateCursor(bool forceRebuild = false);
|
|
||||||
void release();
|
|
||||||
bool isAlphaBlendedCursorSupported();
|
|
||||||
// reset the cursor shape to the system arrow
|
|
||||||
void setSystemArrow();
|
|
||||||
private:
|
|
||||||
#ifdef NL_OS_WINDOWS
|
|
||||||
TColorDepth _ColorDepth;
|
|
||||||
std::string _CurrName;
|
|
||||||
NLMISC::CRGBA _CurrCol;
|
|
||||||
uint8 _CurrRot;
|
|
||||||
uint _CurrHotSpotX;
|
|
||||||
uint _CurrHotSpotY;
|
|
||||||
//
|
|
||||||
class CCursor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
NLMISC::CBitmap Src;
|
|
||||||
TColorDepth ColorDepth;
|
|
||||||
uint OrigHeight;
|
|
||||||
float HotspotScale;
|
|
||||||
uint HotspotOffsetX;
|
|
||||||
uint HotspotOffsetY;
|
|
||||||
sint HotSpotX;
|
|
||||||
sint HotSpotY;
|
|
||||||
HICON Icon;
|
|
||||||
NLMISC::CRGBA Col;
|
|
||||||
uint8 Rot;
|
|
||||||
public:
|
|
||||||
CCursor();
|
|
||||||
~CCursor();
|
|
||||||
CCursor& operator= (const CCursor& from)
|
|
||||||
{
|
|
||||||
if (&from == this)
|
|
||||||
return *this;
|
|
||||||
Src = from.Src; // requires more than a surface copy
|
|
||||||
OrigHeight = from.OrigHeight;
|
|
||||||
HotspotScale = from.HotspotScale;
|
|
||||||
HotspotOffsetX = from.HotspotOffsetX;
|
|
||||||
HotspotOffsetY = from.HotspotOffsetY;
|
|
||||||
HotSpotX = from.HotSpotX;
|
|
||||||
HotSpotY = from.HotSpotY;
|
|
||||||
Icon = from.Icon;
|
|
||||||
Col = from.Col;
|
|
||||||
Rot = from.Rot;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
struct CStrCaseUnsensitiveCmp
|
|
||||||
{
|
|
||||||
bool operator()(const std::string &lhs, const std::string &rhs) const
|
|
||||||
{
|
|
||||||
return NLMISC::nlstricmp(lhs, rhs) < 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
typedef std::map<std::string, CCursor, CStrCaseUnsensitiveCmp> TIconMap;
|
|
||||||
TIconMap _Cursors;
|
|
||||||
HCURSOR _DefaultCursor;
|
|
||||||
bool _AlphaBlendedCursorSupported;
|
|
||||||
bool _AlphaBlendedCursorSupportRetrieved;
|
|
||||||
private:
|
|
||||||
// build a cursor from src, src should have the same size that the hardware cursor
|
|
||||||
// or a assertion is thrown
|
|
||||||
HICON buildCursor(const NLMISC::CBitmap &src, NLMISC::CRGBA col, uint8 rot, sint hotSpotX, sint hotSpotY);
|
|
||||||
#endif // NL_OS_WINDOWS
|
|
||||||
};
|
|
||||||
|
|
||||||
extern CCustomMouse CustomMouse;
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -29,7 +29,6 @@
|
||||||
#include "../actions.h"
|
#include "../actions.h"
|
||||||
#include "../input.h"
|
#include "../input.h"
|
||||||
#include "../client_cfg.h"
|
#include "../client_cfg.h"
|
||||||
#include "custom_mouse.h"
|
|
||||||
#include "../motion/user_controls.h"
|
#include "../motion/user_controls.h"
|
||||||
#include "../init.h"
|
#include "../init.h"
|
||||||
#include "../release.h"
|
#include "../release.h"
|
||||||
|
@ -65,6 +64,7 @@ CInputHandlerManager::CInputHandlerManager()
|
||||||
_MouseButtonsState = noButton;
|
_MouseButtonsState = noButton;
|
||||||
_MouseX = _MouseY = _MouseLastX = _MouseLastY = 0;
|
_MouseX = _MouseY = _MouseLastX = _MouseLastY = 0;
|
||||||
_Focus = true;
|
_Focus = true;
|
||||||
|
// Driver->setFocus(true);
|
||||||
_MouseWheel = 0;
|
_MouseWheel = 0;
|
||||||
_SkipInterfaceManager=false;
|
_SkipInterfaceManager=false;
|
||||||
_RecoverFocusLost = false;
|
_RecoverFocusLost = false;
|
||||||
|
@ -143,16 +143,6 @@ void CInputHandlerManager::operator ()(const NLMISC::CEvent &event)
|
||||||
|
|
||||||
if (event == EventDisplayChangeId)
|
if (event == EventDisplayChangeId)
|
||||||
{
|
{
|
||||||
switch (getCurrentColorDepth())
|
|
||||||
{
|
|
||||||
case 16: CustomMouse.setColorDepth(CCustomMouse::ColorDepth16); break;
|
|
||||||
case 24:
|
|
||||||
case 32: CustomMouse.setColorDepth(CCustomMouse::ColorDepth32); break;
|
|
||||||
default:
|
|
||||||
release();
|
|
||||||
ExitClientError(CI18N::get("uiUnsupportedNewColorDepth").toUtf8().c_str());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process message to InterfaceManager
|
// Process message to InterfaceManager
|
||||||
|
@ -168,6 +158,7 @@ void CInputHandlerManager::operator ()(const NLMISC::CEvent &event)
|
||||||
_MouseButtonsReleased = noButton;
|
_MouseButtonsReleased = noButton;
|
||||||
_MouseButtonsState = noButton;
|
_MouseButtonsState = noButton;
|
||||||
_Focus = false;
|
_Focus = false;
|
||||||
|
// Driver->setFocus(false);
|
||||||
|
|
||||||
if (!_SkipInterfaceManager)
|
if (!_SkipInterfaceManager)
|
||||||
{
|
{
|
||||||
|
@ -186,13 +177,14 @@ void CInputHandlerManager::operator ()(const NLMISC::CEvent &event)
|
||||||
}
|
}
|
||||||
// be nice with other app : let the mouse reappear (useful in direct 3D mode with no hardware cursor)
|
// be nice with other app : let the mouse reappear (useful in direct 3D mode with no hardware cursor)
|
||||||
Driver->showCursor(true);
|
Driver->showCursor(true);
|
||||||
CustomMouse.setSystemArrow();
|
// Driver->setSystemArrow();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_RecoverFocusLost = true; // force to update mouse pos on next click or move
|
_RecoverFocusLost = true; // force to update mouse pos on next click or move
|
||||||
Driver->showCursor(IsMouseCursorHardware());
|
Driver->showCursor(IsMouseCursorHardware());
|
||||||
_Focus = true;
|
_Focus = true;
|
||||||
|
// Driver->setFocus(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!_SkipInterfaceManager)
|
if(!_SkipInterfaceManager)
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include "stdpch.h"
|
#include "stdpch.h"
|
||||||
|
|
||||||
#include "../input.h"
|
#include "../input.h"
|
||||||
#include "custom_mouse.h"
|
|
||||||
//
|
//
|
||||||
#include "view_pointer.h"
|
#include "view_pointer.h"
|
||||||
#include "interface_manager.h"
|
#include "interface_manager.h"
|
||||||
|
@ -692,17 +691,17 @@ void CViewPointer::drawCursor(sint32 texId, NLMISC::CRGBA col, uint8 rot)
|
||||||
{
|
{
|
||||||
CInterfaceManager *pIM = CInterfaceManager::getInstance();
|
CInterfaceManager *pIM = CInterfaceManager::getInstance();
|
||||||
CViewRenderer &rVR = pIM->getViewRenderer();
|
CViewRenderer &rVR = pIM->getViewRenderer();
|
||||||
|
sint32 xPos = _XReal + _OffsetX;
|
||||||
|
sint32 yPos = _YReal + _OffsetY;
|
||||||
if (!IsMouseCursorHardware())
|
if (!IsMouseCursorHardware())
|
||||||
{
|
{
|
||||||
sint32 xPos = _XReal + _OffsetX;
|
|
||||||
sint32 yPos = _YReal + _OffsetY;
|
|
||||||
rVR.draw11RotFlipBitmap (_RenderLayer, xPos, yPos, rot, false, texId, col);
|
rVR.draw11RotFlipBitmap (_RenderLayer, xPos, yPos, rot, false, texId, col);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// set new cursor for the hardware mouse
|
// set new cursor for the hardware mouse
|
||||||
std::string name = rVR.getTextureNameFromId(texId);
|
std::string name = rVR.getTextureNameFromId(texId);
|
||||||
CustomMouse.setCursor(name, col, rot, (uint32) std::max(getX() - (_XReal + _OffsetX), (sint32) 0), (uint32) std::max(getY() - (_YReal + _OffsetY), (sint32) 0));
|
Driver->setCursor(name, col, rot, (uint32) std::max(getX() - xPos, (sint32) 0), (uint32) std::max(getY() - yPos, (sint32) 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include "nel/misc/uv.h"
|
#include "nel/misc/uv.h"
|
||||||
#include "nel/misc/hierarchical_timer.h"
|
#include "nel/misc/hierarchical_timer.h"
|
||||||
#include "interface_manager.h"
|
#include "interface_manager.h"
|
||||||
#include "custom_mouse.h"
|
|
||||||
#include "../client_cfg.h"
|
#include "../client_cfg.h"
|
||||||
|
|
||||||
using namespace NLMISC;
|
using namespace NLMISC;
|
||||||
|
@ -730,6 +729,8 @@ void CViewRenderer::loadTextures (const std::string &textureFileName, const std:
|
||||||
|
|
||||||
_GlobalTextures.push_back (gt);
|
_GlobalTextures.push_back (gt);
|
||||||
|
|
||||||
|
// Driver->setHardwareCursorScale(ClientCfg.HardwareCursorScale);
|
||||||
|
|
||||||
char bufTmp[256], tgaName[256];
|
char bufTmp[256], tgaName[256];
|
||||||
string sTGAname;
|
string sTGAname;
|
||||||
float uvMinU, uvMinV, uvMaxU, uvMaxV;
|
float uvMinU, uvMinV, uvMaxU, uvMaxV;
|
||||||
|
@ -767,23 +768,20 @@ void CViewRenderer::loadTextures (const std::string &textureFileName, const std:
|
||||||
}
|
}
|
||||||
|
|
||||||
// if this is a cursor texture, extract it now (supported for rgba only now, because of the blit)
|
// if this is a cursor texture, extract it now (supported for rgba only now, because of the blit)
|
||||||
if (CustomMouse.isAlphaBlendedCursorSupported())
|
if (texDatas && texDatas->getPixelFormat() == CBitmap::RGBA)
|
||||||
{
|
{
|
||||||
if (texDatas && texDatas->getPixelFormat() == CBitmap::RGBA)
|
if (ClientCfg.HardwareCursors.count(image.Name))
|
||||||
{
|
{
|
||||||
if (ClientCfg.HardwareCursors.count(image.Name))
|
uint x0 = (uint) (image.UVMin.U * gt.Width);
|
||||||
|
uint y0 = (uint) (image.UVMin.V * gt.Height);
|
||||||
|
uint x1 = (uint) (image.UVMax.U * gt.Width);
|
||||||
|
uint y1 = (uint) (image.UVMax.V * gt.Height);
|
||||||
|
if (x1 != x0 && y1 != y0)
|
||||||
{
|
{
|
||||||
uint x0 = (uint) (image.UVMin.U * gt.Width);
|
CBitmap curs;
|
||||||
uint y0 = (uint) (image.UVMin.V * gt.Height);
|
curs.resize(x1 - x0, y1 - y0);
|
||||||
uint x1 = (uint) (image.UVMax.U * gt.Width);
|
curs.blit(*texDatas, x0, y0, (x1 - x0), (y1 - y0), 0, 0);
|
||||||
uint y1 = (uint) (image.UVMax.V * gt.Height);
|
Driver->addCursor(image.Name, curs);
|
||||||
if (x1 != x0 && y1 != y0)
|
|
||||||
{
|
|
||||||
CBitmap curs;
|
|
||||||
curs.resize(x1 - x0, y1 - y0);
|
|
||||||
curs.blit(*texDatas, x0, y0, (x1 - x0), (y1 - y0), 0, 0);
|
|
||||||
CustomMouse.addCursor(image.Name, curs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,6 @@
|
||||||
#include "interface_v3/music_player.h"
|
#include "interface_v3/music_player.h"
|
||||||
#include "http_client.h"
|
#include "http_client.h"
|
||||||
#include "actions_client.h"
|
#include "actions_client.h"
|
||||||
#include "interface_v3/custom_mouse.h"
|
|
||||||
#include "login_progress_post_thread.h"
|
#include "login_progress_post_thread.h"
|
||||||
//
|
//
|
||||||
#include "r2/editor.h"
|
#include "r2/editor.h"
|
||||||
|
@ -502,8 +501,6 @@ void releaseOutGame()
|
||||||
// Remove the Actions listener from the Events Server.
|
// Remove the Actions listener from the Events Server.
|
||||||
EventsListener.removeFromServer(CInputHandlerManager::getInstance()->FilteredEventServer);
|
EventsListener.removeFromServer(CInputHandlerManager::getInstance()->FilteredEventServer);
|
||||||
|
|
||||||
CustomMouse.release();
|
|
||||||
|
|
||||||
// Release Bloom
|
// Release Bloom
|
||||||
CBloomEffect::releaseInstance();
|
CBloomEffect::releaseInstance();
|
||||||
|
|
||||||
|
@ -574,8 +571,6 @@ void release()
|
||||||
Driver->deleteTextContext(TextContext);
|
Driver->deleteTextContext(TextContext);
|
||||||
TextContext = NULL;
|
TextContext = NULL;
|
||||||
|
|
||||||
CustomMouse.release();
|
|
||||||
|
|
||||||
// Release Bloom
|
// Release Bloom
|
||||||
CBloomEffect::releaseInstance();
|
CBloomEffect::releaseInstance();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue