[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [48829] branches/soc-2011-tomato: Merging r48826 through r48828 from trunk into soc-2011-tomato
Sergey Sharybin
sergey.vfx at gmail.com
Wed Jul 11 12:39:08 CEST 2012
Revision: 48829
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=48829
Author: nazgul
Date: 2012-07-11 10:39:08 +0000 (Wed, 11 Jul 2012)
Log Message:
-----------
Merging r48826 through r48828 from trunk into soc-2011-tomato
Revision Links:
--------------
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=48826
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=48828
Modified Paths:
--------------
branches/soc-2011-tomato/intern/ghost/intern/GHOST_SystemX11.cpp
branches/soc-2011-tomato/intern/ghost/intern/GHOST_SystemX11.h
branches/soc-2011-tomato/intern/ghost/intern/GHOST_WindowX11.cpp
branches/soc-2011-tomato/intern/ghost/intern/GHOST_WindowX11.h
branches/soc-2011-tomato/release/scripts/startup/bl_ui/space_clip.py
branches/soc-2011-tomato/source/blender/editors/mask/mask_edit.c
branches/soc-2011-tomato/source/blender/editors/mask/mask_intern.h
branches/soc-2011-tomato/source/blender/editors/mask/mask_ops.c
Property Changed:
----------------
branches/soc-2011-tomato/
branches/soc-2011-tomato/source/blender/editors/interface/interface.c
branches/soc-2011-tomato/source/blender/editors/space_outliner/
Property changes on: branches/soc-2011-tomato
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/ge_harmony:42255,42279-42282,42286,42302,42338,42349,42616,42620,42698-42699,42739,42753,42773-42774,42832,44568,44597-44598,44793-44794
/branches/soc-2011-cucumber:37517,38166-38167,38177,38179-38180,38187,38242,38384,38387,38403-38404,38407,38968,38970,38973,39045,40845,42997-42998,43439
/branches/vgroup_modifiers:38694-39989
/trunk/blender:36831-48825
+ /branches/ge_harmony:42255,42279-42282,42286,42302,42338,42349,42616,42620,42698-42699,42739,42753,42773-42774,42832,44568,44597-44598,44793-44794
/branches/soc-2011-cucumber:37517,38166-38167,38177,38179-38180,38187,38242,38384,38387,38403-38404,38407,38968,38970,38973,39045,40845,42997-42998,43439
/branches/vgroup_modifiers:38694-39989
/trunk/blender:36831-48828
Modified: branches/soc-2011-tomato/intern/ghost/intern/GHOST_SystemX11.cpp
===================================================================
--- branches/soc-2011-tomato/intern/ghost/intern/GHOST_SystemX11.cpp 2012-07-11 10:37:38 UTC (rev 48828)
+++ branches/soc-2011-tomato/intern/ghost/intern/GHOST_SystemX11.cpp 2012-07-11 10:39:08 UTC (rev 48829)
@@ -93,9 +93,12 @@
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);
+ /* note -- don't open connection to XIM server here, because the locale
+ * has to be set before opening the connection but setlocale() has not
+ * been called yet. the connection will be opened after entering
+ * the event loop. */
+ m_xim = NULL;
#endif
m_delete_window_atom
@@ -273,6 +276,35 @@
return window;
}
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+static void destroyIMCallback(XIM xim, XPointer ptr, XPointer data)
+{
+ GHOST_PRINT("XIM server died\n");
+
+ if (ptr)
+ *(XIM *)ptr = NULL;
+}
+
+bool GHOST_SystemX11::openX11_IM()
+{
+ if (!m_display)
+ return false;
+
+ /* set locale modifiers such as "@im=ibus" specified by XMODIFIERS */
+ XSetLocaleModifiers("");
+
+ m_xim = XOpenIM(m_display, NULL, (char *)GHOST_X11_RES_NAME, (char *)GHOST_X11_RES_CLASS);
+ if (!m_xim)
+ return false;
+
+ XIMCallback destroy;
+ destroy.callback = (XIMProc)destroyIMCallback;
+ destroy.client_data = (XPointer)&m_xim;
+ XSetIMValues(m_xim, XNDestroyCallback, &destroy, NULL);
+ return true;
+}
+#endif
+
GHOST_WindowX11 *
GHOST_SystemX11::
findGhostWindow(
@@ -408,6 +440,38 @@
while (XPending(m_display)) {
XEvent xevent;
XNextEvent(m_display, &xevent);
+
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+ /* open connection to XIM server and create input context (XIC)
+ * when receiving the first FocusIn or KeyPress event after startup,
+ * or recover XIM and XIC when the XIM server has been restarted */
+ if (xevent.type == FocusIn || xevent.type == KeyPress) {
+ if (!m_xim && openX11_IM()) {
+ GHOST_PRINT("Connected to XIM server\n");
+ }
+
+ if (m_xim) {
+ GHOST_WindowX11 * window = findGhostWindow(xevent.xany.window);
+ if (window && !window->getX11_XIC() && window->createX11_XIC()) {
+ GHOST_PRINT("XIM input context created\n");
+ if (xevent.type == KeyPress)
+ /* we can assume the window has input focus
+ * here, because key events are received only
+ * when the window is focused. */
+ XSetICFocus(window->getX11_XIC());
+ }
+ }
+ }
+
+ /* dispatch event to XIM server */
+ if ((XFilterEvent(&xevent, (Window)NULL) == True) && (xevent.type != KeyRelease)) {
+ /* do nothing now, the event is consumed by XIM.
+ * however, KeyRelease event should be processed
+ * here, otherwise modifiers remain activated. */
+ continue;
+ }
+#endif
+
processEvent(&xevent);
anyProcessed = true;
}
@@ -535,7 +599,19 @@
XKeyEvent *xke = &(xe->xkey);
KeySym key_sym = XLookupKeysym(xke, 0);
char ascii;
- char utf8_buf[6]; /* 6 is enough for a utf8 char */
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+ /* utf8_array[] is initial buffer used for Xutf8LookupString().
+ * if the length of the utf8 string exceeds this array, allocate
+ * another memory area and call Xutf8LookupString() again.
+ * the last 5 bytes are used to avoid segfault that might happen
+ * at the end of this buffer when the constructor of GHOST_EventKey
+ * reads 6 bytes regardless of the effective data length. */
+ char utf8_array[16 * 6 + 5]; /* 16 utf8 characters */
+ char *utf8_buf = utf8_array;
+ int len = 1; /* at least one null character will be stored */
+#else
+ char *utf8_buf = NULL;
+#endif
GHOST_TKey gkey = convertXKey(key_sym);
GHOST_TEventType type = (xke->type == KeyPress) ?
@@ -547,15 +623,20 @@
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
/* getting unicode on key-up events gives XLookupNone status */
- if (xke->type == KeyPress) {
+ XIC xic = window->getX11_XIC();
+ if (xic && 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))) {
+ if (!(len = Xutf8LookupString(xic, xke, utf8_buf, sizeof(utf8_array) - 5, &key_sym, &status))) {
utf8_buf[0] = '\0';
}
+ if (status == XBufferOverflow) {
+ utf8_buf = (char *) malloc(len + 5);
+ len = Xutf8LookupString(xic, xke, utf8_buf, len, &key_sym, &status);
+ }
+
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 */
@@ -571,19 +652,16 @@
else {
printf("Bad keycode lookup. Keysym 0x%x Status: %s\n",
(unsigned int) key_sym,
- (status == XBufferOverflow ? "BufferOverflow" :
- status == XLookupNone ? "XLookupNone" :
+ (status == XLookupNone ? "XLookupNone" :
status == XLookupKeySym ? "XLookupKeySym" :
"Unknown status"));
- printf("'%.*s' %p %p\n", len, utf8_buf, window->getX11_XIC(), m_xim);
+ printf("'%.*s' %p %p\n", len, utf8_buf, xic, m_xim);
}
}
else {
utf8_buf[0] = '\0';
}
-#else
- utf8_buf[0] = '\0';
#endif
g_event = new
@@ -595,6 +673,42 @@
ascii,
utf8_buf
);
+
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+ /* when using IM for some languages such as Japanese,
+ * one event inserts multiple utf8 characters */
+ if (xic && xke->type == KeyPress) {
+ unsigned char c;
+ int i = 0;
+ while (1) {
+ /* search character boundary */
+ if ((unsigned char)utf8_buf[i++] > 0x7f) {
+ for (; i < len; ++i) {
+ c = utf8_buf[i];
+ if (c < 0x80 || c > 0xbf) break;
+ }
+ }
+
+ if (i >= len) break;
+
+ /* enqueue previous character */
+ pushEvent(g_event);
+
+ g_event = new
+ GHOST_EventKey(
+ getMilliSeconds(),
+ type,
+ window,
+ gkey,
+ '\0',
+ &utf8_buf[i]
+ );
+ }
+ }
+
+ if (utf8_buf != utf8_array)
+ free(utf8_buf);
+#endif
break;
}
@@ -675,6 +789,16 @@
GHOST_TEventType gtype = (xfe.type == FocusIn) ?
GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate;
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+ XIC xic = window->getX11_XIC();
+ if (xic) {
+ if (xe->type == FocusIn)
+ XSetICFocus(xic);
+ else
+ XUnsetICFocus(xic);
+ }
+#endif
+
g_event = new
GHOST_Event(
getMilliSeconds(),
Modified: branches/soc-2011-tomato/intern/ghost/intern/GHOST_SystemX11.h
===================================================================
--- branches/soc-2011-tomato/intern/ghost/intern/GHOST_SystemX11.h 2012-07-11 10:37:38 UTC (rev 48828)
+++ branches/soc-2011-tomato/intern/ghost/intern/GHOST_SystemX11.h 2012-07-11 10:39:08 UTC (rev 48829)
@@ -309,6 +309,10 @@
* X11 window xwind
*/
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+ bool openX11_IM();
+#endif
+
GHOST_WindowX11 *
findGhostWindow(
Window xwind
Modified: branches/soc-2011-tomato/intern/ghost/intern/GHOST_WindowX11.cpp
===================================================================
--- branches/soc-2011-tomato/intern/ghost/intern/GHOST_WindowX11.cpp 2012-07-11 10:37:38 UTC (rev 48828)
+++ branches/soc-2011-tomato/intern/ghost/intern/GHOST_WindowX11.cpp 2012-07-11 10:39:08 UTC (rev 48829)
@@ -401,10 +401,7 @@
}
#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);
+ m_xic = NULL;
#endif
// Set the window icon
@@ -478,6 +475,47 @@
XFlush(m_display);
}
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+static void destroyICCallback(XIC xic, XPointer ptr, XPointer data)
+{
+ GHOST_PRINT("XIM input context destroyed\n");
+
+ if (ptr) {
+ *(XIC *)ptr = NULL;
+ }
+}
+
+bool GHOST_WindowX11::createX11_XIC()
+{
+ XIM xim = m_system->getX11_XIM();
+ if (!xim)
+ return false;
+
+ XICCallback destroy;
+ destroy.callback = (XICProc)destroyICCallback;
+ destroy.client_data = (XPointer)&m_xic;
+ m_xic = XCreateIC(xim, XNClientWindow, m_window, XNFocusWindow, m_window,
+ XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
+ XNResourceName, GHOST_X11_RES_NAME,
+ XNResourceClass, GHOST_X11_RES_CLASS,
+ XNDestroyCallback, &destroy,
+ NULL);
+ if (!m_xic)
+ return false;
+
+ unsigned long fevent;
+ XGetICValues(m_xic, XNFilterEvents, &fevent, NULL);
+ XSelectInput(m_display, m_window,
+ ExposureMask | StructureNotifyMask |
+ KeyPressMask | KeyReleaseMask |
+ EnterWindowMask | LeaveWindowMask |
+ ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask | FocusChangeMask |
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list