[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [41129] trunk/blender: initial support for unicode keyboard input for ghost & blenders WM.

Campbell Barton ideasman42 at gmail.com
Thu Oct 20 07:30:28 CEST 2011


Revision: 41129
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=41129
Author:   campbellbarton
Date:     2011-10-20 05:30:26 +0000 (Thu, 20 Oct 2011)
Log Message:
-----------
initial support for unicode keyboard input for ghost & blenders WM.
- currently X11 only, depends on Xinput (but should not break other os's).
- ghost stores utf8 buffer, copies to wmEvent's
- UI text input is currently the only area that uses this - not console or text editor.
- no rna access yet.

Modified Paths:
--------------
    trunk/blender/intern/ghost/GHOST_Types.h
    trunk/blender/intern/ghost/intern/GHOST_EventKey.h
    trunk/blender/intern/ghost/intern/GHOST_SystemCarbon.cpp
    trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm
    trunk/blender/intern/ghost/intern/GHOST_SystemSDL.cpp
    trunk/blender/intern/ghost/intern/GHOST_SystemWin32.cpp
    trunk/blender/intern/ghost/intern/GHOST_SystemX11.cpp
    trunk/blender/intern/ghost/intern/GHOST_SystemX11.h
    trunk/blender/intern/ghost/intern/GHOST_WindowX11.cpp
    trunk/blender/intern/ghost/intern/GHOST_WindowX11.h
    trunk/blender/source/blender/editors/interface/interface_handlers.c
    trunk/blender/source/blender/windowmanager/WM_types.h
    trunk/blender/source/blender/windowmanager/intern/wm_event_system.c
    trunk/blender/source/gameengine/Ketsji/KX_PythonInit.cpp

Modified: trunk/blender/intern/ghost/GHOST_Types.h
===================================================================
--- trunk/blender/intern/ghost/GHOST_Types.h	2011-10-20 05:18:02 UTC (rev 41128)
+++ trunk/blender/intern/ghost/GHOST_Types.h	2011-10-20 05:30:26 UTC (rev 41129)
@@ -468,6 +468,7 @@
 	GHOST_TKey		key;
 	/** The ascii code for the key event ('\0' if none). */
 	char			ascii;
+	char			utf8_buf[6];
 } GHOST_TEventKeyData;
 
 typedef struct {

Modified: trunk/blender/intern/ghost/intern/GHOST_EventKey.h
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_EventKey.h	2011-10-20 05:18:02 UTC (rev 41128)
+++ trunk/blender/intern/ghost/intern/GHOST_EventKey.h	2011-10-20 05:30:26 UTC (rev 41129)
@@ -55,6 +55,7 @@
 	{
 		m_keyEventData.key = key;
 		m_keyEventData.ascii = '\0';
+		m_keyEventData.utf8_buf[0]= '\0';
 		m_data = &m_keyEventData;
 	}
 	
@@ -65,11 +66,13 @@
 	 * @param key	The key code of the key.
 	 * @param ascii The ascii code for the key event.
 	 */
-	GHOST_EventKey(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window, GHOST_TKey key, char ascii)
+	GHOST_EventKey(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window, GHOST_TKey key, char ascii, const char utf8_buf[6])
 		: GHOST_Event(msec, type, window)
 	{
 		m_keyEventData.key = key;
 		m_keyEventData.ascii = ascii;
+		if (utf8_buf) memcpy(m_keyEventData.utf8_buf, utf8_buf, sizeof(m_keyEventData.utf8_buf));
+		else                 m_keyEventData.utf8_buf[0]= '\0';
 		m_data = &m_keyEventData;
 	}
 		

Modified: trunk/blender/intern/ghost/intern/GHOST_SystemCarbon.cpp
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_SystemCarbon.cpp	2011-10-20 05:18:02 UTC (rev 41128)
+++ trunk/blender/intern/ghost/intern/GHOST_SystemCarbon.cpp	2011-10-20 05:30:26 UTC (rev 41129)
@@ -931,7 +931,7 @@
 				} else {
 					type = GHOST_kEventKeyUp;
 				}
-				pushEvent( new GHOST_EventKey( getMilliSeconds(), type, window, key, ascii) );
+				pushEvent( new GHOST_EventKey( getMilliSeconds(), type, window, key, ascii, NULL) );
 //			}
 			break;
 	

Modified: trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm	2011-10-20 05:18:02 UTC (rev 41128)
+++ trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm	2011-10-20 05:30:26 UTC (rev 41129)
@@ -1656,6 +1656,8 @@
 	}
 	
 	switch ([event type]) {
+		char utf8_buf[6]= {'\0'}; /* TODO, unicode input */
+
 		case NSKeyDown:
 		case NSKeyUp:
 			charsIgnoringModifiers = [event charactersIgnoringModifiers];
@@ -1684,10 +1686,10 @@
 				break; //Cmd-Q is directly handled by Cocoa
 
 			if ([event type] == NSKeyDown) {
-				pushEvent( new GHOST_EventKey([event timestamp]*1000, GHOST_kEventKeyDown, window, keyCode, ascii) );
+				pushEvent( new GHOST_EventKey([event timestamp]*1000, GHOST_kEventKeyDown, window, keyCode, ascii, utf8_buf) );
 				//printf("\nKey down rawCode=0x%x charsIgnoringModifiers=%c keyCode=%u ascii=%i %c",[event keyCode],[charsIgnoringModifiers length]>0?[charsIgnoringModifiers characterAtIndex:0]:' ',keyCode,ascii,ascii);
 			} else {
-				pushEvent( new GHOST_EventKey([event timestamp]*1000, GHOST_kEventKeyUp, window, keyCode, ascii) );
+				pushEvent( new GHOST_EventKey([event timestamp]*1000, GHOST_kEventKeyUp, window, keyCode, ascii, utf8_buf) );
 				//printf("\nKey up rawCode=0x%x charsIgnoringModifiers=%c keyCode=%u ascii=%i %c",[event keyCode],[charsIgnoringModifiers length]>0?[charsIgnoringModifiers characterAtIndex:0]:' ',keyCode,ascii,ascii);
 			}
 			break;

Modified: trunk/blender/intern/ghost/intern/GHOST_SystemSDL.cpp
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_SystemSDL.cpp	2011-10-20 05:18:02 UTC (rev 41128)
+++ trunk/blender/intern/ghost/intern/GHOST_SystemSDL.cpp	2011-10-20 05:30:26 UTC (rev 41129)
@@ -441,7 +441,7 @@
 				}
 			}
 
-			g_event= new GHOST_EventKey(getMilliSeconds(), type, window, gkey, sym);
+			g_event= new GHOST_EventKey(getMilliSeconds(), type, window, gkey, sym, NULL);
 		}
 		break;
 	}

Modified: trunk/blender/intern/ghost/intern/GHOST_SystemWin32.cpp
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_SystemWin32.cpp	2011-10-20 05:18:02 UTC (rev 41128)
+++ trunk/blender/intern/ghost/intern/GHOST_SystemWin32.cpp	2011-10-20 05:30:26 UTC (rev 41129)
@@ -725,7 +725,8 @@
 									(LPSTR) &ascii, 1,
 									NULL,NULL);
 
-		event = new GHOST_EventKey(system->getMilliSeconds(), keyDown ? GHOST_kEventKeyDown: GHOST_kEventKeyUp, window, key, ascii);
+		/* TODO, last arg is utf8, need to pass utf8 arg */
+		event = new GHOST_EventKey(system->getMilliSeconds(), keyDown ? GHOST_kEventKeyDown: GHOST_kEventKeyUp, window, key, ascii, NULL);
 		
 #ifdef GHOST_DEBUG
 		std::cout << ascii << std::endl;

Modified: trunk/blender/intern/ghost/intern/GHOST_SystemX11.cpp
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_SystemX11.cpp	2011-10-20 05:18:02 UTC (rev 41128)
+++ trunk/blender/intern/ghost/intern/GHOST_SystemX11.cpp	2011-10-20 05:30:26 UTC (rev 41129)
@@ -89,6 +89,11 @@
 		abort(); //was return before, but this would just mean it will crash later
 	}
 
+	/* Open a connection to the X input manager */
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+	m_xim = XOpenIM(m_display, NULL, (char *)GHOST_X11_RES_NAME, (char *)GHOST_X11_RES_CLASS);
+#endif
+
 	m_delete_window_atom 
 	  = XInternAtom(m_display, "WM_DELETE_WINDOW", True);
 
@@ -141,6 +146,10 @@
 GHOST_SystemX11::
 ~GHOST_SystemX11()
 {
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+	XCloseIM(m_xim);
+#endif
+
 	XCloseDisplay(m_display);
 }
 
@@ -500,9 +509,9 @@
 		case KeyRelease:
 		{
 			XKeyEvent *xke = &(xe->xkey);
-		
 			KeySym key_sym = XLookupKeysym(xke,0);
 			char ascii;
+			char utf8_buf[6]; /* 6 is enough for a utf8 char */
 			
 			GHOST_TKey gkey = convertXKey(key_sym);
 			GHOST_TEventType type = (xke->type == KeyPress) ? 
@@ -512,13 +521,55 @@
 				ascii = '\0';
 			}
 			
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+			/* getting unicode on key-up events gives XLookupNone status */
+			if (xke->type == KeyPress) {
+				Status status;
+				int len;
+
+				/* use utf8 because its not locale depentant, from xorg docs */
+				if (!(len= Xutf8LookupString(window->getX11_XIC(), xke, utf8_buf, sizeof(utf8_buf), &key_sym, &status))) {
+					utf8_buf[0]= '\0';
+				}
+
+				if ((status == XLookupChars || status == XLookupBoth)) {
+					if ((unsigned char)utf8_buf[0] >= 32) { /* not an ascii control character */
+						/* do nothing for now, this is valid utf8 */
+					}
+					else {
+						utf8_buf[0]= '\0';
+					}
+				}
+				else if (status == XLookupKeySym) {
+					/* this key doesn't have a text representation, it is a command
+					   key of some sort */;
+				}
+				else {
+					printf("Bad keycode lookup. Keysym 0x%x Status: %s\n",
+							  (unsigned int) key_sym,
+							  (status == XBufferOverflow ? "BufferOverflow" :
+							   status == XLookupNone ? "XLookupNone" :
+							   status == XLookupKeySym ? "XLookupKeySym" :
+							   "Unknown status"));
+
+					printf("'%.*s' %p %p\n", len, utf8_buf, window->getX11_XIC(), m_xim);
+				}
+			}
+			else {
+				utf8_buf[0]= '\0';
+			}
+#else
+			utf8_buf[0]= '\0';
+#endif
+
 			g_event = new
 			GHOST_EventKey(
 				getMilliSeconds(),
 				type,
 				window,
 				gkey,
-				ascii
+				ascii,
+			    utf8_buf
 			);
 			
 		break;

Modified: trunk/blender/intern/ghost/intern/GHOST_SystemX11.h
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_SystemX11.h	2011-10-20 05:18:02 UTC (rev 41128)
+++ trunk/blender/intern/ghost/intern/GHOST_SystemX11.h	2011-10-20 05:30:26 UTC (rev 41129)
@@ -40,6 +40,12 @@
 #include "GHOST_System.h"
 #include "../GHOST_Types.h"
 
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+#  define GHOST_X11_RES_NAME  "Blender" /* res_name */
+#  define GHOST_X11_RES_CLASS "Blender" /* res_class */
+#endif
+
+
 class GHOST_WindowX11;
 
 /**
@@ -203,6 +209,14 @@
 		return m_display;
 	}	
 
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+		XIM
+	getX11_XIM(
+	) {
+		return m_xim;
+	}
+#endif
+
 	/* Helped function for get data from the clipboard. */
 	void getClipboard_xcout(XEvent evt, Atom sel, Atom target,
 			 unsigned char **txt, unsigned long *len,
@@ -258,6 +272,9 @@
 private :
 
 	Display * m_display;
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+	XIM m_xim;
+#endif
 
 	/// The vector of windows that need to be updated.
 	std::vector<GHOST_WindowX11 *> m_dirty_windows;

Modified: trunk/blender/intern/ghost/intern/GHOST_WindowX11.cpp
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_WindowX11.cpp	2011-10-20 05:18:02 UTC (rev 41128)
+++ trunk/blender/intern/ghost/intern/GHOST_WindowX11.cpp	2011-10-20 05:30:26 UTC (rev 41129)
@@ -392,6 +392,13 @@
 		}
 	}
 
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+	m_xic = XCreateIC(m_system->getX11_XIM(), XNClientWindow, m_window, XNFocusWindow, m_window,
+	                  XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
+	                  XNResourceName, GHOST_X11_RES_NAME, XNResourceClass,
+	                  GHOST_X11_RES_CLASS, NULL);
+#endif
+
 	// Set the window icon
 	XWMHints *xwmhints = XAllocWMHints();
 	XImage *x_image, *mask_image;
@@ -1304,6 +1311,13 @@
 		XSetSelectionOwner(m_display, Clipboard_atom, None, CurrentTime);
 	}
 	
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+	if (m_xic) {
+		XDestroyIC(m_xic);
+	}
+#endif
+
+
 	XDestroyWindow(m_display, m_window);
 	XFree(m_visual);
 }

Modified: trunk/blender/intern/ghost/intern/GHOST_WindowX11.h
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_WindowX11.h	2011-10-20 05:18:02 UTC (rev 41128)
+++ trunk/blender/intern/ghost/intern/GHOST_WindowX11.h	2011-10-20 05:30:26 UTC (rev 41129)
@@ -221,6 +221,10 @@
 	{ return NULL; }
 #endif // WITH_X11_XINPUT
 
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+	XIC getX11_XIC() { return m_xic; }
+#endif
+
 	/*

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list