Переглянути джерело

Trying to get Unicode input. Fixed file API on Windows.

David Piuva 3 роки тому
батько
коміт
086162d713

+ 8 - 8
Source/DFPSR/api/fileAPI.cpp

@@ -21,6 +21,11 @@
 //    3. This notice may not be removed or altered from any source
 //    distribution.
 
+// Include fileAPI without falling back on local syntax implicitly.
+//   This prevents any local syntax from being implied in functions that are supposed to use variable pathSyntax.
+#define NO_IMPLICIT_PATH_SYNTAX
+#include "fileAPI.h"
+
 #ifdef USE_MICROSOFT_WINDOWS
 	#include <windows.h>
 #else
@@ -32,11 +37,6 @@
 #include <cstdlib>
 #include "bufferAPI.h"
 
-// Include fileAPI without falling back on local syntax implicitly.
-//   This prevents any local syntax from being implied in functions that are supposed to use variable pathSyntax.
-#define NO_IMPLICIT_PATH_SYNTAX
-#include "fileAPI.h"
-
 namespace dsr {
 
 constexpr const char32_t* getPathSeparator(PathSyntax pathSyntax) {
@@ -362,7 +362,7 @@ String file_getApplicationFolder(bool allowFallback) {
 	#ifdef USE_MICROSOFT_WINDOWS
 		NativeChar resultBuffer[maxLength + 1] = {0};
 		GetModuleFileNameW(nullptr, resultBuffer, maxLength);
-		return file_getParentFolder(fromNativeString(resultBuffer));
+		return file_getRelativeParentFolder(fromNativeString(resultBuffer), LOCAL_PATH_SYNTAX);
 	#else
 		NativeChar resultBuffer[maxLength + 1] = {0};
 		if (readlink("/proc/self/exe", resultBuffer, maxLength) != -1) {
@@ -525,7 +525,7 @@ EntryType file_getEntryType(const ReadableString &path) {
 bool file_getFolderContent(const ReadableString& folderPath, std::function<void(const ReadableString& entryPath, const ReadableString& entryName, EntryType entryType)> action) {
 	String optimizedPath = file_optimizePath(folderPath, LOCAL_PATH_SYNTAX);
 	#ifdef USE_MICROSOFT_WINDOWS
-		String pattern = file_combinePaths(optimizedPath, U"*.*");
+		String pattern = file_combinePaths(optimizedPath, U"*.*", LOCAL_PATH_SYNTAX);
 		Buffer buffer;
 		const NativeChar *nativePattern = toNativeString(pattern, buffer);
 		WIN32_FIND_DATAW findData;
@@ -536,7 +536,7 @@ bool file_getFolderContent(const ReadableString& folderPath, std::function<void(
 			while (true) {
 				String entryName = fromNativeString(findData.cFileName);
 				if (!string_match(entryName, U".") && !string_match(entryName, U"..")) {
-					String entryPath = file_combinePaths(optimizedPath, entryName);
+					String entryPath = file_combinePaths(optimizedPath, entryName, LOCAL_PATH_SYNTAX);
 					EntryType entryType = EntryType::UnhandledType;
 					if(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
 						entryType = EntryType::Folder;

+ 3 - 3
Source/DFPSR/gui/InputEvent.h

@@ -61,11 +61,11 @@ class KeyboardEvent : public InputEvent {
 public:
 	// What the user did to the key
 	KeyboardEventType keyboardEventType;
-	// Actual characters for non-latin characters
-	char character;
+	// The raw unicode value without any encoding
+	DsrChar character;
 	// Minimal set of keys for portability
 	DsrKey dsrKey;
-	KeyboardEvent(KeyboardEventType keyboardEventType, char character, DsrKey dsrKey)
+	KeyboardEvent(KeyboardEventType keyboardEventType, DsrChar character, DsrKey dsrKey)
 	 : keyboardEventType(keyboardEventType), character(character), dsrKey(dsrKey) {}
 };
 

+ 17 - 8
Source/windowManagers/Win32Window.cpp

@@ -412,7 +412,14 @@ static LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam,
 		break;
 	case WM_KEYDOWN: case WM_KEYUP:
 		{
-			char character = wParam; // System specific key-code
+			dsr::DsrChar character;
+			if (IsWindowUnicode(hwnd)) {
+				dsr::CharacterEncoding encoding = dsr::CharacterEncoding::BOM_UTF16LE;
+				dsr::String characterString = dsr::string_dangerous_decodeFromData((const void*)&wParam, encoding);
+				character = characterString[0]; // Convert from UTF-16 surrogate to UTF-32 Unicode character
+			} else {
+				character = wParam; // Raw ansi character
+			}
 			dsr::DsrKey dsrKey = getDsrKey(wParam); // Portable key-code
 			bool previouslyPressed = lParam & (1 << 30);
 			if (message == WM_KEYDOWN) {
@@ -422,7 +429,11 @@ static LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam,
 					parent->queueInputEvent(new dsr::KeyboardEvent(dsr::KeyboardEventType::KeyDown, character, dsrKey));
 				}
 				// Press typing with repeat
-				parent->queueInputEvent(new dsr::KeyboardEvent(dsr::KeyboardEventType::KeyType, character, dsrKey));
+				// Caps lock, shift, control and insert is not something you type characters with
+				// TODO: Add more characters to the exclusion list or find a function for this filter somewhere
+				if (character != 16 && character != 17 && character != 20 && character != 37 && character != 45) {
+					parent->queueInputEvent(new dsr::KeyboardEvent(dsr::KeyboardEventType::KeyType, character, dsrKey));
+				}
 			} else { // message == WM_KEYUP
 				// Physical key up
 				parent->queueInputEvent(new dsr::KeyboardEvent(dsr::KeyboardEventType::KeyUp, character, dsrKey));
@@ -449,7 +460,6 @@ static LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam,
 		// Resize the window as requested
 		result = DefWindowProc(hwnd, message, wParam, lParam);
 		break;
-	// TODO: Keyboard presses & typing
 	default:
 		result = DefWindowProc(hwnd, message, wParam, lParam);
 	}
@@ -458,11 +468,10 @@ static LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam,
 
 void Win32Window::prefetchEvents() {
 	MSG messages;
-	// Windows hangs unless we process application events for each window
-	while (PeekMessage(&messages, NULL, 0, 0, PM_REMOVE)) {
-		//dsr::printText("Received an event ", messages.message, "(", messages.wParam, ", ", (intptr_t)messages.lParam, ")\n");
-		TranslateMessage(&messages);
-		DispatchMessage(&messages); // Calling WindowProcedure for each window instance
+	if (IsWindowUnicode(this->hwnd)) {
+		while (PeekMessageW(&messages, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&messages); DispatchMessage(&messages); }
+	} else {
+		while (PeekMessage(&messages, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&messages); DispatchMessage(&messages); }
 	}
 }
 

+ 12 - 6
Source/windowManagers/X11Window.cpp

@@ -458,10 +458,16 @@ static dsr::DsrKey getDsrKey(KeySym keyCode) {
 	return result;
 }
 
-// TODO: Implement support for typing in UNICODE. How can this be tested when even Chinese keyboards use phonetic typing?
-static uint32_t getNativeCharacterCode(XEvent& event) {
-	KeySym key; char text[255]; uint32_t character = '\0';
-	if (XLookupString(&event.xkey, text, 255, &key, 0) == 1) { character = text[0]; }
+static dsr::DsrChar getCharacterCode(XEvent& event) {
+	const int buffersize = 8;
+	KeySym key; char codePoints[buffersize]; dsr::DsrChar character = '\0';
+	if (XLookupString(&event.xkey, codePoints, buffersize, &key, 0) == 1) {
+		// X11 does not specify any encoding, but BOM_UTF16LE seems to work on Linux.
+		// TODO: See if there is a list of X11 character encodings for different platforms.
+		dsr::CharacterEncoding encoding = dsr::CharacterEncoding::BOM_UTF16LE;
+		dsr::String characterString = string_dangerous_decodeFromData(codePoints, encoding);
+		character = characterString[0];
+	}
 	return character;
 }
 
@@ -490,7 +496,7 @@ void X11Window::prefetchEvents() {
 					this->queueInputEvent(new dsr::WindowEvent(dsr::WindowEventType::Redraw, this->windowWidth, this->windowHeight));
 				} else if (currentEvent.type == KeyPress || currentEvent.type == KeyRelease) {
 					// Key down/up
-					uint32_t character = getNativeCharacterCode(currentEvent);
+					dsr::DsrChar character = getCharacterCode(currentEvent);
 					KeySym nativeKey = XLookupKeysym(&currentEvent.xkey, 0);
 					dsr::DsrKey dsrKey = getDsrKey(nativeKey);
 					KeySym nextNativeKey = hasNextEvent ? XLookupKeysym(&nextEvent.xkey, 0) : 0;
@@ -636,7 +642,7 @@ std::shared_ptr<dsr::BackendWindow> createBackendWindow(const dsr::String& title
 		auto backend = std::make_shared<X11Window>(title, width, height);
 		return std::dynamic_pointer_cast<dsr::BackendWindow>(backend);
 	} else {
-		printf("No display detected. Aborting X11 window creation.\n");
+		dsr::printText("No display detected. Aborting X11 window creation.\n");
 		return std::shared_ptr<dsr::BackendWindow>();
 	}
 }