[uim-commit] r1256 - branches/0.4/xim

ekato at freedesktop.org ekato at freedesktop.org
Sun Aug 21 13:41:16 EST 2005


Author: ekato
Date: 2005-08-20 20:41:14 -0700 (Sat, 20 Aug 2005)
New Revision: 1256

Modified:
   branches/0.4/xim/canddisp.cpp
   branches/0.4/xim/convdisp.cpp
   branches/0.4/xim/convdisp.h
   branches/0.4/xim/main.cpp
   branches/0.4/xim/xim.h
   branches/0.4/xim/ximic.cpp
   branches/0.4/xim/ximserver.cpp
   branches/0.4/xim/ximserver.h
Log:
* xim/ : Backport "candidate-window-position" support from trunk
  (r1252).


Modified: branches/0.4/xim/canddisp.cpp
===================================================================
--- branches/0.4/xim/canddisp.cpp	2005-08-21 03:38:06 UTC (rev 1255)
+++ branches/0.4/xim/canddisp.cpp	2005-08-21 03:41:14 UTC (rev 1256)
@@ -39,6 +39,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 #include <errno.h>
+#include <fcntl.h>
 
 #include "uim/uim.h"
 #ifdef UIM_COMPAT_SCM
@@ -56,6 +57,7 @@
 static int candwin_pid;
 static Canddisp *disp;
 static const char *command;
+static bool candwin_inited = false;
 
 static void candwin_read_cb(int fd, int ev);
 
@@ -96,12 +98,21 @@
     if (!command)
 	command = candwin_command();
 
-    if (!disp && command) {
+    if (!candwin_inited && command) {
 	candwin_pid = uim_ipc_open_command(candwin_pid, &candwin_r, &candwin_w, command);
+	if (disp)
+	    delete disp;
 	disp = new Canddisp();
 	int fd = fileno(candwin_r);
-	if (fd != -1)
-	    add_fd_watch(fd, READ_OK, candwin_read_cb);
+	if (fd != -1) {
+	    int flag = fcntl(fd, F_GETFL);
+	    if (flag != -1) {
+		flag |= O_NONBLOCK;
+		if (fcntl(fd, F_SETFL, flag) != -1)
+		    add_fd_watch(fd, READ_OK, candwin_read_cb);
+	    }
+	}
+	candwin_inited = true;
     }
     return disp;
 }
@@ -210,12 +221,8 @@
 
 void Canddisp::check_connection()
 {
-    if (errno == EBADF || errno == EPIPE) {
-	disp = NULL;
-	int fd = fileno(candwin_r);
-	remove_current_fd_watch(fd);
-	delete this;
-    }
+    if (errno == EBADF || errno == EPIPE)
+	terminate_canddisp_connection();
 }
 
 static void candwin_read_cb(int fd, int ev)
@@ -225,11 +232,7 @@
 
     n = read(fd, buf, 1024 - 1);
     if (n == 0) {
-	int fd_w = fileno(candwin_w);
-	if (fd != -1)
-	    close(fd_w);
-	close(fd);
-	remove_current_fd_watch(fd);
+	terminate_canddisp_connection();
 	return;
     }
     if (n == -1)
@@ -237,11 +240,7 @@
     buf[n] = '\0';
 
     if (!strcmp(buf, "err")) {
-	int fd_w = fileno(candwin_w);
-	if (fd != -1)
-	    close(fd_w);
-	close(fd);
-	remove_current_fd_watch(fd);
+	terminate_canddisp_connection();
 	return;
     }
 
@@ -283,6 +282,7 @@
 	close(fd_w);
     }
 
-    disp = NULL;
+    candwin_w = candwin_r = NULL;
+    candwin_inited = false;
     return;
 }

Modified: branches/0.4/xim/convdisp.cpp
===================================================================
--- branches/0.4/xim/convdisp.cpp	2005-08-21 03:38:06 UTC (rev 1255)
+++ branches/0.4/xim/convdisp.cpp	2005-08-21 03:41:14 UTC (rev 1256)
@@ -229,6 +229,7 @@
     virtual ~PeLineWin();
 
     void draw_pe(pe_stat *p);
+    int mCandWinXOff;
 
 private:
     void calc_extent(pe_stat *p);
@@ -265,8 +266,6 @@
     virtual void clear_preedit();
     virtual void update_icxatr();
     virtual void move_candwin();
-    virtual void update_caret_state();
-    virtual void set_im_lang(const char *im_lang);
     virtual bool use_xft();
 private:
     bool check_win();
@@ -284,6 +283,8 @@
 
     char_ent *m_ce;
     int m_ce_len;
+    int m_candwin_x_off;
+    int m_candwin_y_off;
     PeOvWin *m_ov_win;
 };
 
@@ -297,7 +298,6 @@
     virtual void clear_preedit();
     virtual void update_icxatr();
     virtual void move_candwin();
-    virtual void update_caret_state();
     virtual bool use_xft();
 private:
     PeLineWin *mPeWin;
@@ -311,7 +311,6 @@
     virtual void clear_preedit();
     virtual void update_icxatr();
     virtual void move_candwin();
-    virtual void update_caret_state();
     virtual bool use_xft();
 
 private:
@@ -747,6 +746,19 @@
 	if (mCharPos == caret_pos)
 	    mCursorX= m_x;
     }
+
+    switch (XimServer::gCandWinPosType) {
+    case Caret:
+	mCandWinXOff = mCursorX;
+	break;
+    case Right:
+	mCandWinXOff = m_x;
+	break;
+    case Left:
+    default:
+	mCandWinXOff = 0;
+	break;
+    }
 }
 
 int PeLineWin::calc_segment_extent(pe_ustring *s)
@@ -937,6 +949,19 @@
     return m_pe->caret_pos;
 }
 
+void Convdisp::update_caret_state()
+{
+    Canddisp *disp = canddisp_singleton();
+    InputContext *focusedContext = InputContext::focusedContext();
+
+    if (focusedContext && focusedContext == mKkContext) {
+	if (mKkContext->isCaretStateShown())
+	    disp->update_caret_state();
+	else
+	    disp->hide_caret_state();
+    }
+}
+
 // Root window style
 ConvdispRw::ConvdispRw(InputContext *k, icxatr *a) : Convdisp(k, a)
 {
@@ -956,6 +981,7 @@
 
     if (!m_pe->get_char_count()) {
 	clear_preedit();
+	move_candwin(); // reset candwin position
 	return;
     }
 
@@ -990,12 +1016,12 @@
 {
 }
 
-void ConvdispRw::update_caret_state()
+void ConvdispRw::move_candwin()
 {
-}
+    InputContext *focusedContext = InputContext::focusedContext();
+    if (!focusedContext || focusedContext != mKkContext)
+	return;
 
-void ConvdispRw::move_candwin()
-{
     if (m_atr->has_atr(ICA_ClientWindow)) {
 	int x, y;
 	Window win;
@@ -1008,6 +1034,9 @@
 	Canddisp *disp = canddisp_singleton();
 
 	XGetWindowAttributes(XimServer::gDpy, m_atr->client_window, &xattr);
+
+	if (mPeWin)
+	    x += mPeWin->mCandWinXOff;
 	disp->move(x, y + xattr.height + 28); // lower-left side under the preedit window
     }
 }
@@ -1021,6 +1050,8 @@
 ConvdispOv::ConvdispOv(InputContext *k, icxatr *a) : Convdisp(k, a)
 {
     m_ov_win = 0;
+    m_candwin_x_off = 0;
+    m_candwin_y_off = 0;
 #ifdef FLASHPLAYER_WORKAROUND
     revised_spot_y = -1;
 #endif
@@ -1032,32 +1063,18 @@
 	delete m_ov_win;
 }
 
-void ConvdispOv::set_im_lang(const char *im_lang)
-{
-    mIMLang = im_lang;
-}
-
-
 void ConvdispOv::update_preedit()
 {
     draw_preedit();
     move_candwin();
 }
 
-void ConvdispOv::update_caret_state()
+void ConvdispOv::move_candwin()
 {
-    Canddisp *disp = canddisp_singleton();
     InputContext *focusedContext = InputContext::focusedContext();
+    if (!focusedContext || focusedContext != mKkContext)
+	return;
 
-    if (focusedContext && focusedContext == mKkContext) {
-	move_candwin();
-	disp->update_caret_state();
-	m_atr->unset_change_mask(ICA_SpotLocation);
-    }
-}
-
-void ConvdispOv::move_candwin()
-{
     if (m_atr->has_atr(ICA_SpotLocation) ) {
 	int x = -1, y = -1;
 	Window win;
@@ -1089,8 +1106,12 @@
 	}
 #endif
 	if (x > -1 && y > -1) {
+	    x += m_candwin_x_off;
+	    y += m_candwin_y_off;
+
 	    Canddisp *disp = canddisp_singleton();
 	    disp->move(x, y + UNDERLINE_HEIGHT + 1);
+	    m_atr->unset_change_mask(ICA_SpotLocation);
 	}
 #if 0
     } else if (m_atr->has_atr(ICA_SpotLocation)) {
@@ -1113,6 +1134,8 @@
 {
     delete m_ov_win;
     m_ov_win = NULL;
+    m_candwin_x_off = 0;
+    m_candwin_y_off = 0;
 }
 
 void ConvdispOv::validate_area()
@@ -1136,6 +1159,7 @@
 {
 
     if (m_atr->is_changed(ICA_SpotLocation)) {
+	move_candwin();
 	uim_bool  show_caret_state = uim_scm_symbol_value_bool("bridge-show-input-state?");
 	if (show_caret_state == UIM_TRUE)
 	    update_caret_state();
@@ -1176,10 +1200,9 @@
 	m_atr->unset_change_mask(ICA_FontSet);
     }
   
-    if (m_atr->is_changed(ICA_SpotLocation)) {
+    if (m_atr->is_changed(ICA_SpotLocation))
 	move_candwin();
-	m_atr->unset_change_mask(ICA_SpotLocation);
-    }
+
     draw_preedit();
 }
 
@@ -1381,6 +1404,8 @@
 {
     int i;
     int x, y;
+    int caret_pos = get_caret_pos();
+    int right_limit = m_atr->area.width + m_atr->area.x;
 
     x = m_atr->spot_location.x;
     y = m_atr->spot_location.y;
@@ -1425,30 +1450,38 @@
 	    }
 	}
 
-	int right_limit = m_atr->area.width;
-	if (m_atr->has_atr(ICA_Area))
-	    right_limit += m_atr->area.x;
-
-	if (m_ce[i].width + x >
-	    right_limit) {
+	if (m_ce[i].width + x > right_limit) {
 	    // goto next line
 	    x = m_atr->area.x;
-	    y += m_atr->line_space;
+	    y += (m_atr->line_space + UNDERLINE_HEIGHT);
 	}
-	m_ce[i].x = x;
-	m_ce[i].y = y;
+	m_ce[i].x = x - m_atr->area.x;
+	m_ce[i].y = y - m_atr->area.y;
+#ifdef FLASHPLAYER_WORKAROUND
+	// workaround for brain damaged flash player plugin
+	if (m_ce[i].y == 0)
+	    m_ce[i].y += m_ce[i].height;
+#endif
 	x += m_ce[i].width;
     }
-    if (m_atr->has_atr(ICA_Area)) {
-	for (i = 0; i < m_ce_len; i++) {
-	    m_ce[i].x -= m_atr->area.x;
-	    m_ce[i].y -= m_atr->area.y;
-#ifdef FLASHPLAYER_WORKAROUND
-	    // workaround for brain damaged flash player plugin
-	    if (m_ce[i].y == 0)
-		m_ce[i].y += m_ce[i].height;
-#endif
+
+    switch (XimServer::gCandWinPosType) {
+    case Caret:
+	if (caret_pos == 0) {
+	    m_candwin_x_off = m_ce[caret_pos].x - m_atr->spot_location.x;
+	    m_candwin_y_off = m_ce[caret_pos].y - m_atr->spot_location.y;
+	} else {
+	    m_candwin_x_off = m_ce[caret_pos - 1].x + m_ce[caret_pos - 1].width - m_atr->spot_location.x;
+	    m_candwin_y_off = m_ce[caret_pos - 1].y - m_atr->spot_location.y;
 	}
+	break;
+    case Right:
+	m_candwin_x_off = m_ce[m_ce_len - 1].x + m_ce[m_ce_len - 1].width - m_atr->spot_location.x;
+	m_candwin_y_off = m_ce[m_ce_len - 1].y - m_atr->spot_location.y;
+	break;
+    case Left:
+    default:
+	break;
     }
 }
 
@@ -1541,12 +1574,12 @@
     }
 }
 
-void ConvdispOs::update_caret_state()
+void ConvdispOs::move_candwin()
 {
-}
+    InputContext *focusedContext = InputContext::focusedContext();
+    if (!focusedContext || focusedContext != mKkContext)
+	return;
 
-void ConvdispOs::move_candwin()
-{
     if (m_atr->has_atr(ICA_ClientWindow)) {
 	int x, y;
 	Window win;

Modified: branches/0.4/xim/convdisp.h
===================================================================
--- branches/0.4/xim/convdisp.h	2005-08-21 03:38:06 UTC (rev 1255)
+++ branches/0.4/xim/convdisp.h	2005-08-21 03:41:14 UTC (rev 1256)
@@ -49,11 +49,11 @@
     void unset_focus();
     InputContext *get_context();
     int get_caret_pos();
+    void update_caret_state();
     virtual void update_preedit() = 0;
     virtual void clear_preedit() = 0;
     virtual void update_icxatr() = 0;
     virtual void move_candwin() = 0;
-    virtual void update_caret_state() = 0;
     virtual void set_im_lang(const char *im_lang);
     virtual void set_locale_name(const char *locale);
     virtual const char *get_locale_name();

Modified: branches/0.4/xim/main.cpp
===================================================================
--- branches/0.4/xim/main.cpp	2005-08-21 03:38:06 UTC (rev 1255)
+++ branches/0.4/xim/main.cpp	2005-08-21 03:41:14 UTC (rev 1256)
@@ -61,6 +61,7 @@
 
 Display *XimServer::gDpy;
 std::map<Window, XimServer *> XimServer::gServerMap;
+CandWinPosType XimServer::gCandWinPosType;
 
 // Configuration
 int g_option_mask;
@@ -538,10 +539,6 @@
 	}
     }
 
-    InputContext *focusedContext = InputContext::focusedContext();
-    if (focusedContext)
-	focusedContext->focusIn();
-
     pretrans_setup();
 }
 
@@ -618,6 +615,7 @@
     if (uim_scm_symbol_value_bool("uim-xim-use-xft-font?"))
 	init_default_xftfont(); // setup Xft fonts for Ov/Rw preedit
 #endif
+    check_candwin_pos_type();
 
     // Handle pending events to prevent hang just after startup
     check_pending_xevent();

Modified: branches/0.4/xim/xim.h
===================================================================
--- branches/0.4/xim/xim.h	2005-08-21 03:38:06 UTC (rev 1255)
+++ branches/0.4/xim/xim.h	2005-08-21 03:41:14 UTC (rev 1256)
@@ -291,7 +291,6 @@
     void changeContext(const char *engine);
     const char *get_encoding();
     const char *get_lang_region();
-    void move_candwin();
 
 public:
     static XimIC *get_current_ic();
@@ -308,7 +307,7 @@
     void send_sync();
     
     Connection *mConn;
-    // mConvdisp is 0 until getting enough icxatr.  Need to delete
+    // mConvdisp is NULL until getting enough icxatr.  Need to delete
     // this after deletion of m_kkContext since it is also refered by
     // m_kkContext.
     Convdisp *mConvdisp;

Modified: branches/0.4/xim/ximic.cpp
===================================================================
--- branches/0.4/xim/ximic.cpp	2005-08-21 03:38:06 UTC (rev 1255)
+++ branches/0.4/xim/ximic.cpp	2005-08-21 03:41:14 UTC (rev 1256)
@@ -345,7 +345,7 @@
     const char *locale = m_kkContext->get_locale_name();
     m_xatr.set_locale_name(locale);
 
-    mConvdisp = 0;
+    mConvdisp = NULL;
     m_keyState = new keyState(this);
     if (g_option_mask & OPT_TRACE)
 	printf("imid=%d, icid=%d ic created.\n", mIMid, mICid);
@@ -382,12 +382,6 @@
     return mIMid;
 }
 
-void XimIC::move_candwin()
-{
-    if (mConvdisp)
-	mConvdisp->move_candwin();
-}
-
 void XimIC::setFocus()
 {
     if (!mIsActive)
@@ -403,7 +397,6 @@
 	mConvdisp->unset_focus();
     }
 
-    mConvdisp->move_candwin();
     m_kkContext->focusIn();
 
     if (mConvdisp && is_candwin_active == true) {

Modified: branches/0.4/xim/ximserver.cpp
===================================================================
--- branches/0.4/xim/ximserver.cpp	2005-08-21 03:38:06 UTC (rev 1255)
+++ branches/0.4/xim/ximserver.cpp	2005-08-21 03:41:14 UTC (rev 1256)
@@ -156,10 +156,12 @@
 
     if (!strcmp(custom, "bridge-show-input-state?") &&
 		    !uim_scm_symbol_value_bool("bridge-show-input-state?")) {
-	    Canddisp *disp = canddisp_singleton();
-	    disp->hide_caret_state();
+	Canddisp *disp = canddisp_singleton();
+	disp->hide_caret_state();
     }
 
+    if (!strcmp(custom, "candidate-window-position"))
+	check_candwin_pos_type();
 }
 
 bool
@@ -285,7 +287,7 @@
 {
     mXic = ic;
     m_pe = new pe_stat(this);
-    mConvdisp = 0;
+    mConvdisp = NULL;
     mServer = svr;
     mEngineName = NULL;
     mLocaleName = NULL;
@@ -294,6 +296,7 @@
     mCandwinActive = false;
     mNumPage = 1;
     mDisplayLimit = 0;
+    mCaretStateShown = false;
 }
 
 InputContext::~InputContext()
@@ -436,6 +439,10 @@
     check_helper_connection();
     uim_helper_client_focus_in(mUc);
     mFocusedContext = this;
+    if (mConvdisp) {
+	mConvdisp->move_candwin();
+	mConvdisp->update_caret_state();
+    }
     uim_prop_list_update(mUc);	
     uim_prop_label_update(mUc);	
 }
@@ -764,6 +771,7 @@
 	int timeout = uim_scm_symbol_value_int("bridge-show-input-state-time-length");
 	Canddisp *disp = canddisp_singleton();
 	disp->show_caret_state(str, timeout);
+	mCaretStateShown = true;
     }
 }
 
@@ -777,6 +785,11 @@
     return mLocaleName;
 }
 
+bool InputContext::isCaretStateShown()
+{
+    return mCaretStateShown;
+}
+
 keyState::keyState(XimIC *ic)
 {
     XimIM *im;
@@ -1072,6 +1085,22 @@
     gMod5Mask = check_modifier(Mod5MaskSyms);
 }
 
+
+void
+check_candwin_pos_type()
+{
+    char *candwin_pos_type = uim_scm_symbol_value_str("candidate-window-position");
+
+    if (candwin_pos_type && !strcmp(candwin_pos_type, "left"))
+	XimServer::gCandWinPosType = Left;
+    else if (candwin_pos_type && !strcmp(candwin_pos_type, "right"))
+	XimServer::gCandWinPosType = Right;
+    else
+	XimServer::gCandWinPosType = Caret;
+
+    free(candwin_pos_type);
+}
+
 /*
  * Local variables:
  *  c-indent-level: 4

Modified: branches/0.4/xim/ximserver.h
===================================================================
--- branches/0.4/xim/ximserver.h	2005-08-21 03:38:06 UTC (rev 1255)
+++ branches/0.4/xim/ximserver.h	2005-08-21 03:41:14 UTC (rev 1256)
@@ -57,6 +57,11 @@
     uString s;
     int stat;
 };
+typedef enum {
+    Caret,
+    Left,
+    Right
+} CandWinPosType;
 
 // state of preedit.
 // created in the constructor of InputContext, and deleted in the
@@ -84,6 +89,7 @@
 void init_default_xftfont();
 void update_default_xftfont();
 #endif
+void check_candwin_pos_type();
 
 
 // for command line option
@@ -168,6 +174,7 @@
     void update_prop_list(const char *str);
     void update_prop_label(const char *str);
     bool hasActiveCandwin();
+    bool isCaretStateShown();
     const char *get_engine_name();
     const char *get_locale_name();
     void changeContext(const char *engine);
@@ -203,6 +210,7 @@
     std::vector<const char *> active_candidates;
     char *mEngineName;
     char *mLocaleName;
+    bool mCaretStateShown;
 };
 
 class Locale {
@@ -243,6 +251,7 @@
     static XimServer *findServer(Window w);
     static Display *gDpy;
     static std::map<Window, XimServer *> gServerMap;
+    static CandWinPosType gCandWinPosType;
 private:
     Window mSelectionWin;
     Atom mServerAtom;



More information about the uim-commit mailing list