[uim-commit] r1252 - trunk/xim

ekato at freedesktop.org ekato at freedesktop.org
Sun Aug 21 11:46:20 EST 2005


Author: ekato
Date: 2005-08-20 18:46:14 -0700 (Sat, 20 Aug 2005)
New Revision: 1252

Modified:
   trunk/xim/canddisp.cpp
   trunk/xim/convdisp.cpp
   trunk/xim/convdisp.h
   trunk/xim/main.cpp
   trunk/xim/xim.h
   trunk/xim/ximic.cpp
   trunk/xim/ximserver.cpp
   trunk/xim/ximserver.h
Log:
* xim/ : Support "candidate-window-position" option for
  over-the-spot/Root-window style, and do some refactoring on
  move_candwin().
	
* xim/xim.h (class XimIC) : Remove move_candwin().  Fix comment.
* xim/ximic.cpp (XimIM::XimIC) : Initialize mConvdisp as NULL
  explicitly.
(XimIC::move_candwin) : Removed.
(XimIC::setFocus) : Call move_candwin() in m_kkContext->focusIn().
* xim/ximserver.cpp (XimServer::customContext) : Check
  "candidate-window-position".
(XimServer::reloadConfigs) : Ditto.
(InputContext::InputContext) : Initialize mConvdisp as NULL
  explicitly.  Initialize new variable mCaretStateShow.
(InputContext::focusIn) : Call move_candwin() and
  update_caret_state() here instead of XimIC::setFocus.
(InputContext::update_prop_label) : Set mCaretStateShown if
  disp->show_caret_state() is called.
(InptuContext::isCaretStateShown) : New.
(check_candwin_pos_type) : New function to check
  "candidate-window-position" global option.
* xim/main.cpp : Add XimServer::gCandWinPosType global variable.
(reload_uim) : No need to call focusIn() for focusedContext.
(main) : Check "candidate-window-position" at a startup.
* xim/convdisp.cpp (Class PeLineWin) : Add public variable
  mCandWinXOff to support "candidate-window-position" option.
(class ConvdispOv) : Remove update_caret_state() and set_im_lang()
  virtual member.  Add m_candwin_x_off and m_candwin_y_off
  variables to support "candidate-window-position".
(class ConvdispRw) : Remove update_caret_state() virtual function.
(class ConvdispOs) : Ditto.
(PeLineWin::draw_segment) : Check candidate window position type.
(Convdisp::update_caret_state) : Combined with ConvdispOv/Rw/Os's
  virtual function.  Don't call move_candwin() in this function.
(ConvdispRw::update_preedit) : Call move_candwin() after
  clear_preedit() to reset candidate window position.
(ConvdispRw::update_caret_state) : Removed.
(ConvdispRw::move_candwin) : Don't move the window unless its
  context if focused.  Support "candidate-window-position".
(ConvdispOv::ConvdispOv) : Initialize m_candwin_x_off and
  m_candwin_y_off.
(ConvdispOv::set_im_lang) : Removed since the function is the same
  as one in the base class.
(ConvdispOv::update_caret_state) : Ditto.
(ConvdispOv::move_candwin) :  Don't move the window unless its
  context if focused.  Support "candidate-window-position".
(ConvdispOv::clear_preedit) : Reset candidate window position
  offset.
(ConvdispOv::update_icxatr) : Call move_candwin() explicitly if
  ICA_SpotLocation is changed.  unset_change_mask will be called
  in ConvdispOv::move_candwin().
(ConvdispOv::layoutCharEnt) : Simplified a bit.  Support
  "candidate-window-position".
(ConvdispOs::update_caret_state) : Removed.
(ConvdispOs::move_candwin) : Don't move the window unless its
  context if focused.
* xim/canddisp.cpp : Use nonblocking IO for candwin_r.
* xim/ximserver.h : Typedef CandwinPosType for
  "candidate-window-position".  Add check_candwin_pos_type()
  prototype.
(class InputContext) : Add new member isCaretStateShown() and
  mCaretStateShown.
(class XimServer) : Add new member gCandWinPosType.
* xim/convdisp.h (class Convdisp) : Now update_caret_state() is
  not a virtual function.


Modified: trunk/xim/canddisp.cpp
===================================================================
--- trunk/xim/canddisp.cpp	2005-08-20 23:41:56 UTC (rev 1251)
+++ trunk/xim/canddisp.cpp	2005-08-21 01:46:14 UTC (rev 1252)
@@ -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;
 }
@@ -272,7 +283,6 @@
     }
 
     candwin_w = candwin_r = NULL;
-    delete disp;
-    disp = NULL;
+    candwin_inited = false;
     return;
 }

Modified: trunk/xim/convdisp.cpp
===================================================================
--- trunk/xim/convdisp.cpp	2005-08-20 23:41:56 UTC (rev 1251)
+++ trunk/xim/convdisp.cpp	2005-08-21 01:46:14 UTC (rev 1252)
@@ -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: trunk/xim/convdisp.h
===================================================================
--- trunk/xim/convdisp.h	2005-08-20 23:41:56 UTC (rev 1251)
+++ trunk/xim/convdisp.h	2005-08-21 01:46:14 UTC (rev 1252)
@@ -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: trunk/xim/main.cpp
===================================================================
--- trunk/xim/main.cpp	2005-08-20 23:41:56 UTC (rev 1251)
+++ trunk/xim/main.cpp	2005-08-21 01:46:14 UTC (rev 1252)
@@ -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: trunk/xim/xim.h
===================================================================
--- trunk/xim/xim.h	2005-08-20 23:41:56 UTC (rev 1251)
+++ trunk/xim/xim.h	2005-08-21 01:46:14 UTC (rev 1252)
@@ -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: trunk/xim/ximic.cpp
===================================================================
--- trunk/xim/ximic.cpp	2005-08-20 23:41:56 UTC (rev 1251)
+++ trunk/xim/ximic.cpp	2005-08-21 01:46:14 UTC (rev 1252)
@@ -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: trunk/xim/ximserver.cpp
===================================================================
--- trunk/xim/ximserver.cpp	2005-08-20 23:41:56 UTC (rev 1251)
+++ trunk/xim/ximserver.cpp	2005-08-21 01:46:14 UTC (rev 1252)
@@ -159,6 +159,9 @@
 	Canddisp *disp = canddisp_singleton();
 	disp->hide_caret_state();
     }
+
+    if (!strcmp(custom, "candidate-window-position"))
+	check_candwin_pos_type();
 }
 
 void XimServer::reloadConfigs() {
@@ -183,6 +186,8 @@
 	Canddisp *disp = canddisp_singleton();
 	disp->hide_caret_state();
     }
+
+    check_candwin_pos_type();
 }
 
 bool
@@ -308,7 +313,7 @@
 {
     mXic = ic;
     m_pe = new pe_stat(this);
-    mConvdisp = 0;
+    mConvdisp = NULL;
     mServer = svr;
     mEngineName = NULL;
     mLocaleName = NULL;
@@ -317,6 +322,7 @@
     mCandwinActive = false;
     mNumPage = 1;
     mDisplayLimit = 0;
+    mCaretStateShown = false;
 }
 
 InputContext::~InputContext()
@@ -459,6 +465,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);	
 }
@@ -787,6 +797,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;
     }
 }
 
@@ -800,6 +811,11 @@
     return mLocaleName;
 }
 
+bool InputContext::isCaretStateShown()
+{
+    return mCaretStateShown;
+}
+
 keyState::keyState(XimIC *ic)
 {
     XimIM *im;
@@ -1095,6 +1111,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: trunk/xim/ximserver.h
===================================================================
--- trunk/xim/ximserver.h	2005-08-20 23:41:56 UTC (rev 1251)
+++ trunk/xim/ximserver.h	2005-08-21 01:46:14 UTC (rev 1252)
@@ -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
@@ -85,6 +90,7 @@
 void update_default_xftfont();
 #endif
 void reload_uim(int x);
+void check_candwin_pos_type();
 
 
 // for command line option
@@ -169,6 +175,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);
@@ -204,6 +211,7 @@
     std::vector<const char *> active_candidates;
     char *mEngineName;
     char *mLocaleName;
+    bool mCaretStateShown;
 };
 
 class Locale {
@@ -245,6 +253,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