To: vim-dev@vim.org Subject: Patch 6.1a.028 Fcc: outbox From: Bram Moolenaar 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 -- Bram@moolenaar.net -- 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 ///