diff engine/core/video/cursor.cpp @ 255:51cc05d862f2

Merged editor_rewrite branch to trunk. This contains changes that may break compatibility against existing clients. For a list of changes that may affect your client, see: http://wiki.fifengine.de/Changes_to_pychan_and_FIFE_in_editor_rewrite_branch
author cheesesucker@33b003aa-7bff-0310-803a-e67f0ece8222
date Mon, 08 Jun 2009 16:00:02 +0000
parents 90005975cdbb
children f2195628947b
line wrap: on
line diff
--- a/engine/core/video/cursor.cpp	Wed Jun 03 19:29:52 2009 +0000
+++ b/engine/core/video/cursor.cpp	Mon Jun 08 16:00:02 2009 +0000
@@ -20,6 +20,14 @@
  ***************************************************************************/
 
 // Standard C++ library includes
+#if defined( WIN32 )
+#include <windows.h>
+#include <sdl.h>
+#endif
+
+#if defined( __linux__ )
+#include <X11/Xcursor/Xcursor.h>
+#endif
 
 // 3rd party library includes
 
@@ -29,6 +37,7 @@
 // Second block: files included from the same folder
 #include "util/structures/rect.h"
 #include "util/time/timemanager.h"
+#include "util/log/logger.h"
 
 #include "imagepool.h"
 #include "animationpool.h"
@@ -37,10 +46,36 @@
 #include "renderbackend.h"
 #include "cursor.h"
 
+#if defined( WIN32 )
+
+// From SDL_sysmouse.c
+struct WMcursor {
+	HCURSOR curs;
+#ifndef _WIN32_WCE
+	Uint8 *ands;
+	Uint8 *xors;
+#endif
+};
+
+#endif
+
+#if defined( __linux__ )
+
+// Stops the compiler from confusing it with FIFE:Cursor
+typedef Cursor XCursor;
+
+// From SDL_x11mouse.c
+struct WMcursor {
+	Cursor x_cursor;
+};
+
+#endif
+
 namespace FIFE {
-	
+	static Logger _log(LM_GUI); // We should have a log module for cursor
+
 	Cursor::Cursor(ImagePool* imgpool, AnimationPool* animpool, RenderBackend* renderbackend):
-		m_cursor_id(0),
+		m_cursor_id(NC_ARROW),
 		m_drag_id(0),
 		m_cursor_type(CURSOR_NATIVE),
 		m_drag_type(CURSOR_NONE),
@@ -51,8 +86,10 @@
 		m_drag_animtime(0),
 		m_drag_offset_x(0),
 		m_drag_offset_y(0),
+		m_native_cursor(NULL),
 		m_timemanager(TimeManager::instance()) {
 		assert(m_timemanager);
+		set(m_cursor_type, m_cursor_id);
 	}
 	
 	void Cursor::set(MouseCursorType ctype, unsigned int cursor_id) {
@@ -60,6 +97,7 @@
 		m_cursor_type = ctype;
 		if (ctype == CURSOR_NATIVE) {
 			SDL_ShowCursor(1);
+			setNativeCursor(cursor_id);
 		} else {
 			SDL_ShowCursor(0);
 			if (ctype == CURSOR_ANIMATION) {
@@ -120,4 +158,169 @@
 			m_renderbackend->popClipArea();
 		}
 	}
+
+	unsigned int Cursor::getNativeId(unsigned int cursor_id) {
+#if defined( WIN32 )
+		switch (cursor_id) {
+			case NC_ARROW:
+				return 32512; // IDC_ARROW;
+			case NC_IBEAM:
+				return 32513; // IDC_IBEAM;
+			case NC_WAIT:
+				return 32514; // IDC_WAIT;
+			case NC_CROSS:
+				return 32515; // IDC_CROSS;
+			case NC_UPARROW:
+				return 32516; // IDC_UPARROW;
+			case NC_RESIZESE:
+				return 32642; // IDC_SIZENWSE;
+			case NC_RESIZESW:
+				return 32643; // IDC_SIZENESW;
+			case NC_RESIZEE:
+				return 32644; // IDC_SIZEWE;
+			case NC_RESIZES:
+				return 32645; // IDC_SIZENS;
+			case NC_RESIZENW:
+				return 32642; // IDC_SIZENWSE;
+			case NC_RESIZENE:
+				return 32643; // IDC_SIZENESW;
+			case NC_RESIZEW:
+				return 32644; // IDC_SIZEWE;
+			case NC_RESIZEN:
+				return 32645; // IDC_SIZENS;
+			case NC_RESIZEALL:
+				return 32646; // IDC_SIZEALL;
+			case NC_NO:
+				return 32648; // IDC_NO;
+			case NC_HAND:
+				return 32649; // IDC_HAND;
+			case NC_APPSTARTING:
+				return 32650; // IDC_APPSTARTING;
+			case NC_HELP:
+				return 32651; // IDC_HELP;
+			default:
+				break;
+		}
+
+#elif defined( __linux__ )
+		switch (cursor_id) {
+			case NC_ARROW:
+				return 68;
+			case NC_IBEAM:
+				return 152;
+			case NC_WAIT:
+				return 150;
+			case NC_CROSS:
+				return 130;
+			case NC_UPARROW:
+				return 22;
+			case NC_RESIZESE:
+				return 14;
+			case NC_RESIZESW:
+				return 12;
+			case NC_RESIZEE:
+				return 96;
+			case NC_RESIZES:
+				return 16;
+			case NC_RESIZENW:
+				return 134;
+			case NC_RESIZENE:
+				return 136;
+			case NC_RESIZEW:
+				return 70;
+			case NC_RESIZEN:
+				return 138;
+			case NC_RESIZEALL:
+				return 52;
+			case NC_NO:
+				return 0;
+			case NC_HAND:
+				return 60;
+			case NC_APPSTARTING:
+				return 150;
+			case NC_HELP:
+				return 92;
+			default:
+				break;
+		}
+#endif
+		return cursor_id;
+	}
+
+	void Cursor::setNativeCursor(unsigned int cursor_id) {
+#if !defined( WIN32 ) && !defined(__linux__)
+		return;
+#endif
+
+		// Check if a value in NativeCursors is requested
+		cursor_id = getNativeId(cursor_id);
+
+		// Load cursor
+#if defined( __linux__ )
+		static Display* dsp = XOpenDisplay(NULL);
+		XCursor xCursor = XcursorShapeLoadCursor(dsp, cursor_id);
+		if (xCursor == 0) {
+			if (m_native_cursor != NULL) {
+				SDL_FreeCursor(m_native_cursor);
+				m_native_cursor = NULL;
+			}
+			FL_WARN(_log, "Cursor: No cursor matching cursor_id was found.");
+			return;
+		}
+#elif defined( WIN32 )
+		// Load native cursor
+		HCURSOR hIcon = LoadCursor(NULL, MAKEINTRESOURCE(cursor_id));
+		if (hIcon == static_cast<HCURSOR>(0)) {
+			if (m_native_cursor != NULL) {
+				SDL_FreeCursor(m_native_cursor);
+				m_native_cursor = NULL;
+			}
+			FL_WARN(_log, "Cursor: No cursor matching cursor_id was found.");
+			return;
+		}
+#endif
+
+		WMcursor *cursor;
+		SDL_Cursor *curs2;
+
+		// Allocate memory. Use SDL_FreeCursor to free cursor memory
+		cursor = (WMcursor *)SDL_malloc(sizeof(*cursor));
+		curs2 = (SDL_Cursor *)SDL_malloc(sizeof *curs2);
+
+		//-- Set up some default values --
+		curs2->wm_cursor = cursor;
+		curs2->data = NULL;
+		curs2->mask = NULL;
+		curs2->save[0] = NULL;
+		curs2->save[1] = NULL;
+		curs2->area.x = 0;
+		curs2->area.y = 0;
+		curs2->area.w = 32;
+		curs2->area.h = 32;
+		curs2->hot_x = 0;
+		curs2->hot_y = 0;
+
+#if defined(WIN32)
+		cursor->curs = hIcon;
+#ifndef _WIN32_WCE
+		cursor->ands = NULL;
+		cursor->xors = NULL;
+#endif
+
+		// Get hot spot
+		ICONINFO iconinfo;
+		if (GetIconInfo(hIcon, &iconinfo)) {
+			curs2->hot_x = static_cast<Sint16>(iconinfo.xHotspot);
+			curs2->hot_y = static_cast<Sint16>(iconinfo.yHotspot);
+		}
+
+#elif defined(__linux__)
+		cursor->x_cursor = xCursor;
+		XSync(dsp, false);
+#endif
+		
+		m_native_cursor = curs2;
+		SDL_SetCursor(curs2);
+
+	}
 }