فهرست منبع

WIP: Linux port
- Finishing up the main event loop
- Variety of compiler error & warning fixes

Marko Pintera 8 سال پیش
والد
کامیت
eb86ee0346

+ 1 - 1
Source/BansheeCore/Components/BsCAnimation.cpp

@@ -493,7 +493,7 @@ namespace bs
 		{
 		{
 			HSceneObject root = SO();
 			HSceneObject root = SO();
 
 
-			auto& findMappings = [&](const String& name, AnimationCurveFlags flags)
+			const auto& findMappings = [&](const String& name, AnimationCurveFlags flags)
 			{
 			{
 				if (flags.isSet(AnimationCurveFlag::ImportedCurve))
 				if (flags.isSet(AnimationCurveFlag::ImportedCurve))
 					return;
 					return;

+ 6 - 2
Source/BansheeCore/Components/BsCCamera.cpp

@@ -4,6 +4,7 @@
 #include "RTTI/BsCCameraRTTI.h"
 #include "RTTI/BsCCameraRTTI.h"
 #include "Scene/BsSceneObject.h"
 #include "Scene/BsSceneObject.h"
 #include "Scene/BsSceneManager.h"
 #include "Scene/BsSceneManager.h"
+#include "BsCoreApplication.h"
 
 
 namespace bs 
 namespace bs 
 {
 {
@@ -15,8 +16,11 @@ namespace bs
 
 
 	CCamera::CCamera(const HSceneObject& parent, SPtr<RenderTarget> target, float left, float top, float width, float height)
 	CCamera::CCamera(const HSceneObject& parent, SPtr<RenderTarget> target, float left, float top, float width, float height)
 		: Component(parent), mTarget(target), mLeft(left), mTop(top), mWidth(width), mHeight(height)
 		: Component(parent), mTarget(target), mLeft(left), mTop(top), mWidth(width), mHeight(height)
-	{
-		setFlag(ComponentFlag::AlwaysRun, true);
+    {
+		if(mTarget == nullptr)
+			mTarget = CoreApplication::instance().getPrimaryWindow();
+
+		Component::setFlag(ComponentFlag::AlwaysRun, true);
 		setName("Camera");
 		setName("Camera");
 	}
 	}
 
 

+ 4 - 1
Source/BansheeCore/Image/BsPixelUtil.h

@@ -5,8 +5,11 @@
 #include "BsCorePrerequisites.h"
 #include "BsCorePrerequisites.h"
 #include "Image/BsPixelData.h"
 #include "Image/BsPixelData.h"
 
 
-namespace bs 
+namespace bs
 {
 {
+	// Undefine conflicting defines from other libs
+#undef None
+
 	/** @addtogroup Utility-Core
 	/** @addtogroup Utility-Core
 	 *  @{
 	 *  @{
 	 */
 	 */

+ 3 - 0
Source/BansheeCore/Input/BsInputFwd.h

@@ -7,6 +7,9 @@
 
 
 namespace bs
 namespace bs
 {
 {
+	// Undefine conflicting defines from other libs
+#undef None
+
 	/** @addtogroup Input
 	/** @addtogroup Input
 	 *  @{
 	 *  @{
 	 */
 	 */

+ 5 - 5
Source/BansheeCore/Linux/BsLinuxDragAndDrop.cpp

@@ -1,13 +1,13 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
-#include <X11/Xatom.h>
-#include <X11/Xlib.h>
-#include <String/BsUnicode.h>
+#include "String/BsUnicode.h"
 #include "Platform/BsPlatform.h"
 #include "Platform/BsPlatform.h"
 #include "RenderAPI/BsRenderWindow.h"
 #include "RenderAPI/BsRenderWindow.h"
 #include "BsLinuxDragAndDrop.h"
 #include "BsLinuxDragAndDrop.h"
 #include "BsLinuxWindow.h"
 #include "BsLinuxWindow.h"
 #include "BsLinuxPlatform.h"
 #include "BsLinuxPlatform.h"
+#include <X11/Xatom.h>
+#include <X11/Xlib.h>
 
 
 namespace bs
 namespace bs
 {
 {
@@ -18,7 +18,7 @@ namespace bs
 	INT32 LinuxDragAndDrop::sDNDVersion = 0;
 	INT32 LinuxDragAndDrop::sDNDVersion = 0;
 	::Window LinuxDragAndDrop::sDNDSource = None;
 	::Window LinuxDragAndDrop::sDNDSource = None;
 	Vector2I LinuxDragAndDrop::sDragPosition;
 	Vector2I LinuxDragAndDrop::sDragPosition;
-	Vector<DragAndDropOp> LinuxDragAndDrop::sQueuedOperations;
+	Vector<LinuxDragAndDrop::DragAndDropOp> LinuxDragAndDrop::sQueuedOperations;
 	Vector<OSDropTarget*> LinuxDragAndDrop::sTargetsToRegister;
 	Vector<OSDropTarget*> LinuxDragAndDrop::sTargetsToRegister;
 	Vector<OSDropTarget*> LinuxDragAndDrop::sTargetsToUnregister;
 	Vector<OSDropTarget*> LinuxDragAndDrop::sTargetsToUnregister;
 
 
@@ -209,7 +209,7 @@ namespace bs
 	void LinuxDragAndDrop::makeDNDAware(::Window xWindow)
 	void LinuxDragAndDrop::makeDNDAware(::Window xWindow)
 	{
 	{
 		UINT32 dndVersion = 5;
 		UINT32 dndVersion = 5;
-		XChangeProperty(sXDisplay, xWindow, sXdndAware, XA_ATOM, 32, PropModeReplace, (unsigned char*)dndVersion, 1);
+		XChangeProperty(sXDisplay, xWindow, sXdndAware, XA_ATOM, 32, PropModeReplace, (unsigned char*)&dndVersion, 1);
 	}
 	}
 
 
 	OSDropTarget& LinuxDragAndDrop::createDropTarget(const RenderWindow* window, INT32 x, INT32 y, UINT32 width,
 	OSDropTarget& LinuxDragAndDrop::createDropTarget(const RenderWindow* window, INT32 x, INT32 y, UINT32 width,

+ 2 - 2
Source/BansheeCore/Linux/BsLinuxDragAndDrop.h

@@ -36,12 +36,12 @@ namespace bs
 			{ }
 			{ }
 
 
 			DragAndDropOp(DragAndDropOpType type, OSDropTarget* target, const Vector2I& pos)
 			DragAndDropOp(DragAndDropOpType type, OSDropTarget* target, const Vector2I& pos)
-				:type(type), position(pos), target(target)
+				:type(type), target(target), position(pos)
 			{ }
 			{ }
 
 
 			DragAndDropOp(DragAndDropOpType type, OSDropTarget* target, const Vector2I& pos,
 			DragAndDropOp(DragAndDropOpType type, OSDropTarget* target, const Vector2I& pos,
 				const Vector<WString>& fileList)
 				const Vector<WString>& fileList)
-				:type(type), position(pos), target(target), fileList(fileList)
+				:type(type), target(target), position(pos), fileList(fileList)
 			{ }
 			{ }
 
 
 			DragAndDropOpType type;
 			DragAndDropOpType type;

+ 4 - 4
Source/BansheeCore/Linux/BsLinuxFolderMonitor.cpp

@@ -45,7 +45,7 @@ namespace bs
 
 
 		if(monitorSubdirectories)
 		if(monitorSubdirectories)
 		{
 		{
-			FileSystem::iterate(folderToMonitor, nullptr, [&pathToHandle](const Path& path)
+			FileSystem::iterate(folderToMonitor, nullptr, [this](const Path& path)
 			{
 			{
 				addPath(path);
 				addPath(path);
 				return true;
 				return true;
@@ -274,7 +274,7 @@ namespace bs
 			m->started = true;
 			m->started = true;
 		}
 		}
 
 
-		FolderWatchInfo* watchInfo = bs_new<FolderWatchInfo>(folderPath, subdirectories, changeFilter);
+		FolderWatchInfo* watchInfo = bs_new<FolderWatchInfo>(folderPath, m->inHandle, subdirectories, changeFilter);
 
 
 		// Register and start the monitor
 		// Register and start the monitor
 		{
 		{
@@ -366,7 +366,7 @@ namespace bs
 			if (length < 0)
 			if (length < 0)
 				return;
 				return;
 
 
-			UINT32 readPos = 0;
+			INT32 readPos = 0;
 			while(readPos < length)
 			while(readPos < length)
 			{
 			{
 				inotify_event* event = (inotify_event*)&buffer[readPos];
 				inotify_event* event = (inotify_event*)&buffer[readPos];
@@ -408,7 +408,7 @@ namespace bs
 						// Actually trigger the events
 						// Actually trigger the events
 
 
 						// File/folder was added
 						// File/folder was added
-						if(((event->mask & IN_CREATE | IN_MOVED_TO) != 0))
+						if(((event->mask & (IN_CREATE | IN_MOVED_TO)) != 0))
 						{
 						{
 							if (isDirectory)
 							if (isDirectory)
 							{
 							{

+ 219 - 71
Source/BansheeCore/Linux/BsLinuxPlatform.cpp

@@ -7,8 +7,12 @@
 #include "Linux/BsLinuxWindow.h"
 #include "Linux/BsLinuxWindow.h"
 #include "RenderAPI/BsRenderWindow.h"
 #include "RenderAPI/BsRenderWindow.h"
 #include "BsLinuxDragAndDrop.h"
 #include "BsLinuxDragAndDrop.h"
+#include "BsCoreApplication.h"
+#include <X11/X.h>
 #include <X11/Xatom.h>
 #include <X11/Xatom.h>
 #include <X11/Xcursor/Xcursor.h>
 #include <X11/Xcursor/Xcursor.h>
+#include <X11/Xlib.h>
+#include <X11/XKBlib.h>
 
 
 namespace bs
 namespace bs
 {
 {
@@ -20,7 +24,6 @@ namespace bs
 	Event<void(float)> Platform::onMouseWheelScrolled;
 	Event<void(float)> Platform::onMouseWheelScrolled;
 	Event<void(UINT32)> Platform::onCharInput;
 	Event<void(UINT32)> Platform::onCharInput;
 
 
-	Event<void(ct::RenderWindow*)> Platform::onMouseLeftWindow;
 	Event<void()> Platform::onMouseCaptureChanged;
 	Event<void()> Platform::onMouseCaptureChanged;
 
 
 	enum class X11CursorType
 	enum class X11CursorType
@@ -56,6 +59,10 @@ namespace bs
 		Time lastButtonPressTime;
 		Time lastButtonPressTime;
 
 
 		Atom atomDeleteWindow;
 		Atom atomDeleteWindow;
+		Atom atomWmState;
+		Atom atomWmStateHidden;
+		Atom atomWmStateMaxVert;
+		Atom atomWmStateMaxHorz;
 
 
 		// Clipboard
 		// Clipboard
 		WString clipboardData;
 		WString clipboardData;
@@ -141,19 +148,19 @@ namespace bs
 		if(!data->cursorClipEnabled)
 		if(!data->cursorClipEnabled)
 			return false;
 			return false;
 
 
-		int32_t clippedX = pos.x - data->cursorClipRect.x;
-		int32_t clippedY = pos.y - data->cursorClipRect.y;
+		INT32 clippedX = pos.x - data->cursorClipRect.x;
+		INT32 clippedY = pos.y - data->cursorClipRect.y;
 
 
 		if(clippedX < 0)
 		if(clippedX < 0)
 			clippedX = data->cursorClipRect.x + data->cursorClipRect.width + clippedX;
 			clippedX = data->cursorClipRect.x + data->cursorClipRect.width + clippedX;
-		else if(clippedX >= data->cursorClipRect.width)
+		else if(clippedX >= (INT32)data->cursorClipRect.width)
 			clippedX = data->cursorClipRect.x + (clippedX - data->cursorClipRect.width);
 			clippedX = data->cursorClipRect.x + (clippedX - data->cursorClipRect.width);
 		else
 		else
 			clippedX = data->cursorClipRect.x + clippedX;
 			clippedX = data->cursorClipRect.x + clippedX;
 
 
 		if(clippedY < 0)
 		if(clippedY < 0)
 			clippedY = data->cursorClipRect.y + data->cursorClipRect.height + clippedY;
 			clippedY = data->cursorClipRect.y + data->cursorClipRect.height + clippedY;
-		else if(clippedY >= data->cursorClipRect.height)
+		else if(clippedY >= (INT32)data->cursorClipRect.height)
 			clippedY = data->cursorClipRect.y + (clippedY - data->cursorClipRect.height);
 			clippedY = data->cursorClipRect.y + (clippedY - data->cursorClipRect.height);
 		else
 		else
 			clippedY = data->cursorClipRect.y + clippedY;
 			clippedY = data->cursorClipRect.y + clippedY;
@@ -204,7 +211,7 @@ namespace bs
 		LinuxWindow* linuxWindow;
 		LinuxWindow* linuxWindow;
 		window.getCustomAttribute("WINDOW", &linuxWindow);
 		window.getCustomAttribute("WINDOW", &linuxWindow);
 
 
-		uint32_t mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask;
+		UINT32 mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask;
 		XGrabPointer(mData->xDisplay, linuxWindow->_getXWindow(), False, mask, GrabModeAsync,
 		XGrabPointer(mData->xDisplay, linuxWindow->_getXWindow(), False, mask, GrabModeAsync,
 				GrabModeAsync, None, None, CurrentTime);
 				GrabModeAsync, None, None, CurrentTime);
 		XSync(mData->xDisplay, False);
 		XSync(mData->xDisplay, False);
@@ -316,8 +323,8 @@ namespace bs
 		Lock lock(mData->lock);
 		Lock lock(mData->lock);
 
 
 		XcursorImage* image = XcursorImageCreate((int)bgraData->getWidth(), (int)bgraData->getHeight());
 		XcursorImage* image = XcursorImageCreate((int)bgraData->getWidth(), (int)bgraData->getHeight());
-		image->xhot = hotSpot.x;
-		image->yhot = hotSpot.y;
+		image->xhot = (XcursorDim)hotSpot.x;
+		image->yhot = (XcursorDim)hotSpot.y;
 		image->delay = 0;
 		image->delay = 0;
 
 
 		memcpy(image->pixels, bgraData->getData(), bgraData->getSize());
 		memcpy(image->pixels, bgraData->getData(), bgraData->getSize());
@@ -448,10 +455,93 @@ namespace bs
 	WString Platform::keyCodeToUnicode(UINT32 keyCode)
 	WString Platform::keyCodeToUnicode(UINT32 keyCode)
 	{
 	{
 		Lock lock(mData->lock);
 		Lock lock(mData->lock);
-		// TODOPORT
+
+		// Note: Assuming the keyCode is equal to X11 KeySym. Which it is because that's how our input manager reports them.
+		KeySym keySym = (KeySym)keyCode;
+
+		XKeyPressedEvent event;
+		bs_zero_out(event);
+		event.keycode = XKeysymToKeycode(mData->xDisplay, keySym);
+		event.display = mData->xDisplay;
+
+		Status status;
+		char buffer[16];
+
+		INT32 length = Xutf8LookupString(mData->IC, &event, buffer, sizeof(buffer), nullptr, &status);
+		if(length > 0)
+		{
+			buffer[length] = '\0';
+
+			return UTF8::toWide(String(buffer));
+		}
+
 		return L"";
 		return L"";
 	}
 	}
 
 
+	/**
+	 * Converts an X11 KeySym code into an input command, if possible. Returns true if conversion was done.
+	 *
+	 * @param[in]	keySym			KeySym to try to translate to a command.
+	 * @param[in]	shift			True if the shift key was held down when the key was pressed.
+	 * @param[out]	command			Input command. Only valid if function returns true.
+	 * @return						True if the KeySym is an input command.
+	 */
+	bool parseInputCommand(KeySym keySym, bool shift, InputCommandType& command)
+	{
+		switch (keySym)
+		{
+		case XK_Left:
+			command = shift ? InputCommandType::SelectLeft : InputCommandType::CursorMoveLeft;
+			return true;
+		case XK_Right:
+			command = shift ? InputCommandType::SelectRight : InputCommandType::CursorMoveRight;
+			return true;
+		case XK_Up:
+			command = shift ? InputCommandType::SelectUp : InputCommandType::CursorMoveUp;
+			return true;
+		case XK_Down:
+			command = shift ? InputCommandType::SelectDown : InputCommandType::CursorMoveDown;
+			return true;
+		case XK_Escape:
+			command = InputCommandType::Escape;
+			return true;
+		case XK_ISO_Enter:
+			command = shift ? InputCommandType::Return : InputCommandType::Confirm;
+			return true;
+		case XK_BackSpace:
+			command = InputCommandType::Backspace;
+			return true;
+		case XK_Delete:
+			command = InputCommandType::Delete;
+			return true;
+		}
+
+		return false;
+	}
+
+	/** Returns a LinuxWindow from a native X11 window handle. */
+	LinuxWindow* getLinuxWindow(LinuxPlatform::Pimpl* data, ::Window xWindow)
+	{
+		auto iterFind = data->windowMap.find(xWindow);
+		if (iterFind != data->windowMap.end())
+		{
+			LinuxWindow* window = iterFind->second;
+			return window;
+		}
+
+		return nullptr;
+	}
+
+	/** Returns a RenderWindow from a native X11 window handle. Returns null if the window isn't a RenderWindow */
+	ct::RenderWindow* getRenderWindow(LinuxPlatform::Pimpl* data, ::Window xWindow)
+	{
+		LinuxWindow* linuxWindow = getLinuxWindow(data, xWindow);
+		if(linuxWindow != nullptr)
+			return (ct::RenderWindow*)linuxWindow->_getUserData();
+
+		return nullptr;
+	}
+
 	void Platform::_messagePump()
 	void Platform::_messagePump()
 	{
 	{
 		while(true)
 		while(true)
@@ -470,21 +560,21 @@ namespace bs
 				if(LinuxDragAndDrop::handleClientMessage(event.xclient))
 				if(LinuxDragAndDrop::handleClientMessage(event.xclient))
 					break;
 					break;
 
 
-				if(event.xclient.data.l[0] == mData->atomDeleteWindow)
+				if((Atom)event.xclient.data.l[0] == mData->atomDeleteWindow)
 					XDestroyWindow(mData->xDisplay, event.xclient.window);
 					XDestroyWindow(mData->xDisplay, event.xclient.window);
 			}
 			}
 				break;
 				break;
 			case DestroyNotify:
 			case DestroyNotify:
 			{
 			{
-				auto iterFind = mData->windowMap.find(event.xdestroywindow.window);
-				if (iterFind == mData->windowMap.end())
-					break;
-
-				LinuxWindow* window = iterFind->second;
-				window->_cleanUp();
+				LinuxWindow* window = getLinuxWindow(mData, event.xdestroywindow.window);
+				if(window != nullptr)
+				{
+					CoreApplication::instance().quitRequested();
+					window->_cleanUp();
 
 
-				if(mData->mainXWindow == 0)
-					return;
+					if (mData->mainXWindow == 0)
+						return;
+				}
 			}
 			}
 				break;
 				break;
 			case KeyPress:
 			case KeyPress:
@@ -509,33 +599,21 @@ namespace bs
 					}
 					}
 				}
 				}
 
 
-				// Process normal key press
-				{
-					static XComposeStatus keyboard;
-					uint8_t buffer[16];
-					KeySym symbol;
-					XLookupString(&event.xkey, (char*)buffer, sizeof(buffer), &symbol, &keyboard);
+				// Handle input commands
+				InputCommandType command = InputCommandType::Backspace;
 
 
-					bool alt = event.xkey.state & Mod1Mask;
-					bool control = event.xkey.state & ControlMask;
-					bool shift = event.xkey.state & ShiftMask;
+				KeySym keySym = XkbKeycodeToKeysym(mData->xDisplay, (KeyCode)event.xkey.keycode, 0, 0);
+				bool shift = (event.xkey.state & ShiftMask) != 0;
 
 
-					// TODOPORT - Report key press
+				if(parseInputCommand(keySym, shift, command))
+				{
+					if(!onInputCommand.empty())
+						onInputCommand(command);
 				}
 				}
 			}
 			}
 				break;
 				break;
 			case KeyRelease:
 			case KeyRelease:
-			{
-				uint8_t buffer[16];
-				KeySym symbol;
-				XLookupString(&event.xkey, (char *) buffer, sizeof(buffer), &symbol, nullptr);
-
-				bool alt = (event.xkey.state & Mod1Mask) != 0;
-				bool control = (event.xkey.state & ControlMask) != 0;
-				bool shift = (event.xkey.state & ShiftMask) != 0;
-
-				// TODOPORT - Report key release
-			}
+				// Do nothing
 				break;
 				break;
 			case ButtonPress:
 			case ButtonPress:
 			{
 			{
@@ -594,12 +672,9 @@ namespace bs
 				// Handle window dragging for windows without a title bar
 				// Handle window dragging for windows without a title bar
 				if(button == Button1)
 				if(button == Button1)
 				{
 				{
-					auto iterFind = mData->windowMap.find(event.xbutton.window);
-					if (iterFind != mData->windowMap.end())
-					{
-						LinuxWindow* window = iterFind->second;
+					LinuxWindow* window = getLinuxWindow(mData, event.xbutton.window);
+					if(window != nullptr)
 						window->_dragStart(event.xbutton.x, event.xbutton.y);
 						window->_dragStart(event.xbutton.x, event.xbutton.y);
-					}
 				}
 				}
 
 
 				break;
 				break;
@@ -644,12 +719,9 @@ namespace bs
 				// Handle window dragging for windows without a title bar
 				// Handle window dragging for windows without a title bar
 				if(button == Button1)
 				if(button == Button1)
 				{
 				{
-					auto iterFind = mData->windowMap.find(event.xbutton.window);
-					if (iterFind != mData->windowMap.end())
-					{
-						LinuxWindow* window = iterFind->second;
+					LinuxWindow* window = getLinuxWindow(mData, event.xbutton.window);
+					if(window != nullptr)
 						window->_dragEnd();
 						window->_dragEnd();
-					}
 				}
 				}
 
 
 				break;
 				break;
@@ -675,54 +747,75 @@ namespace bs
 				onCursorMoved(pos, btnStates);
 				onCursorMoved(pos, btnStates);
 
 
 				// Handle window dragging for windows without a title bar
 				// Handle window dragging for windows without a title bar
-				auto iterFind = mData->windowMap.find(event.xmotion.window);
-				if (iterFind != mData->windowMap.end())
-				{
-					LinuxWindow* window = iterFind->second;
+				LinuxWindow* window = getLinuxWindow(mData, event.xmotion.window);
+				if(window != nullptr)
 					window->_dragUpdate(event.xmotion.x, event.xmotion.y);
 					window->_dragUpdate(event.xmotion.x, event.xmotion.y);
-				}
 			}
 			}
 				break;
 				break;
 			case EnterNotify:
 			case EnterNotify:
-				if(event.xcrossing.mode == NotifyNormal)
-				{
-					// TODOPORT - Send mouse enter event
-				}
+				// Do nothing
 				break;
 				break;
 			case LeaveNotify:
 			case LeaveNotify:
-				if(event.xcrossing.mode == NotifyNormal)
+			{
+				if (event.xcrossing.mode == NotifyNormal)
 				{
 				{
 					Vector2I pos;
 					Vector2I pos;
 					pos.x = event.xcrossing.x_root;
 					pos.x = event.xcrossing.x_root;
 					pos.y = event.xcrossing.y_root;
 					pos.y = event.xcrossing.y_root;
 
 
-					if(clipCursor(mData, pos))
+					if (clipCursor(mData, pos))
 						_setCursorPosition(mData, pos);
 						_setCursorPosition(mData, pos);
-
-					// TODOPORT - Send mouse leave event
 				}
 				}
+
+				ct::RenderWindow* renderWindow = getRenderWindow(mData, event.xcrossing.window);
+				if(renderWindow != nullptr)
+					renderWindow->_notifyMouseLeft();
+			}
 				break;
 				break;
 			case ConfigureNotify:
 			case ConfigureNotify:
 			{
 			{
-				const XConfigureEvent &xce = event.xconfigure;
-
-				auto iterFind = mData->windowMap.find(event.xdestroywindow.window);
-				if (iterFind == mData->windowMap.end())
-					break;
-
-				LinuxWindow* window = iterFind->second;
-				updateClipBounds(mData, window);
+				LinuxWindow* window = getLinuxWindow(mData, event.xconfigure.window);
+				if(window != nullptr)
+				{
+					updateClipBounds(mData, window);
 
 
-				// TODOPORT - Send move/resize event
+					ct::RenderWindow* renderWindow = (ct::RenderWindow*)window->_getUserData();
+					if(renderWindow != nullptr)
+						renderWindow->_windowMovedOrResized();
+				}
 			}
 			}
 				break;
 				break;
 			case FocusIn:
 			case FocusIn:
+			{
 				// Update input context focus
 				// Update input context focus
 				XSetICFocus(mData->IC);
 				XSetICFocus(mData->IC);
+
+				// Send event to render window
+				ct::RenderWindow* renderWindow = getRenderWindow(mData, event.xfocus.window);
+
+				// Not a render window, so it doesn't care about these events
+				if (renderWindow != nullptr)
+				{
+					if (!renderWindow->getProperties().hasFocus)
+						renderWindow->_windowFocusReceived();
+				}
+			}
 				break;
 				break;
 			case FocusOut:
 			case FocusOut:
+			{
 				// Update input context focus
 				// Update input context focus
 				XUnsetICFocus(mData->IC);
 				XUnsetICFocus(mData->IC);
+
+				// Send event to render window
+				ct::RenderWindow* renderWindow = getRenderWindow(mData, event.xfocus.window);
+
+				// Not a render window, so it doesn't care about these events
+				if (renderWindow != nullptr)
+				{
+					if (renderWindow->getProperties().hasFocus)
+						renderWindow->_windowFocusLost();
+				}
+			}
 				break;
 				break;
 			case SelectionNotify:
 			case SelectionNotify:
 				LinuxDragAndDrop::handleSelectionNotify(event.xselection);
 				LinuxDragAndDrop::handleSelectionNotify(event.xselection);
@@ -774,6 +867,57 @@ namespace bs
 				XFlush (mData->xDisplay);
 				XFlush (mData->xDisplay);
 			}
 			}
 				break;
 				break;
+			case PropertyNotify:
+				// Report minimize, maximize and restore events
+				if(event.xproperty.atom == mData->atomWmState)
+				{
+					Atom type;
+					INT32 format;
+					unsigned long count, bytesRemaining;
+					UINT8* data = nullptr;
+
+					INT32 result = XGetWindowProperty(mData->xDisplay, event.xproperty.window, mData->atomWmState,
+							0, 1024, False, AnyPropertyType, &type, &format,
+							&count, &bytesRemaining, &data);
+
+					if (result == Success)
+					{
+						ct::RenderWindow* renderWindow = getRenderWindow(mData, event.xproperty.window);
+
+						// Not a render window, so it doesn't care about these events
+						if(renderWindow == nullptr)
+							continue;
+
+						Atom* atoms = (Atom*)data;
+
+						bool foundHorz = false;
+						bool foundVert = false;
+						for (unsigned long i = 0; i < count; i++)
+						{
+							if (atoms[i] == mData->atomWmStateMaxHorz) foundHorz = true;
+							if (atoms[i] == mData->atomWmStateMaxVert) foundVert = true;
+
+							if (foundVert && foundHorz)
+							{
+								if(event.xproperty.state == PropertyNewValue)
+									renderWindow->_notifyMaximized();
+								else
+									renderWindow->_notifyRestored();
+							}
+
+							if(atoms[i] == mData->atomWmStateHidden)
+							{
+								if(event.xproperty.state == PropertyNewValue)
+									renderWindow->_notifyMinimized();
+								else
+									renderWindow->_notifyRestored();
+							}
+						}
+
+						XFree(atoms);
+					}
+				}
+				break;
 			default:
 			default:
 				break;
 				break;
 			}
 			}
@@ -796,6 +940,10 @@ namespace bs
 		}
 		}
 
 
 		mData->atomDeleteWindow = XInternAtom(mData->xDisplay, "WM_DELETE_WINDOW", False);
 		mData->atomDeleteWindow = XInternAtom(mData->xDisplay, "WM_DELETE_WINDOW", False);
+		mData->atomWmState = XInternAtom(mData->xDisplay, "_NET_WM_STATE", False);
+		mData->atomWmStateHidden = XInternAtom(mData->xDisplay, "_NET_WM_STATE_HIDDEN", False);
+		mData->atomWmStateMaxHorz = XInternAtom(mData->xDisplay, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
+		mData->atomWmStateMaxVert = XInternAtom(mData->xDisplay, "_NET_WM_STATE_MAXIMIZED_VERT", False);
 
 
 		// Drag and drop
 		// Drag and drop
 		LinuxDragAndDrop::startUp(mData->xDisplay);
 		LinuxDragAndDrop::startUp(mData->xDisplay);

+ 1 - 7
Source/BansheeCore/Linux/BsLinuxPlatform.h

@@ -2,9 +2,9 @@
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 #pragma once
 #pragma once
 
 
+#include "Platform/BsPlatform.h"
 #include <X11/X.h>
 #include <X11/X.h>
 #include <X11/Xlib.h>
 #include <X11/Xlib.h>
-#include "Platform/BsPlatform.h"
 
 
 namespace bs
 namespace bs
 {
 {
@@ -44,9 +44,3 @@ namespace bs
 
 
 	/** @} */
 	/** @} */
 }
 }
-
-// Undefine conflicting defines from X.h
-#undef None
-#undef Success
-#undef Convex
-#undef Bool

+ 31 - 36
Source/BansheeCore/Linux/BsLinuxWindow.cpp

@@ -4,10 +4,7 @@
 #include "BsLinuxPlatform.h"
 #include "BsLinuxPlatform.h"
 #include "BsLinuxDragAndDrop.h"
 #include "BsLinuxDragAndDrop.h"
 
 
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
 #include <X11/Xatom.h>
 #include <X11/Xatom.h>
-#include <X11/extensions/Xrandr.h>
 
 
 #define _NET_WM_STATE_REMOVE 0
 #define _NET_WM_STATE_REMOVE 0
 #define _NET_WM_STATE_ADD 1
 #define _NET_WM_STATE_ADD 1
@@ -38,6 +35,8 @@ namespace bs
 
 
 		Rect2I dragZone;
 		Rect2I dragZone;
 		INT32 dragStartX, dragStartY;
 		INT32 dragStartX, dragStartY;
+
+		void* userData = nullptr;
 	};
 	};
 
 
 	LinuxWindow::LinuxWindow(const WINDOW_DESC &desc)
 	LinuxWindow::LinuxWindow(const WINDOW_DESC &desc)
@@ -108,7 +107,7 @@ namespace bs
 				ButtonPressMask | ButtonReleaseMask |
 				ButtonPressMask | ButtonReleaseMask |
 				EnterWindowMask | LeaveWindowMask |
 				EnterWindowMask | LeaveWindowMask |
 				PointerMotionMask | ButtonMotionMask |
 				PointerMotionMask | ButtonMotionMask |
-				StructureNotifyMask
+				StructureNotifyMask | PropertyChangeMask
 		);
 		);
 		XMapWindow(display, m->xWindow);
 		XMapWindow(display, m->xWindow);
 
 
@@ -295,7 +294,7 @@ namespace bs
 		m->dragZone = rect;
 		m->dragZone = rect;
 	}
 	}
 
 
-	bool LinuxWindow::_dragStart(int32_t x, int32_t y)
+	bool LinuxWindow::_dragStart(INT32 x, INT32 y)
 	{
 	{
 		if(m->hasTitleBar)
 		if(m->hasTitleBar)
 			return false;
 			return false;
@@ -303,8 +302,8 @@ namespace bs
 		if(m->dragZone.width == 0 || m->dragZone.height == 0)
 		if(m->dragZone.width == 0 || m->dragZone.height == 0)
 			return false;
 			return false;
 
 
-		if(x >= m->dragZone.x && x < (m->dragZone.x + m->dragZone.width) &&
-		   y >= m->dragZone.y && y < (m->dragZone.y + m->dragZone.height))
+		if(x >= m->dragZone.x && x < (INT32)(m->dragZone.x + m->dragZone.width) &&
+		   y >= m->dragZone.y && y < (INT32)(m->dragZone.y + m->dragZone.height))
 		{
 		{
 			m->dragStartX = x;
 			m->dragStartX = x;
 			m->dragStartY = y;
 			m->dragStartY = y;
@@ -316,13 +315,13 @@ namespace bs
 		return false;
 		return false;
 	}
 	}
 
 
-	void LinuxWindow::_dragUpdate(int32_t x, int32_t y)
+	void LinuxWindow::_dragUpdate(INT32 x, INT32 y)
 	{
 	{
 		if(!m->dragInProgress)
 		if(!m->dragInProgress)
 			return;
 			return;
 
 
-		int32_t offsetX = x - m->dragStartX;
-		int32_t offsetY = y - m->dragStartY;
+		INT32 offsetX = x - m->dragStartX;
+		INT32 offsetY = y - m->dragStartY;
 
 
 		move(getLeft() + offsetX, getTop() + offsetY);
 		move(getLeft() + offsetX, getTop() + offsetY);
 	}
 	}
@@ -337,16 +336,26 @@ namespace bs
 		return m->xWindow;
 		return m->xWindow;
 	}
 	}
 
 
+	void LinuxWindow::_setUserData(void* data)
+	{
+		m->userData = data;
+	}
+
+	void* LinuxWindow::_getUserData() const
+	{
+		return m->userData;
+	}
+
 	bool LinuxWindow::isMaximized() const
 	bool LinuxWindow::isMaximized() const
 	{
 	{
 		Atom wmState = XInternAtom(LinuxPlatform::getXDisplay(), "_NET_WM_STATE", False);
 		Atom wmState = XInternAtom(LinuxPlatform::getXDisplay(), "_NET_WM_STATE", False);
 		Atom type;
 		Atom type;
-		int32_t format;
+		INT32 format;
 		uint64_t length;
 		uint64_t length;
 		uint64_t remaining;
 		uint64_t remaining;
 		uint8_t* data = nullptr;
 		uint8_t* data = nullptr;
 
 
-		int32_t result = XGetWindowProperty(LinuxPlatform::getXDisplay(), m->xWindow, wmState,
+		INT32 result = XGetWindowProperty(LinuxPlatform::getXDisplay(), m->xWindow, wmState,
 				0, 1024, False, XA_ATOM, &type, &format,
 				0, 1024, False, XA_ATOM, &type, &format,
 				&length, &remaining, &data);
 				&length, &remaining, &data);
 
 
@@ -358,7 +367,7 @@ namespace bs
 
 
 			bool foundHorz = false;
 			bool foundHorz = false;
 			bool foundVert = false;
 			bool foundVert = false;
-			for (uint64_t i = 0; i < length; i++)
+			for (UINT32 i = 0; i < length; i++)
 			{
 			{
 				if (atoms[i] == wmMaxHorz)
 				if (atoms[i] == wmMaxHorz)
 					foundHorz = true;
 					foundHorz = true;
@@ -379,12 +388,12 @@ namespace bs
 	{
 	{
 		Atom wmState = XInternAtom(LinuxPlatform::getXDisplay(), "WM_STATE", True);
 		Atom wmState = XInternAtom(LinuxPlatform::getXDisplay(), "WM_STATE", True);
 		Atom type;
 		Atom type;
-		int32_t format;
+		INT32 format;
 		uint64_t length;
 		uint64_t length;
 		uint64_t remaining;
 		uint64_t remaining;
 		uint8_t* data = nullptr;
 		uint8_t* data = nullptr;
 
 
-		int32_t result = XGetWindowProperty(LinuxPlatform::getXDisplay(), m->xWindow, wmState,
+		INT32 result = XGetWindowProperty(LinuxPlatform::getXDisplay(), m->xWindow, wmState,
 				0, 1024, False, AnyPropertyType, &type, &format,
 				0, 1024, False, AnyPropertyType, &type, &format,
 				&length, &remaining, &data);
 				&length, &remaining, &data);
 
 
@@ -442,7 +451,7 @@ namespace bs
 			Atom wmBypassCompositor = XInternAtom(LinuxPlatform::getXDisplay(), "_NET_WM_BYPASS_COMPOSITOR", False);
 			Atom wmBypassCompositor = XInternAtom(LinuxPlatform::getXDisplay(), "_NET_WM_BYPASS_COMPOSITOR", False);
 			if (wmBypassCompositor)
 			if (wmBypassCompositor)
 			{
 			{
-				static constexpr uint32_t enabled = 1;
+				static constexpr UINT32 enabled = 1;
 
 
 				XChangeProperty(LinuxPlatform::getXDisplay(), m->xWindow, wmBypassCompositor,
 				XChangeProperty(LinuxPlatform::getXDisplay(), m->xWindow, wmBypassCompositor,
 						XA_CARDINAL, 32, PropModeReplace, (unsigned char*) &enabled, 1);
 						XA_CARDINAL, 32, PropModeReplace, (unsigned char*) &enabled, 1);
@@ -469,29 +478,15 @@ namespace bs
 
 
 	void LinuxWindow::setShowDecorations(bool show)
 	void LinuxWindow::setShowDecorations(bool show)
 	{
 	{
-		static constexpr uint32_t MWM_HINTS_FUNCTIONS		= (1 << 0);
-		static constexpr uint32_t MWM_HINTS_DECORATIONS		= (1 << 1);
-
-		static constexpr uint32_t MWM_DECOR_BORDER			= (1 << 1);
-		static constexpr uint32_t MWM_DECOR_RESIZEH			= (1 << 2);
-		static constexpr uint32_t MWM_DECOR_TITLE			= (1 << 3);
-		static constexpr uint32_t MWM_DECOR_MENU			= (1 << 4);
-		static constexpr uint32_t MWM_DECOR_MINIMIZE		= (1 << 5);
-		static constexpr uint32_t MWM_DECOR_MAXIMIZE		= (1 << 6);
-
-		static constexpr uint32_t MWM_FUNC_RESIZE			= (1 << 1);
-		static constexpr uint32_t MWM_FUNC_MOVE				= (1 << 2);
-		static constexpr uint32_t MWM_FUNC_MINIMIZE			= (1 << 3);
-		static constexpr uint32_t MWM_FUNC_MAXIMIZE			= (1 << 4);
-		static constexpr uint32_t MWM_FUNC_CLOSE			= (1 << 5);
+		static constexpr UINT32 MWM_HINTS_DECORATIONS		= (1 << 1);
 
 
 		struct MotifHints
 		struct MotifHints
 		{
 		{
-			uint32_t       flags;
-			uint32_t       functions;
-			uint32_t       decorations;
-			int32_t        inputMode;
-			uint32_t       status;
+			UINT32       flags;
+			UINT32       functions;
+			UINT32       decorations;
+			INT32        inputMode;
+			UINT32       status;
 		};
 		};
 
 
 		if(show)
 		if(show)

+ 6 - 1
Source/BansheeCore/Linux/BsLinuxWindow.h

@@ -126,6 +126,12 @@ namespace bs
 		/** Toggles between fullscreen and windowed mode. */
 		/** Toggles between fullscreen and windowed mode. */
 		void _setFullscreen(bool fullscreen);
 		void _setFullscreen(bool fullscreen);
 
 
+		/** Attaches non-specific user data that can later be retrieved through _getUserData(). */
+		void _setUserData(void* data);
+
+		/** Returns user data attached to the object when _setUserData was called. */
+		void* _getUserData() const;
+
 		/** @} */
 		/** @} */
 
 
 	private:
 	private:
@@ -166,4 +172,3 @@ namespace bs
 	/** @} */
 	/** @} */
 	/** @} */
 	/** @} */
 }
 }
-

+ 10 - 12
Source/BansheeCore/Managers/BsRenderWindowManager.cpp

@@ -9,9 +9,7 @@ namespace bs
 {
 {
 	RenderWindowManager::RenderWindowManager()
 	RenderWindowManager::RenderWindowManager()
 		:mWindowInFocus(nullptr), mNewWindowInFocus(nullptr)
 		:mWindowInFocus(nullptr), mNewWindowInFocus(nullptr)
-	{
-		Platform::onMouseLeftWindow.connect(std::bind(&RenderWindowManager::windowMouseLeft, this, _1));
-	}
+	{ }
 
 
 	RenderWindowManager::~RenderWindowManager()
 	RenderWindowManager::~RenderWindowManager()
 	{
 	{
@@ -78,7 +76,7 @@ namespace bs
 		if (window == nullptr)
 		if (window == nullptr)
 			return;
 			return;
 
 
-		auto iterFind = std::find_if(begin(mMovedOrResizedWindows), end(mMovedOrResizedWindows), 
+		auto iterFind = std::find_if(begin(mMovedOrResizedWindows), end(mMovedOrResizedWindows),
 			[&](const MoveOrResizeData& x) { return x.window == window; });
 			[&](const MoveOrResizeData& x) { return x.window == window; });
 
 
 		const RenderWindowProperties& props = coreWindow->getProperties();
 		const RenderWindowProperties& props = coreWindow->getProperties();
@@ -96,32 +94,32 @@ namespace bs
 			mMovedOrResizedWindows.push_back(newEntry);
 			mMovedOrResizedWindows.push_back(newEntry);
 			moveResizeData = &mMovedOrResizedWindows.back();
 			moveResizeData = &mMovedOrResizedWindows.back();
 		}
 		}
-		
+
 		moveResizeData->x = props.left;
 		moveResizeData->x = props.left;
 		moveResizeData->y = props.top;
 		moveResizeData->y = props.top;
 		moveResizeData->width = props.width;
 		moveResizeData->width = props.width;
 		moveResizeData->height = props.height;
 		moveResizeData->height = props.height;
 	}
 	}
 
 
-	void RenderWindowManager::notifySyncDataDirty(ct::RenderWindow* coreWindow)
+	void RenderWindowManager::notifyMouseLeft(ct::RenderWindow* coreWindow)
 	{
 	{
 		Lock lock(mWindowMutex);
 		Lock lock(mWindowMutex);
 
 
 		RenderWindow* window = getNonCore(coreWindow);
 		RenderWindow* window = getNonCore(coreWindow);
+		auto iterFind = std::find(begin(mMouseLeftWindows), end(mMouseLeftWindows), window);
 
 
-		if (window != nullptr)
-			mDirtyProperties.insert(window);
+		if (iterFind == end(mMouseLeftWindows))
+			mMouseLeftWindows.push_back(window);
 	}
 	}
 
 
-	void RenderWindowManager::windowMouseLeft(ct::RenderWindow* coreWindow)
+	void RenderWindowManager::notifySyncDataDirty(ct::RenderWindow* coreWindow)
 	{
 	{
 		Lock lock(mWindowMutex);
 		Lock lock(mWindowMutex);
 
 
 		RenderWindow* window = getNonCore(coreWindow);
 		RenderWindow* window = getNonCore(coreWindow);
-		auto iterFind = std::find(begin(mMouseLeftWindows), end(mMouseLeftWindows), window);
 
 
-		if (iterFind == end(mMouseLeftWindows))
-			mMouseLeftWindows.push_back(window);
+		if (window != nullptr)
+			mDirtyProperties.insert(window);
 	}
 	}
 
 
 	void RenderWindowManager::_update()
 	void RenderWindowManager::_update()

+ 3 - 3
Source/BansheeCore/Managers/BsRenderWindowManager.h

@@ -49,6 +49,9 @@ namespace bs
 		/**	Called by the core thread when window is moved or resized. */
 		/**	Called by the core thread when window is moved or resized. */
 		void notifyMovedOrResized(ct::RenderWindow* window);
 		void notifyMovedOrResized(ct::RenderWindow* window);
 
 
+		/**	Called by the core thread when mouse leaves a window. */
+		void notifyMouseLeft(ct::RenderWindow* window);
+
 		/**	Called by the sim thread when window properties change. */
 		/**	Called by the sim thread when window properties change. */
 		void notifySyncDataDirty(ct::RenderWindow* coreWindow);
 		void notifySyncDataDirty(ct::RenderWindow* coreWindow);
 
 
@@ -66,9 +69,6 @@ namespace bs
 	protected:
 	protected:
 		friend class RenderWindow;
 		friend class RenderWindow;
 
 
-		/**	Called by the core thread when mouse leaves a window. */
-		void windowMouseLeft(ct::RenderWindow* window);
-
 		/**	Finds a sim thread equivalent of the provided core thread window implementation. */
 		/**	Finds a sim thread equivalent of the provided core thread window implementation. */
 		RenderWindow* getNonCore(const ct::RenderWindow* window) const;
 		RenderWindow* getNonCore(const ct::RenderWindow* window) const;
 
 

+ 0 - 7
Source/BansheeCore/Platform/BsPlatform.h

@@ -401,13 +401,6 @@ namespace bs
 		 */
 		 */
 		static void _shutDown();
 		static void _shutDown();
 
 
-		/**
-		 * Triggered when a pointer leaves the provided window.
-		 *
-		 * @note	Sim thread only.
-		 */
-		static Event<void(ct::RenderWindow*)> onMouseLeftWindow;
-
 		/**
 		/**
 		 * Triggered whenever the pointer moves.
 		 * Triggered whenever the pointer moves.
 		 *
 		 *

+ 7 - 0
Source/BansheeCore/RenderAPI/BsRenderWindow.cpp

@@ -359,6 +359,13 @@ namespace bs
 		bs::RenderWindowManager::instance().notifySyncDataDirty(this);
 		bs::RenderWindowManager::instance().notifySyncDataDirty(this);
 	}
 	}
 
 
+	void RenderWindow::_notifyMouseLeft()
+	{
+		THROW_IF_NOT_CORE_THREAD;
+
+		bs::RenderWindowManager::instance().notifyMouseLeft(this);
+	}
+
 	const RenderWindowProperties& RenderWindow::getProperties() const
 	const RenderWindowProperties& RenderWindow::getProperties() const
 	{
 	{
 		return static_cast<const RenderWindowProperties&>(getPropertiesInternal());
 		return static_cast<const RenderWindowProperties&>(getPropertiesInternal());

+ 7 - 0
Source/BansheeCore/RenderAPI/BsRenderWindow.h

@@ -310,6 +310,13 @@ namespace bs
 		 */
 		 */
 		virtual void _notifyRestored();
 		virtual void _notifyRestored();
 
 
+		/**
+		 * Called when the mouse leaves the window.
+		 *
+		 * @note	Core thread.
+		 */
+		virtual void _notifyMouseLeft();
+
 	protected:
 	protected:
 		friend class bs::RenderWindow;
 		friend class bs::RenderWindow;
 		friend class RenderWindowManager;
 		friend class RenderWindowManager;

+ 4 - 0
Source/BansheeCore/Utility/BsCommonTypes.h

@@ -4,6 +4,10 @@
 
 
 namespace bs 
 namespace bs 
 {
 {
+	// Undefine defines from other libs, that conflict with enums below
+#undef None
+#undef Convex
+
 	/** @addtogroup Utility-Core
 	/** @addtogroup Utility-Core
 	 *  @{
 	 *  @{
 	 */
 	 */

+ 1 - 8
Source/BansheeCore/Win32/BsWin32Platform.cpp

@@ -22,7 +22,6 @@ namespace bs
 	Event<void(float)> Platform::onMouseWheelScrolled;
 	Event<void(float)> Platform::onMouseWheelScrolled;
 	Event<void(UINT32)> Platform::onCharInput;
 	Event<void(UINT32)> Platform::onCharInput;
 
 
-	Event<void(ct::RenderWindow*)> Platform::onMouseLeftWindow;
 	Event<void()> Platform::onMouseCaptureChanged;
 	Event<void()> Platform::onMouseCaptureChanged;
 
 
 	Platform::Pimpl* Platform::mData = bs_new<Platform::Pimpl>();
 	Platform::Pimpl* Platform::mData = bs_new<Platform::Pimpl>();
@@ -517,8 +516,6 @@ namespace bs
 	 *
 	 *
 	 * @param[in]	virtualKeyCode	Virtual key code to try to translate to a command.
 	 * @param[in]	virtualKeyCode	Virtual key code to try to translate to a command.
 	 * @param[out]	command			Input command. Only valid if function returns true.
 	 * @param[out]	command			Input command. Only valid if function returns true.
-	 * @param[in]	ignoreMovement	If true, then movement keys (up/down/left/right) will be ignored and not considered
-	 *								as input commands (useful if you need to parse num keys as numbers and not movement).
 	 */
 	 */
 	bool getCommand(unsigned int virtualKeyCode, InputCommandType& command)
 	bool getCommand(unsigned int virtualKeyCode, InputCommandType& command)
 	{
 	{
@@ -553,8 +550,6 @@ namespace bs
 		return false;
 		return false;
 	}
 	}
 
 
-	
-
 	LRESULT CALLBACK Win32Platform::_win32WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 	LRESULT CALLBACK Win32Platform::_win32WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 	{
 	{
 		if (uMsg == WM_CREATE)
 		if (uMsg == WM_CREATE)
@@ -732,9 +727,7 @@ namespace bs
 				mData->mIsTrackingMouse = false; // TrackMouseEvent ends when this message is received and needs to be re-applied
 				mData->mIsTrackingMouse = false; // TrackMouseEvent ends when this message is received and needs to be re-applied
 
 
 				Lock lock(mData->mSync);
 				Lock lock(mData->mSync);
-
-				if (!onMouseLeftWindow.empty())
-					onMouseLeftWindow(win);
+				win->_notifyMouseLeft();
 			}
 			}
 			return 0;
 			return 0;
 		case WM_LBUTTONUP:
 		case WM_LBUTTONUP:

+ 3 - 3
Source/BansheeGLRenderAPI/BsGLRenderAPI.cpp

@@ -460,7 +460,7 @@ namespace bs { namespace ct
 						if (glTex != nullptr)
 						if (glTex != nullptr)
 						{
 						{
 							SPtr<TextureView> texView = glTex->requestView(surface.mipLevel, surface.numMipLevels, 
 							SPtr<TextureView> texView = glTex->requestView(surface.mipLevel, surface.numMipLevels, 
-								surface.arraySlice, surface.numArraySlices, GVU_DEFAULT);
+								surface.face, surface.numFaces, GVU_DEFAULT);
 
 
 							GLTextureView* glTexView = static_cast<GLTextureView*>(texView.get());
 							GLTextureView* glTexView = static_cast<GLTextureView*>(texView.get());
 							GLenum newTextureType = glTexView->getGLTextureTarget();
 							GLenum newTextureType = glTexView->getGLTextureTarget();
@@ -609,8 +609,8 @@ namespace bs { namespace ct
 						if (texture != nullptr)
 						if (texture != nullptr)
 						{
 						{
 							GLTexture* tex = static_cast<GLTexture*>(texture.get());
 							GLTexture* tex = static_cast<GLTexture*>(texture.get());
-							glBindImageTexture(unit, tex->getGLID(), surface.mipLevel, surface.numArraySlices > 1,
-								surface.arraySlice, GL_READ_WRITE, tex->getGLFormat());
+							glBindImageTexture(unit, tex->getGLID(), surface.mipLevel, surface.numFaces > 1,
+								surface.face, GL_READ_WRITE, tex->getGLFormat());
 
 
 							SPtr<GLSLGpuProgram> activeProgram = getActiveProgram(type);
 							SPtr<GLSLGpuProgram> activeProgram = getActiveProgram(type);
 							if (activeProgram != nullptr)
 							if (activeProgram != nullptr)

+ 4 - 3
Source/BansheeGLRenderAPI/Linux/BsLinuxContext.cpp

@@ -10,10 +10,11 @@ namespace bs { namespace ct
 		int contextErrorHandler(::Display* display, XErrorEvent* error)
 		int contextErrorHandler(::Display* display, XErrorEvent* error)
 		{
 		{
 			// Do nothing
 			// Do nothing
+			return 0;
 		}
 		}
 
 
 		LinuxContext::LinuxContext(::Display* display, XVisualInfo& visualInfo)
 		LinuxContext::LinuxContext(::Display* display, XVisualInfo& visualInfo)
-		: mDisplay(display), mContext(None)
+		: mDisplay(display), mContext(0)
 	{
 	{
 		LinuxPlatform::lockX();
 		LinuxPlatform::lockX();
 
 
@@ -106,7 +107,7 @@ namespace bs { namespace ct
 	void LinuxContext::endCurrent()
 	void LinuxContext::endCurrent()
 	{
 	{
 		LinuxPlatform::lockX();
 		LinuxPlatform::lockX();
-		glXMakeCurrent(mDisplay, None, None);
+		glXMakeCurrent(mDisplay, 0, 0);
 		LinuxPlatform::unlockX();
 		LinuxPlatform::unlockX();
 	}
 	}
 
 
@@ -117,7 +118,7 @@ namespace bs { namespace ct
 			LinuxPlatform::lockX();
 			LinuxPlatform::lockX();
 
 
 			glXDestroyContext(mDisplay, mContext);
 			glXDestroyContext(mDisplay, mContext);
-			mContext = None;
+			mContext = 0;
 
 
 			LinuxPlatform::unlockX();
 			LinuxPlatform::unlockX();
 		}
 		}

+ 12 - 13
Source/BansheeGLRenderAPI/Linux/BsLinuxGLSupport.cpp

@@ -4,9 +4,8 @@
 #include "Linux/BsLinuxGLSupport.h"
 #include "Linux/BsLinuxGLSupport.h"
 #include "Linux/BsLinuxContext.h"
 #include "Linux/BsLinuxContext.h"
 #include "Linux/BsLinuxRenderWindow.h"
 #include "Linux/BsLinuxRenderWindow.h"
-#include "GL/wglew.h"
 #include "BsLinuxVideoModeInfo.h"
 #include "BsLinuxVideoModeInfo.h"
-#include "BsGLRenderAPI.h
+#include "BsGLRenderAPI.h"
 
 
 namespace bs { namespace ct
 namespace bs { namespace ct
 {
 {
@@ -121,8 +120,8 @@ namespace bs { namespace ct
 			const char* end = iter;
 			const char* end = iter;
 			const char* name = std::string(start, end).c_str();
 			const char* name = std::string(start, end).c_str();
 
 
-			uint32_t numExtensions = sizeof(gExtensionMap) / sizeof(gExtensionMap[0]);
-			for (int i = 0; i < numExtensions; ++i)
+			UINT32 numExtensions = sizeof(gExtensionMap) / sizeof(gExtensionMap[0]);
+			for (UINT32 i = 0; i < numExtensions; ++i)
 			{
 			{
 				if(strcmp(name, gExtensionMap[i].name) == 0)
 				if(strcmp(name, gExtensionMap[i].name) == 0)
 				{
 				{
@@ -153,10 +152,10 @@ namespace bs { namespace ct
 			return bs_shared_ptr_new<LinuxContext>(x11display, visualInfo);
 			return bs_shared_ptr_new<LinuxContext>(x11display, visualInfo);
 		else
 		else
 		{
 		{
-			SPtr<LinuxContext> context = rapi->getMainContext();
+			SPtr<GLContext> context = rapi->getMainContext();
 			context->setCurrent();
 			context->setCurrent();
 
 
-			return context;
+			return std::static_pointer_cast<LinuxContext>(context);
 		}
 		}
 	}
 	}
 
 
@@ -188,7 +187,7 @@ namespace bs { namespace ct
 		INT32 bestConfig = -1;
 		INT32 bestConfig = -1;
 		for (int i = 0; i < numConfigs; ++i)
 		for (int i = 0; i < numConfigs; ++i)
 		{
 		{
-			UINT32 configScore = 0;
+			INT32 configScore = 0;
 
 
 			// Depth buffer contributes the most to score
 			// Depth buffer contributes the most to score
 			if(depthStencil)
 			if(depthStencil)
@@ -197,7 +196,7 @@ namespace bs { namespace ct
 				glXGetFBConfigAttrib(display, configs[i], GLX_DEPTH_SIZE, &depth);
 				glXGetFBConfigAttrib(display, configs[i], GLX_DEPTH_SIZE, &depth);
 				glXGetFBConfigAttrib(display, configs[i], GLX_STENCIL_SIZE, &stencil);
 				glXGetFBConfigAttrib(display, configs[i], GLX_STENCIL_SIZE, &stencil);
 
 
-				UINT32 score = 0;
+				INT32 score = 0;
 				if(depth == 24 && stencil == 8)
 				if(depth == 24 && stencil == 8)
 					score = 10000;
 					score = 10000;
 				else if(depth == 32 && stencil == 8)
 				else if(depth == 32 && stencil == 8)
@@ -217,7 +216,7 @@ namespace bs { namespace ct
 			// sRGB contributes second most
 			// sRGB contributes second most
 			if(srgb)
 			if(srgb)
 			{
 			{
-				int32_t hasSRGB = 0;
+				INT32 hasSRGB = 0;
 
 
 				if(extGLX_EXT_framebuffer_sRGB)
 				if(extGLX_EXT_framebuffer_sRGB)
 					glXGetFBConfigAttrib(display, configs[i], GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, &hasSRGB);
 					glXGetFBConfigAttrib(display, configs[i], GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, &hasSRGB);
@@ -234,14 +233,14 @@ namespace bs { namespace ct
 
 
 			if((multisample >= 1) && extGLX_ARB_multisample)
 			if((multisample >= 1) && extGLX_ARB_multisample)
 			{
 			{
-				int32_t hasMultisample, numSamples;
+				INT32 hasMultisample, numSamples;
 				glXGetFBConfigAttrib(display, configs[i], GLX_SAMPLE_BUFFERS, &hasMultisample);
 				glXGetFBConfigAttrib(display, configs[i], GLX_SAMPLE_BUFFERS, &hasMultisample);
 				glXGetFBConfigAttrib(display, configs[i], GLX_SAMPLES, &numSamples);
 				glXGetFBConfigAttrib(display, configs[i], GLX_SAMPLES, &numSamples);
 
 
-				if(hasMultisample && (numSamples <= multisample))
+				if(hasMultisample && (numSamples <= (INT32)multisample))
 				{
 				{
 					configScore += (32 - (multisample - numSamples)) * 10;
 					configScore += (32 - (multisample - numSamples)) * 10;
-					caps[i].numSamples = numSamples;
+					caps[i].numSamples = (UINT32)numSamples;
 				}
 				}
 			}
 			}
 
 
@@ -258,7 +257,7 @@ namespace bs { namespace ct
 		{
 		{
 			// Something went wrong
 			// Something went wrong
 			XFree(configs);
 			XFree(configs);
-			bs_stack_delete(caps, numConfigs);
+			bs_stack_delete(caps, (UINT32)numConfigs);
 
 
 			return output;
 			return output;
 		}
 		}

+ 12 - 15
Source/BansheeGLRenderAPI/Linux/BsLinuxRenderWindow.cpp

@@ -6,6 +6,7 @@
 #include "Linux/BsLinuxWindow.h"
 #include "Linux/BsLinuxWindow.h"
 #include "Linux/BsLinuxVideoModeInfo.h"
 #include "Linux/BsLinuxVideoModeInfo.h"
 #include "Linux/BsLinuxGLSupport.h"
 #include "Linux/BsLinuxGLSupport.h"
+#include "Linux/BsLinuxContext.h"
 #include "BsGLPixelFormat.h"
 #include "BsGLPixelFormat.h"
 #include "BsGLRenderWindowManager.h"
 #include "BsGLRenderWindowManager.h"
 
 
@@ -67,8 +68,6 @@ namespace bs
 
 
 	LinuxRenderWindow::~LinuxRenderWindow()
 	LinuxRenderWindow::~LinuxRenderWindow()
 	{
 	{
-		RenderWindowProperties& props = mProperties;
-
 		if (mWindow != nullptr)
 		if (mWindow != nullptr)
 		{
 		{
 			LinuxPlatform::lockX();
 			LinuxPlatform::lockX();
@@ -116,13 +115,14 @@ namespace bs
 		if (opt != mDesc.platformSpecific.end())
 		if (opt != mDesc.platformSpecific.end())
 			windowDesc.parent = (::Window)parseUINT64(opt->second);
 			windowDesc.parent = (::Window)parseUINT64(opt->second);
 
 
-		mIsChild = windowDesc.parent != nullptr;
+		mIsChild = windowDesc.parent != 0;
 		props.isFullScreen = mDesc.fullscreen && !mIsChild;
 		props.isFullScreen = mDesc.fullscreen && !mIsChild;
 
 
 		mShowOnSwap = mDesc.hideUntilSwap;
 		mShowOnSwap = mDesc.hideUntilSwap;
 		props.isHidden = mDesc.hideUntilSwap || mDesc.hidden;
 		props.isHidden = mDesc.hideUntilSwap || mDesc.hidden;
 
 
 		mWindow = bs_new<LinuxWindow>(windowDesc);
 		mWindow = bs_new<LinuxWindow>(windowDesc);
+		mWindow->_setUserData(this);
 
 
 		props.width = mWindow->getWidth();
 		props.width = mWindow->getWidth();
 		props.height = mWindow->getHeight();
 		props.height = mWindow->getHeight();
@@ -130,7 +130,7 @@ namespace bs
 		props.left = mWindow->getLeft();
 		props.left = mWindow->getLeft();
 
 
 		props.hwGamma = visualConfig.caps.srgb;
 		props.hwGamma = visualConfig.caps.srgb;
-		props.multisampleCount = visualConfig.caps.numSamples > 1;
+		props.multisampleCount = visualConfig.caps.numSamples;
 
 
 		XWindowAttributes windowAttributes;
 		XWindowAttributes windowAttributes;
 		XGetWindowAttributes(LinuxPlatform::getXDisplay(), mWindow->_getXWindow(), &windowAttributes);
 		XGetWindowAttributes(LinuxPlatform::getXDisplay(), mWindow->_getXWindow(), &windowAttributes);
@@ -172,9 +172,6 @@ namespace bs
 
 
 		RenderWindowProperties& props = mProperties;
 		RenderWindowProperties& props = mProperties;
 
 
-		UINT32 actualMonitorIdx = std::min(monitorIdx, numOutputs - 1);
-		const LinuxVideoOutputInfo& outputInfo = static_cast<const LinuxVideoOutputInfo&>(videoModeInfo.getOutputInfo (actualMonitorIdx));
-
 		LinuxPlatform::lockX();
 		LinuxPlatform::lockX();
 		::Display* display = LinuxPlatform::getXDisplay();
 		::Display* display = LinuxPlatform::getXDisplay();
 
 
@@ -189,7 +186,7 @@ namespace bs
 		int numSizes;
 		int numSizes;
 		XRRScreenSize* screenSizes = XRRConfigSizes(screenConfig, &numSizes);
 		XRRScreenSize* screenSizes = XRRConfigSizes(screenConfig, &numSizes);
 
 
-		if(width != screenSizes[currentSizeID].width || height != screenSizes[currentSizeID].height ||
+		if((INT32)width != screenSizes[currentSizeID].width || (INT32)height != screenSizes[currentSizeID].height ||
 			currentRate != (short)refreshRate)
 			currentRate != (short)refreshRate)
 			changeVideoMode = true;
 			changeVideoMode = true;
 
 
@@ -215,18 +212,18 @@ namespace bs
 				UINT32 curWidth, curHeight;
 				UINT32 curWidth, curHeight;
 				if(currentRotation == RR_Rotate_90 || currentRotation == RR_Rotate_270)
 				if(currentRotation == RR_Rotate_90 || currentRotation == RR_Rotate_270)
 				{
 				{
-					curWidth = screenSizes[i].height;
-					curHeight = screenSizes[i].width;
+					curWidth = (UINT32)screenSizes[i].height;
+					curHeight = (UINT32)screenSizes[i].width;
 				}
 				}
 				else
 				else
 				{
 				{
-					curWidth = screenSizes[i].width;
-					curHeight = screenSizes[i].height;
+					curWidth = (UINT32)screenSizes[i].width;
+					curHeight = (UINT32)screenSizes[i].height;
 				}
 				}
 
 
 				if(curWidth == width && curHeight == height)
 				if(curWidth == width && curHeight == height)
 				{
 				{
-					foundSizeID = i;
+					foundSizeID = (SizeID)i;
 					foundSize = true;
 					foundSize = true;
 					break;
 					break;
 				}
 				}
@@ -251,8 +248,8 @@ namespace bs
 					}
 					}
 					else
 					else
 					{
 					{
-						short diffNew = abs((short)refreshRate - rates[i]);
-						short diffOld = abs((short)refreshRate - bestRate);
+						short diffNew = (short)abs((short)refreshRate - rates[i]);
+						short diffOld = (short)abs((short)refreshRate - bestRate);
 
 
 						if(diffNew < diffOld)
 						if(diffNew < diffOld)
 							bestRate = rates[i];
 							bestRate = rates[i];

+ 1 - 1
Source/BansheeGLRenderAPI/Linux/BsLinuxVideoModeInfo.cpp

@@ -70,7 +70,7 @@ namespace bs { namespace ct
 		INT32 numOutputProps;
 		INT32 numOutputProps;
 		Atom* outputProps = XRRListOutputProperties(x11Display, screenRes->outputs[resIdx], &numOutputProps);
 		Atom* outputProps = XRRListOutputProperties(x11Display, screenRes->outputs[resIdx], &numOutputProps);
 
 
-		for(UINT32 k = 0; k < numOutputProps; k++)
+		for(INT32 k = 0; k < numOutputProps; k++)
 		{
 		{
 			if(outputProps[k] != EDID)
 			if(outputProps[k] != EDID)
 				continue;
 				continue;

+ 1 - 1
Source/BansheeUtility/Linux/BsUnixFileSystem.cpp

@@ -122,7 +122,7 @@ namespace bs
 
 
 		DataStream::AccessMode accessMode = DataStream::READ;
 		DataStream::AccessMode accessMode = DataStream::READ;
 		if (!readOnly)
 		if (!readOnly)
-			accessMode = (accessMode | (UINT32)DataStream::WRITE);
+			accessMode = (DataStream::AccessMode)((UINT32)accessMode | (UINT32)DataStream::WRITE);
 
 
 		return bs_shared_ptr_new<FileDataStream>(path, accessMode, true);
 		return bs_shared_ptr_new<FileDataStream>(path, accessMode, true);
 	}
 	}