Kaynağa Gözat

Add OsEventType::TEXT

Daniele Bartolini 8 yıl önce
ebeveyn
işleme
fe1fc6312a

+ 4 - 1
src/device/device.cpp

@@ -298,8 +298,11 @@ bool Device::process_events(bool vsync)
 			unpause();
 			break;
 
+		case OsEventType::TEXT:
+			break;
+
 		default:
-			CE_FATAL("Unknown OS event");
+			CE_FATAL("OsEventType: unknown");
 			break;
 		}
 	}

+ 19 - 0
src/device/device_event_queue.h

@@ -21,6 +21,7 @@ struct OsEventType
 		EXIT,
 		PAUSE,
 		RESUME,
+		TEXT,
 		NONE
 	};
 };
@@ -60,6 +61,13 @@ struct ResolutionEvent
 	u16 height;
 };
 
+struct TextEvent
+{
+	u16 type;
+	u8 len;
+	u8 utf8[4];
+};
+
 union OsEvent
 {
 	u16 type;
@@ -67,6 +75,7 @@ union OsEvent
 	AxisEvent axis;
 	StatusEvent status;
 	ResolutionEvent resolution;
+	TextEvent text;
 };
 
 /// Single Producer Single Consumer event queue.
@@ -139,6 +148,16 @@ struct DeviceEventQueue
 		push_event(ev);
 	}
 
+	void push_text_event(u8 len, u8 utf8[4])
+	{
+		OsEvent ev;
+		ev.text.type = OsEventType::TEXT;
+		ev.text.len = len;
+		memcpy(ev.text.utf8, utf8, sizeof(ev.text.utf8));
+
+		push_event(ev);
+	}
+
 	void push_none_event()
 	{
 		OsEvent ev;

+ 39 - 1
src/device/main_linux.cpp

@@ -348,6 +348,22 @@ struct LinuxDevice
 		Rotation rr_old_rot;
 		const SizeID rr_old_sizeid = XRRConfigCurrentConfiguration(_screen_config, &rr_old_rot);
 
+		XIM im;
+		im = XOpenIM(_x11_display, NULL, NULL, NULL);
+		CE_ASSERT(im != NULL, "XOpenIM: error");
+
+		XIC ic;
+		ic = XCreateIC(im
+			, XNInputStyle
+			, 0
+			| XIMPreeditNothing
+			| XIMStatusNothing
+			, XNClientWindow
+			, root_window
+			, NULL
+			);
+		CE_ASSERT(ic != NULL, "XCreateIC: error");
+
 		// Start main thread
 		MainThreadArgs mta;
 		mta.opts = opts;
@@ -438,8 +454,27 @@ struct LinuxDevice
 				case KeyRelease:
 					{
 						KeySym keysym = XLookupKeysym(&event.xkey, 0);
-						KeyboardButton::Enum kb = x11_translate_key(keysym);
 
+						if (event.type == KeyPress)
+						{
+							Status status = 0;
+							u8 utf8[4] = { 0 };
+							int len = Xutf8LookupString(ic
+								, &event.xkey
+								, (char*)utf8
+								, sizeof(utf8)
+								, &keysym
+								, &status
+								);
+
+							if (status == XLookupChars || status == XLookupBoth)
+							{
+								if (len)
+									_queue.push_text_event(len, utf8);
+							}
+						}
+
+						KeyboardButton::Enum kb = x11_translate_key(keysym);
 						if (kb != KeyboardButton::COUNT)
 						{
 							_queue.push_button_event(InputDeviceType::KEYBOARD
@@ -466,6 +501,9 @@ struct LinuxDevice
 
 		main_thread.stop();
 
+		XDestroyIC(ic);
+		XCloseIM(im);
+
 		// Restore previous screen configuration
 		Rotation rr_rot;
 		const SizeID rr_sizeid = XRRConfigCurrentConfiguration(_screen_config, &rr_rot);