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. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to