To: [email protected]
Subject: Patch 6.1a.028
Fcc: outbox
From: Bram Moolenaar <[email protected]>
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
------------

Patch 6.1a.028
Problem:    XIM: problems with feedback and some input methods.
Solution:   Use iconv for calculating the cells.  Remove the queue for
           key_press_event only when text was changed. (Yasuhiro Matsumoto)
Files:      src/globals.h, src/mbyte.c, src/screen.c


*** ../vim61a.027/src/globals.h Fri Feb 22 16:07:45 2002
--- src/globals.h       Mon Mar  4 21:10:06 2002
***************
*** 611,616 ****
--- 611,618 ----
 # ifdef FEAT_GUI_GTK
 EXTERN GdkICAttr      *xic_attr INIT(= NULL);
 EXTERN GdkIC          *xic INIT(= NULL);
+ EXTERN colnr_T                preedit_start_col INIT(= MAXCOL);
+ EXTERN char           *draw_feedback INIT(= NULL);
 # else
 EXTERN XIC            xic INIT(= NULL);
 # endif
*** ../vim61a.027/src/mbyte.c   Sun Feb 24 20:33:52 2002
--- src/mbyte.c Mon Mar  4 21:30:06 2002
***************
*** 2677,2682 ****
--- 2677,2683 ----
 #endif

 #if defined(FEAT_GUI_GTK) || defined(PROTO)
+ static int    preedit_buf_len = 0;
 static int    xim_preediting INIT(= FALSE);   /* XIM in showmode() */
 static int    xim_input_style;
 #ifndef FEAT_GUI_GTK
***************
*** 2878,2883 ****
--- 2879,2889 ----
           }
       }
     }
+     if (xim_input_style & XIMPreeditCallbacks)
+     {
+       preedit_buf_len = 0;
+       getvcol(curwin, &(curwin->w_cursor), &preedit_start_col, NULL, NULL);
+     }
 #else
 # if 0
       /* When had tested kinput2 + canna + Athena GUI version with
***************
*** 3593,3598 ****
--- 3599,3605 ----
     static void
 preedit_start_cbproc(XIC xic, XPointer client_data, XPointer call_data)
 {
+     draw_feedback = NULL;
     xim_preediting = TRUE;
     gui_update_cursor(TRUE, FALSE);
     if (showmode() > 0)
***************
*** 3615,3621 ****
 }

 static GSList *key_press_event_queue = NULL;
- static int preedit_buf_len = 0;
 static gboolean processing_queued_event = FALSE;

 /*ARGSUSED*/
--- 3622,3627 ----
***************
*** 3630,3635 ****
--- 3636,3648 ----
     draw_data = (XIMPreeditDrawCallbackStruct *) call_data;
     text = (XIMText *) draw_data->text;

+     if ((text == NULL && draw_data->chg_length == preedit_buf_len)
+           || preedit_buf_len == 0)
+     {
+       getvcol(curwin, &(curwin->w_cursor), &preedit_start_col, NULL, NULL);
+       vim_free(draw_feedback);
+       draw_feedback = NULL;
+     }
     if (draw_data->chg_length > 0)
     {
       int bs_cnt;
***************
*** 3641,3686 ****
       xim_back_delete(bs_cnt);
       preedit_buf_len -= bs_cnt;
     }
!     if (text != NULL && (src = text->string.multi_byte) != NULL)
     {
!       int             len = strlen(src);
 #ifdef FEAT_MBYTE
!       char_u          *buf;
 #endif
!       GdkWChar        *wstr = NULL;

-       wstr = g_new(GdkWChar, len);
-       preedit_buf_len += gdk_mbstowcs(wstr, src, len);
-       g_free(wstr);
 #ifdef FEAT_MBYTE
!       if (input_conv.vc_type != CONV_NONE
!               && (buf = string_convert(&input_conv,
                                                (char_u *)src, &len)) != NULL)
!       {
!           /* Converted from 'termencoding' to 'encoding'. */
!           add_to_input_buf_csi(buf, len);
           vim_free(buf);
       }
-       else
- #endif
-           add_to_input_buf_csi((char_u *)src, len);
-     }
-     event_queue = key_press_event_queue;
-     processing_queued_event = TRUE;
-     while (event_queue)
-     {
-       GdkEvent *ev = event_queue->data;
-       gboolean *ret;
-       gtk_signal_emit_by_name((GtkObject*)gui.mainwin, "key_press_event",
-                               ev, &ret);
-       gdk_event_free(ev);
-       event_queue = event_queue->next;
     }
!     processing_queued_event = FALSE;
!     if (key_press_event_queue)
     {
!       g_slist_free(key_press_event_queue);
!       key_press_event_queue = NULL;
     }
     if (gtk_main_level() > 0)
       gtk_main_quit();
--- 3654,3738 ----
       xim_back_delete(bs_cnt);
       preedit_buf_len -= bs_cnt;
     }
!     if (text != NULL)
     {
!       int             len;
 #ifdef FEAT_MBYTE
!       char_u          *buf = NULL;
 #endif
!       char_u          *ptr;
!       unsigned int    nfeedback = 0;
!
!       src = text->string.multi_byte;
!       if (src != NULL && !text->encoding_is_wchar)
!       {
!           len = strlen(src);
!           ptr = (char_u *)src;
!           /* Avoid the enter for decision */
!           if (*ptr == '\n')
!               return;

 #ifdef FEAT_MBYTE
!           if (input_conv.vc_type != CONV_NONE
!                   && (buf = string_convert(&input_conv,
                                                (char_u *)src, &len)) != NULL)
!           {
!               /* Converted from 'termencoding' to 'encoding'. */
!               add_to_input_buf_csi(buf, len);
!               ptr = buf;
!           }
!           else
! #endif
!               add_to_input_buf_csi((char_u *)src, len);
!           /* Add count of character to preedit_buf_len  */
!           while (*ptr != NUL)
!           {
! #ifdef FEAT_MBYTE
!               if (draw_data->text->feedback != NULL)
!               {
!                   if (draw_feedback == NULL)
!                       draw_feedback = (char *)alloc(draw_data->chg_first
!                                                             + text->length);
!                   else
!                       draw_feedback = realloc(draw_feedback,
!                                        draw_data->chg_first + text->length);
!                   if (draw_feedback != NULL)
!                   {
!                       draw_feedback[nfeedback + draw_data->chg_first]
!                                      = draw_data->text->feedback[nfeedback];
!                       nfeedback++;
!                   }
!               }
!               if (has_mbyte)
!                   ptr += mb_ptr2len_check(ptr);
!               else
! #endif
!                   ptr++;
!               preedit_buf_len++;
!           }
           vim_free(buf);
       }
     }
!     if (text != NULL || draw_data->chg_length > 0)
     {
!       event_queue = key_press_event_queue;
!       processing_queued_event = TRUE;
!       while (event_queue != NULL)
!       {
!           GdkEvent *ev = event_queue->data;
!
!           gboolean *ret;
!           gtk_signal_emit_by_name((GtkObject*)gui.mainwin, "key_press_event",
!                                                                   ev, &ret);
!           gdk_event_free(ev);
!           event_queue = event_queue->next;
!       }
!       processing_queued_event = FALSE;
!       if (key_press_event_queue)
!       {
!           g_slist_free(key_press_event_queue);
!           key_press_event_queue = NULL;
!       }
     }
     if (gtk_main_level() > 0)
       gtk_main_quit();
***************
*** 3696,3701 ****
--- 3748,3755 ----
     static void
 preedit_done_cbproc(XIC xic, XPointer client_data, XPointer call_data)
 {
+     vim_free(draw_feedback);
+     draw_feedback = NULL;
     xim_preediting = FALSE;
     gui_update_cursor(TRUE, FALSE);
     if (showmode() > 0)
***************
*** 4105,4113 ****
       {
           int retlen;

!             if (!lenp)
!                 len /= sizeof(unsigned short);
!             retlen = WideCharToMultiByte(vcp->vc_dbcs, 0,
                               (const unsigned short *)ptr, len, 0, 0, 0, 0);
           retval = alloc(retlen + 1);
           if (retval == NULL)
--- 4159,4167 ----
       {
           int retlen;

!           if (!lenp)
!               len /= sizeof(unsigned short);
!           retlen = WideCharToMultiByte(vcp->vc_dbcs, 0,
                               (const unsigned short *)ptr, len, 0, 0, 0, 0);
           retval = alloc(retlen + 1);
           if (retval == NULL)
***************
*** 4116,4122 ****
                    (const unsigned short *) ptr, len, retval, retlen, 0, 0);
           retval[retlen] = NUL;
           if (lenp != NULL)
!               *lenp = retlen;
           break;
       }
       case CONV_CODEPAGE:     /* current codepage -> ucs-2 */
--- 4170,4176 ----
                    (const unsigned short *) ptr, len, retval, retlen, 0, 0);
           retval[retlen] = NUL;
           if (lenp != NULL)
!               *lenp = retlen;
           break;
       }
       case CONV_CODEPAGE:     /* current codepage -> ucs-2 */
***************
*** 4130,4136 ****
           MultiByteToWideChar(GetACP(), 0, ptr, len,
                                          (unsigned short *) retval, retlen);
           if (lenp != NULL)
!               *lenp = retlen * sizeof(unsigned short); /* number of shorts -> buffer size */
       }
 # endif
     }
--- 4184,4190 ----
           MultiByteToWideChar(GetACP(), 0, ptr, len,
                                          (unsigned short *) retval, retlen);
           if (lenp != NULL)
!               *lenp = retlen * sizeof(unsigned short); /* number of shorts -> buffer size */
       }
 # endif
     }
*** ../vim61a.027/src/screen.c  Sun Mar  3 17:04:53 2002
--- src/screen.c        Mon Mar  4 21:27:41 2002
***************
*** 3494,3499 ****
--- 3494,3543 ----
               && (search_attr == 0 || char_attr != search_attr))
           char_attr = extra_attr;

+ #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
+       if (xic != NULL
+               && lnum == curwin->w_cursor.lnum
+               && State == INSERT
+               && im_get_status()
+               && !p_imdisable
+               && preedit_start_col != MAXCOL)
+       {
+           colnr_T tcol;
+           static int  bcol = 0;
+           static int  old_attr = -1;
+
+           getvcol(curwin, &(curwin->w_cursor), &tcol, NULL, NULL);
+           if ((long)preedit_start_col <= vcol && vcol < (long)tcol)
+           {
+               if (old_attr == -1)
+               {
+                   bcol = 0;
+                   old_attr = char_attr;
+               }
+               if (draw_feedback != NULL)
+               {
+                   if (draw_feedback[bcol] & XIMReverse)
+                       char_attr = HL_INVERSE;
+                   else if (draw_feedback[bcol] & XIMUnderline)
+                       char_attr = HL_UNDERLINE;
+                   else
+                       char_attr = hl_attr(HLF_V);
+               }
+               else
+                   char_attr = old_attr;
+               bcol++;
+           }
+           else
+           {
+               if (old_attr >= 0)
+               {
+                   char_attr = old_attr;
+                   old_attr = -1;
+                   bcol = 0;
+               }
+           }
+       }
+ #endif
       /*
        * Handle the case where we are in column 0 but not on the first
        * character of the line and the user wants us to show us a
*** ../vim61a.027/src/version.c Mon Mar  4 20:57:03 2002
--- src/version.c       Mon Mar  4 21:43:36 2002
***************
*** 608,609 ****
--- 608,611 ----
 {   /* Add new patch number below this line */
+ /**/
+     28,
 /**/

--
In a world without fences, who needs Gates and Windows?

///  Bram Moolenaar -- [email protected] -- http://www.moolenaar.net  \\\
///   Creator of Vim -- http://vim.sf.net -- ftp://ftp.vim.org/pub/vim   \\\
\\\           Project leader for A-A-P -- http://www.a-a-p.org           ///
\\\  Help me helping AIDS orphans in Uganda - http://iccf-holland.org  ///