Author: ek.kato
Date: Tue Oct  7 04:26:08 2008
New Revision: 5584

Modified:
   trunk/helper/candwin-gtk.c
   trunk/qt/candwin-qt.cpp
   trunk/qt/candwin-qt.h
   trunk/xim/canddisp.cpp
   trunk/xim/canddisp.h
   trunk/xim/main.cpp
   trunk/xim/ximserver.cpp
   trunk/xim/ximserver.h

Log:
* xim/ximserver.h : Define UIM_XIM_USE_NEW_PAGE_HANDLING as in
  r5577.
* xim/ximserver.cpp
  - (InputContext::InputContext) : Initialize mNumCandidates.
  - (InputContext::candidate_activate)
    - Fix possible leaks.
    - Only set the first page for UIM_XIM_USE_NEW_PAGE_HANDLING.
  - (InputContext::candidate_update) : Only set the current page
    for UIM_XIM_USE_NEW_PAGE_HANDLING.
  - (InputContext::prepare_page_candidates) : New.  Set candidate
    list for the selected page.
  - (InputContext::candidate_select) : Check the candidate list
    for the new page with UIM_XIM_USE_NEW_PAGE_HANDLING.
  - (InputContext::candidate_shift_page) : Ditto.
  - (InputContext::candidate_deactivate) : Use per-page memory
    handling for UIM_XIM_USE_NEW_PAGE_HANDLING.
* xim/canddisp.h
* xim/canddisp.cpp
  - (Canddisp::set_nr_candidates)
  - (Canddisp::set_page_candidates)
  - (Canddisp::show_page)
    - New.  New message for helper-candwin with
      UIM_XIM_USE_NEW_PAGE_HANDLING.
* xim/main.cpp (main) : Modify startup message.
* helper/candwin-gtk.c
  - Support UIM_XIM_USE_NEW_PAGE_HANDLING.
  - (candwin_set_nr_candidates)
  - (candwin_set_page_candidates)
  - (candwin_show_page)
    - New protocol handler.
  - (cb_tree_view_destroy) : Add sanity check.
  - (candwin_activate) : Ditto.
  - (str_parse) : Handle new messages with
    UIM_XIM_USE_NEW_PAGE_HANDLING.
  - (uim_cand_win_gtk_set_index) : Port r5578 from GTK+ bridge.
  - (uim_cand_win_gtk_set_page) : Port r5577 from GTK+ bridge.
  - (uim_cand_win_gtk_set_page_candidates) : New.  Copied from
    GTK+ bridge.
* qt/candwin-qt.cpp
* qt/candwin-qt.h
  - Support UIM_XIM_USE_NEW_PAGE_HANDING.
  - (CandidateWindow::setNrCandidates)
  - (CandidateWindow::setPageCandidates)
  - (CandidateWindow::showPage)
    - New protocol handler.
  - (CandidateWindow::strParse) : Handle new messages with
    UIM_XIM_USE_NEW_PAGE_HANDLING.


Modified: trunk/helper/candwin-gtk.c
==============================================================================
--- trunk/helper/candwin-gtk.c  (original)
+++ trunk/helper/candwin-gtk.c  Tue Oct  7 04:26:08 2008
@@ -96,6 +96,7 @@
 static gint uim_cand_win_gtk_get_index(UIMCandidateWindow *cwin);
static void uim_cand_win_gtk_set_index(UIMCandidateWindow *cwin, gint index);
 static void uim_cand_win_gtk_set_page(UIMCandidateWindow *cwin, gint page);
+static void uim_cand_win_gtk_set_page_candidates(UIMCandidateWindow *cwin, guint page, GSList *candidates);

 static void uim_cand_win_gtk_layout(void);

@@ -150,6 +151,9 @@
 static void candwin_move(char **str);
 static void candwin_show(void);
 static void candwin_deactivate(void);
+static void candwin_set_nr_candidates(gchar **str);
+static void candwin_set_page_candidates(gchar **str);
+static void candwin_show_page(gchar **str);
 static void str_parse(char *str);

 static void index_changed_cb(UIMCandidateWindow *cwin)
@@ -286,8 +290,10 @@

   for (i = cwin->stores->len - 1; i >= 0; i--) {
     GtkListStore *store = g_ptr_array_remove_index(cwin->stores, i);
-    gtk_list_store_clear(store);
-    g_object_unref(G_OBJECT(store));
+    if (store) {
+      gtk_list_store_clear(store);
+      g_object_unref(G_OBJECT(store));
+    }
   }
   g_ptr_array_free(cwin->stores, TRUE);
 }
@@ -405,8 +411,10 @@
   /* remove old data */
   for (i = cwin->stores->len - 1; i >= 0; i--) {
     GtkListStore *store = g_ptr_array_remove_index(cwin->stores, i);
-    gtk_list_store_clear(store);
-    g_object_unref(G_OBJECT(store));
+    if (store) {
+      gtk_list_store_clear(store);
+      g_object_unref(G_OBJECT(store));
+    }
   }

   if (!strncmp(str[1], "charset=", 8))
@@ -546,6 +554,99 @@
   gtk_widget_hide(cwin->caret_state_indicator);
 }

+static void
+candwin_set_nr_candidates(gchar **str)
+{
+  guint nr, display_limit;
+  gint i, nr_stores = 1;
+
+  sscanf(str[1], "%ud", &nr);
+  sscanf(str[2], "%ud", &display_limit);
+
+  cwin->candidate_index = -1;
+  cwin->nr_candidates = nr;
+  cwin->display_limit = display_limit;
+  cwin->need_hilite = FALSE;
+  cwin->is_active = TRUE;
+
+  if (cwin->stores == NULL)
+    cwin->stores = g_ptr_array_new();
+
+  /* remove old data */
+  for (i = cwin->stores->len - 1; i >= 0; i--) {
+    GtkListStore *store = g_ptr_array_remove_index(cwin->stores, i);
+    if (store) {
+      gtk_list_store_clear(store);
+      g_object_unref(G_OBJECT(store));
+    }
+  }
+
+  /* calculate number of GtkListStores to create */
+  if (display_limit) {
+    nr_stores = nr / display_limit;
+    if (nr > display_limit * nr_stores)
+      nr_stores++;
+  }
+
+  /* setup dummy array */
+  for (i = 0; i < nr_stores; i++)
+    g_ptr_array_add(cwin->stores, NULL);
+}
+
+static void
+candwin_set_page_candidates(gchar **str)
+{
+  gsize rbytes, wbytes;
+  gint i;
+  guint j = 1;
+  gchar *utf8_str;
+  const gchar *charset;
+  GSList *candidates = NULL;
+  int page;
+
+  if (!strncmp(str[1], "charset=", 8))
+    charset = str[1] + 8;
+  else
+    charset = "UTF-8";
+
+  if (!strncmp(str[2], "page=", 5)) {
+    page = atoi(str[2] + 5);
+    i = 3;
+  } else {
+    /* shouldn't happen */
+    page = 0;
+    i = 2;
+  }
+
+  for ( ; str[i]; i++) {
+    if (strcmp(str[i], "") == 0) {
+      break;
+    }
+    utf8_str = g_convert(str[i],
+                        -1,
+                        "UTF-8",
+                        charset,
+                        &rbytes, &wbytes, NULL);
+
+    candidates = g_slist_prepend(candidates, utf8_str);
+    j++;
+  }
+  candidates = g_slist_reverse(candidates);
+
+  uim_cand_win_gtk_set_page_candidates(cwin, page, candidates);
+}
+
+static void
+candwin_show_page(gchar **str)
+{
+  int page;
+
+  sscanf(str[1], "%d", &page);
+
+  uim_cand_win_gtk_set_page(cwin, page);
+  gtk_widget_show_all(GTK_WIDGET(cwin));
+}
+
 static void str_parse(gchar *str)
 {
   gchar **tmp;
@@ -573,6 +674,12 @@
       caret_state_update();
     } else if (strcmp("hide_caret_state", command) == 0) {
       caret_state_hide();
+    } else if (strcmp("set_nr_candidates", command) == 0) {
+      candwin_set_nr_candidates(tmp);
+    } else if (strcmp("set_page_candidates", command) == 0) {
+      candwin_set_page_candidates(tmp);
+    } else if (strcmp("show_page", command) == 0) {
+      candwin_show_page(tmp);
     }
   }
   g_strfreev(tmp);
@@ -679,6 +786,7 @@
 ->view));

     gtk_tree_selection_unselect_all(selection);
+    update_label(cwin);
   }
 }

@@ -695,20 +803,15 @@
   len = cwin->stores->len;
   g_return_if_fail(len);

-  if (page < 0) {
-    gtk_tree_view_set_model(GTK_TREE_VIEW(cwin->view),
-                           GTK_TREE_MODEL(cwin->stores->pdata[len - 1]));
+  if (page < 0)
     new_page = len - 1;
-  } else if (page >= (gint) len) {
-    gtk_tree_view_set_model(GTK_TREE_VIEW(cwin->view),
-                           GTK_TREE_MODEL(cwin->stores->pdata[0]));
+  else if (page >= (gint) len)
     new_page = 0;
-  } else {
-    gtk_tree_view_set_model(GTK_TREE_VIEW(cwin->view),
-
-                           GTK_TREE_MODEL(cwin->stores->pdata[page]));
+  else
     new_page = page;
-  }
+
+  gtk_tree_view_set_model(GTK_TREE_VIEW(cwin->view),
+                         GTK_TREE_MODEL(cwin->stores->pdata[new_page]));

   cwin->page_index = new_page;

@@ -728,8 +831,50 @@
  /* shrink the window */
   gtk_window_resize(GTK_WINDOW(cwin), CANDWIN_DEFAULT_WIDTH, 1);

-  if (new_index != -1)
-    uim_cand_win_gtk_set_index(cwin, new_index);
+  uim_cand_win_gtk_set_index(cwin, new_index);
+}
+
+/* copied from uim-cand-win-gtk.c and adjusted */
+static void
+uim_cand_win_gtk_set_page_candidates(UIMCandidateWindow *cwin,
+                                    guint page,
+                                    GSList *candidates)
+{
+  GtkListStore *store;
+  GSList *node;
+  gint j, len;
+
+  g_return_if_fail(UIM_IS_CANDIDATE_WINDOW(cwin));
+
+  if (candidates == NULL)
+    return;
+
+  len = g_slist_length(candidates);
+
+  /* create GtkListStores, and set candidates */
+  store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
+
+  cwin->stores->pdata[page] = store;
+  /* set candidates */
+  for (j = 0, node = g_slist_nth(candidates, j);
+       j < len;
+       j++, node = g_slist_next(node))
+  {
+    GtkTreeIter ti;
+
+    if (node) {
+      gchar *str = node->data;
+      gchar **column = g_strsplit(str, "\t", 2);
+      gtk_list_store_append(store, &ti);
+      gtk_list_store_set(store, &ti,
+                        COLUMN_HEADING, column[0],
+                        COLUMN_CANDIDATE, column[1],
+                        TERMINATOR);
+
+      g_strfreev(column);
+      g_free(str);
+    }
+  }
 }

 static void

Modified: trunk/qt/candwin-qt.cpp
==============================================================================
--- trunk/qt/candwin-qt.cpp     (original)
+++ trunk/qt/candwin-qt.cpp     Tue Oct  7 04:26:08 2008
@@ -248,6 +248,99 @@
     hide();
     isActive = false;
 }
+void CandidateWindow::setNrCandidates( const QStringList &list )
+{
+#if defined(ENABLE_DEBUG)
+    qDebug( "uim-candwin-qt: setNrCandidates()" );
+#endif
+    if ( list[ 1 ].isEmpty() || list[ 2 ].isEmpty() )
+        return ;
+
+    // remove old data
+    cList->clear();
+    stores.clear();
+
+    // set default value
+    candidateIndex = -1;
+    nrCandidates = list[ 1 ].toInt();
+    displayLimit = list[ 2 ].toInt();
+    needHilite = false;
+    isActive = true;
+
+    // setup dummy stores
+    for ( int i = 0; i < nrCandidates; i++ ) {
+       CandData d;
+       stores.append( d );
+    }
+}
+void CandidateWindow::setPageCandidates( const QStringList &list )
+{
+#if defined(ENABLE_DEBUG)
+    qDebug( "uim-candwin-qt: setPageCandidates()" );
+#endif
+    /**
+ * format: set_page_candidates\ncharset=$charset\npage=$value\nhead1\tcand1\nhead2\tcand2\nhead3\tcand3\n
+     */
+
+    int page = 0;
+
+    // get charset and create codec
+    QTextCodec *codec = NULL;
+    if ( !list[ 1 ].isEmpty() && list[ 1 ].startsWith( "charset" ) )
+    {
+        const QStringList l = QStringList::split( "=", list[ 1 ] );
+        codec = QTextCodec::codecForName( l[ 1 ] );
+    }
+
+    // get page
+    if ( !list[ 2 ].isEmpty() && list[ 2 ].startsWith( "page" ) )
+    {
+        const QStringList l = QStringList::split( "=", list[ 2 ] );
+        page = l[ 1 ].toInt();
+    }
+
+    for ( int i = 3; !list[ i ].isNull(); i++ )
+    {
+        // case list[i] = ""
+        if ( list[ i ].isEmpty() )
+            break;
+
+        // split heading_label and cand_str
+        QStringList l = QStringList::split( "\t", list [ i ], true );
+
+        // store data
+        CandData &d = stores[page * displayLimit + i - 3];
+        QString headString;
+        if ( codec )
+            headString = codec->toUnicode( l [ 0 ] );
+        else
+            headString = l [ 0 ];
+
+        d.label = headString;
+
+       // XXX Current prime (0.4.6) may return candidate string
+       // containing "\t", and we can't handle annotation in another
+       // window yet.
+       l.pop_front();
+       QString candString = l.join( "\t" );
+
+        if ( codec )
+            d.str = codec->toUnicode( candString );
+        else
+            d.str = candString;
+    }
+}
+void CandidateWindow::showPage( const QStringList &list )
+{
+#if defined(ENABLE_DEBUG)
+    qDebug( "uim-candwin-qt: showPage()" );
+#endif
+    const int page = list[ 1 ].toInt();
+
+    setPage( page );
+    adjustCandidateWindowSize();
+    show();
+}
 void CandidateWindow::slotStdinActivated( int fd )
 {
     char buf[ 4096 ];
@@ -300,6 +393,12 @@
             moveCand( list );
         else if ( QString::compare( "deactivate", ( *it ) ) == 0 )
             deactivateCand();
+        else if ( QString::compare( "set_nr_candidates", ( *it ) ) == 0 )
+            setNrCandidates( list );
+        else if ( QString::compare( "set_page_candidates", ( *it ) ) == 0 )
+            setPageCandidates( list );
+        else if ( QString::compare( "show_page", ( *it ) ) == 0 )
+            showPage( list );
     }
 }


Modified: trunk/qt/candwin-qt.h
==============================================================================
--- trunk/qt/candwin-qt.h       (original)
+++ trunk/qt/candwin-qt.h       Tue Oct  7 04:26:08 2008
@@ -64,6 +64,10 @@
     void showCand();
     void deactivateCand();

+    void setNrCandidates( const QStringList &list );
+    void setPageCandidates( const QStringList &list );
+    void showPage( const QStringList &list );
+
 public slots:
     void slotStdinActivated( int );
     void slotCandidateSelected( QListViewItem* );
@@ -112,7 +116,7 @@
         {
             QListViewItemIterator it( firstChild() );
             uint j = 0;
-            for ( ; it.current() && it.current() != item; ++it, ++j );
+            for ( ; it.current() && it.current() != item; ++it, ++j ) ;

             if ( !it.current() )
                 return -1;

Modified: trunk/xim/canddisp.cpp
==============================================================================
--- trunk/xim/canddisp.cpp      (original)
+++ trunk/xim/canddisp.cpp      Tue Oct  7 04:26:08 2008
@@ -138,6 +138,48 @@
     check_connection();
 }

+#if UIM_XIM_USE_NEW_PAGE_HANDLING
+void Canddisp::set_nr_candidates(int nr, int display_limit)
+{
+    if (!candwin_w)
+       return;
+
+    fprintf(candwin_w, "set_nr_candidates\n");
+    fprintf(candwin_w, "%d\n", nr);
+    fprintf(candwin_w, "%d\n", display_limit);
+    fprintf(candwin_w, "\n");
+    fflush(candwin_w);
+    check_connection();
+}
+
+void Canddisp::set_page_candidates(int page, CandList candidates)
+{
+    std::vector<const char *>::iterator i;
+
+    if (!candwin_w)
+       return;
+
+ fprintf(candwin_w, "set_page_candidates\ncharset=UTF-8\npage=%d\n", page);
+    for (i = candidates.begin(); i != candidates.end(); ++i)
+       fprintf(candwin_w, "%s\n", *i);
+    fprintf(candwin_w, "\n");
+    fflush(candwin_w);
+    check_connection();
+}
+
+void Canddisp::show_page(int page)
+{
+    if (!candwin_w)
+       return;
+
+    fprintf(candwin_w, "show_page\n");
+    fprintf(candwin_w, "%d\n", page);
+    fprintf(candwin_w, "\n");
+    fflush(candwin_w);
+    check_connection();
+}
+#endif /* UIM_XIM_USE_NEW_PAGE_HANDLING */
+
 void Canddisp::select(int index, bool need_hilite)
 {
     if (!candwin_w)

Modified: trunk/xim/canddisp.h
==============================================================================
--- trunk/xim/canddisp.h        (original)
+++ trunk/xim/canddisp.h        Tue Oct  7 04:26:08 2008
@@ -34,6 +34,7 @@
 #ifndef UIM_XIM_CANDDISP_H
 #define UIM_XIM_CANDDISP_H

+#include "ximserver.h"
 #include <vector>

 class Canddisp {
@@ -49,6 +50,11 @@
     void show_caret_state(const char *str, int timeout);
     void update_caret_state();
     void hide_caret_state();
+#if UIM_XIM_USE_NEW_PAGE_HANDLING
+    void set_nr_candidates(int nr, int display_limit);
+    void set_page_candidates(int page, CandList candidates);
+    void show_page(int page);
+#endif
 private:
     void check_connection();
 };

Modified: trunk/xim/main.cpp
==============================================================================
--- trunk/xim/main.cpp  (original)
+++ trunk/xim/main.cpp  Tue Oct  7 04:26:08 2008
@@ -573,7 +573,7 @@
 {
     const char *locale;

-    printf("UIM-XIM bridge. Now supporting multiple locales.\n");
+    printf("uim <-> XIM bridge. Supporting multiple locales.\n");

     get_runtime_env();


Modified: trunk/xim/ximserver.cpp
==============================================================================
--- trunk/xim/ximserver.cpp     (original)
+++ trunk/xim/ximserver.cpp     Tue Oct  7 04:26:08 2008
@@ -333,6 +333,9 @@
     mFocusedContext = this;
     createUimContext(engine);
     mCandwinActive = false;
+#if UIM_XIM_USE_NEW_PAGE_HANDLING
+    mNumCandidates = 0;
+#endif
     mNumPage = 1;
     mDisplayLimit = 0;
     mCaretStateShown = false;
@@ -802,14 +805,31 @@
 void InputContext::candidate_activate(int nr, int display_limit)
 {
     int i;
+#if !UIM_XIM_USE_NEW_PAGE_HANDLING
     const char *cand_str;
     const char *heading_label;
     uim_candidate cand[nr];
-    std::vector<const char *> candidates;
     char *str;
+#else
+    std::vector<CandList>::iterator slot_it;
+#endif
+    std::vector<const char *> candidates;
+    std::vector<const char *>::iterator it;

     Canddisp *disp = canddisp_singleton();

+    mDisplayLimit = display_limit;
+    if (display_limit)
+       mNumPage = (nr - 1) / display_limit + 1;
+#if !UIM_XIM_USE_NEW_PAGE_HANDLING
+    /* remove old data */
+    if (!active_candidates.empty()) {
+       for (it = active_candidates.begin();
+            it != active_candidates.end();
+            ++it)
+           free((char *)*it);
+    }
+    active_candidates.clear();
     for (i = 0; i < nr; i++) {
        cand[i] = uim_get_candidate(mUc, i,
                        display_limit ? i % display_limit : i);
@@ -827,14 +847,33 @@
        }
     }
     disp->activate(candidates, display_limit);
+    active_candidates = candidates;
     for (i = 0; i < nr; i++) {
        uim_candidate_free(cand[i]);
     }
+#else /* !UIM_XIM_USE_NEW_PAGE_HANDLING */
+    mNumCandidates = nr;
+    /* remove old data */
+    for (slot_it = mCandidateSlot.begin();
+        slot_it != mCandidateSlot.end();
+        ++slot_it) {
+       if (*slot_it != (CandList)0) {
+           for (it = (*slot_it).begin(); it != (*slot_it).end(); ++it)
+               free((char *)*it);
+       }
+    }
+    mCandidateSlot.clear();
+
+    /* setup dummy data */
+    for (i = 0; i < mNumPage; i++)
+       mCandidateSlot.push_back((CandList)0);
+
+    prepare_page_candidates(0);
+    disp->set_nr_candidates(nr, display_limit);
+    disp->set_page_candidates(0, mCandidateSlot[0]);
+    disp->show_page(0);
+#endif /* !UIM_XIM_USE_NEW_PAGE_HANDLING */
     mCandwinActive = true;
-    active_candidates = candidates;
-    mDisplayLimit = display_limit;
-    if (display_limit)
-       mNumPage = (nr - 1) / display_limit + 1;

     current_cand_selection = 0;
     current_page = 0;
@@ -845,14 +884,90 @@
 {
     Canddisp *disp = canddisp_singleton();

+#if !UIM_XIM_USE_NEW_PAGE_HANDLING
     disp->activate(active_candidates, mDisplayLimit);
+#else
+    prepare_page_candidates(current_page);
+    disp->set_nr_candidates(mNumCandidates, mDisplayLimit);
+    disp->set_page_candidates(current_page, mCandidateSlot[current_page]);
+    disp->show_page(current_page);
+#endif
     disp->select(current_cand_selection, need_hilite_selected_cand);
     disp->show();
 }

+#if UIM_XIM_USE_NEW_PAGE_HANDLING
+void InputContext::prepare_page_candidates(int page)
+{
+    int i;
+    int page_nr, start;
+    const char *cand_str;
+    const char *heading_label;
+    char *str;
+    CandList candidates;
+
+    if (page < 0)
+       return;
+
+    if (mCandidateSlot[page] != (CandList)0)
+       return;
+
+    start = page * mDisplayLimit;
+    if (mDisplayLimit && (mNumCandidates - start) > mDisplayLimit)
+       page_nr = mDisplayLimit;
+    else
+       page_nr = mNumCandidates - start;
+
+    uim_candidate cand[page_nr];
+
+    for (i = 0; i < page_nr; i++) {
+       cand[i] = uim_get_candidate(mUc, (i + start),
+                       mDisplayLimit ? (i + start) % mDisplayLimit :
+                                       (i + start));
+       cand_str = uim_candidate_get_cand_str(cand[i]);
+       heading_label = uim_candidate_get_heading_label(cand[i]);
+       //annotation_str = uim_candidate_get_annotation(cand[i]);
+       if (cand_str && heading_label) {
+           str = (char *)malloc(strlen(cand_str) + strlen(heading_label) + 2);
+           sprintf(str, "%s\t%s", heading_label, cand_str);
+           candidates.push_back((const char *)str);
+       }
+       else {
+           fprintf(stderr, "Warning: cand_str at %d is NULL\n", i);
+           candidates.push_back((const char *)strdup("\t"));
+       }
+    }
+
+    for (i = 0; i < page_nr; i++)
+       uim_candidate_free(cand[i]);
+
+    mCandidateSlot[page] = candidates;
+}
+
+int InputContext::prepare_page_candidates_by_index(int index)
+{
+    int page;
+
+    page = mDisplayLimit ? index / mDisplayLimit : 0;
+    prepare_page_candidates(page);
+
+    return page;
+}
+#endif
+
 void InputContext::candidate_select(int index)
 {
     Canddisp *disp = canddisp_singleton();
+
+#if UIM_XIM_USE_NEW_PAGE_HANDLING
+    int new_page = prepare_page_candidates_by_index(index);
+
+    if (new_page < 0)
+       return; // shouldn't happen
+
+    if (current_page != new_page)
+       disp->set_page_candidates(new_page, mCandidateSlot[new_page]);
+#endif
     disp->select(index, need_hilite_selected_cand);
     current_cand_selection = index;
     if (mDisplayLimit)
@@ -879,10 +994,20 @@

new_index = (current_page * mDisplayLimit) + (current_cand_selection % mDisplayLimit);

+#if !UIM_XIM_USE_NEW_PAGE_HANDLING
        if (new_index >= active_candidates.size())
            current_cand_selection = active_candidates.size() - 1;
+#else
+       if (new_index >= mNumCandidates)
+           current_cand_selection = mNumCandidates - 1;
+#endif
        else
            current_cand_selection = new_index;
+#if UIM_XIM_USE_NEW_PAGE_HANDLING
+       Canddisp *disp = canddisp_singleton();
+       prepare_page_candidates(current_page);
+       disp->set_page_candidates(current_page, mCandidateSlot[current_page]);
+#endif
     }
     candidate_select(current_cand_selection);
     if (need_hilite_selected_cand)
@@ -896,9 +1021,24 @@
        Canddisp *disp = canddisp_singleton();

        disp->deactivate();
+#if !UIM_XIM_USE_NEW_PAGE_HANDLING
        for (i = active_candidates.begin(); i != active_candidates.end(); ++i) {
            free((char *)*i);
        }
+       active_candidates.clear();
+#else
+       int j;
+       for (j = 0; j < mNumPage; j++) {
+           if ((CandList)mCandidateSlot[j] != (CandList)0) {
+               for (i = mCandidateSlot[j].begin();
+                    i != mCandidateSlot[j].end();
+                    ++i) {
+                   free((char *)*i);
+               }
+           }
+       }
+       mCandidateSlot.clear();
+#endif
        mCandwinActive = false;
        current_cand_selection = 0;
     }

Modified: trunk/xim/ximserver.h
==============================================================================
--- trunk/xim/ximserver.h       (original)
+++ trunk/xim/ximserver.h       Tue Oct  7 04:26:08 2008
@@ -44,6 +44,7 @@
 #include "uim/uim.h"
 #include "compose.h"

+#define UIM_XIM_USE_NEW_PAGE_HANDLING 1

 // preedit ornament
 #define PE_NORMAL 0
@@ -53,6 +54,9 @@

 typedef wchar_t uchar;
 typedef std::list<uchar> uString;
+#if UIM_XIM_USE_NEW_PAGE_HANDLING
+typedef std::vector<const char *> CandList;
+#endif
 struct pe_ustring {
     uString s;
     int stat;
@@ -169,6 +173,10 @@
     void candidate_shift_page(int direction);
     void candidate_deactivate();
     void candidate_update();
+#if UIM_XIM_USE_NEW_PAGE_HANDLING
+    void prepare_page_candidates(int page);
+    int prepare_page_candidates_by_index(int index);
+#endif
     void update_prop_list(const char *str);
     void update_prop_label(const char *str);
     bool hasActiveCandwin();
@@ -210,12 +218,18 @@
     Convdisp *mConvdisp;
     uim_context mUc;
     bool mCandwinActive;
-    int mDisplayLimit;
+    uint mDisplayLimit;
+#if UIM_XIM_USE_NEW_PAGE_HANDLING
+    uint mNumCandidates;
+#endif
     int mNumPage;
     int current_cand_selection;
     int current_page;
     bool need_hilite_selected_cand;
     std::vector<const char *> active_candidates;
+#if UIM_XIM_USE_NEW_PAGE_HANDLING
+    std::vector<CandList> mCandidateSlot;
+#endif
     char *mEngineName;
     char *mLocaleName;
     bool mCaretStateShown;

Reply via email to