一半君的总结纸

听话只听一半君

centos 7 安装 fcitx (为了能在Sublime Text 3里敲中文)

为了在sublime text 3里输中文 … orz

repo里找不到,所以只好…

fcitx的乱搞部分

# 准备
yum install enchant-devel iso-codes-devel opencc-devel gobject-introspection-devel

# 似乎需要这个
wget http://downloads.sourceforge.net/project/presage/presage/0.8.9/presage-0.8.9.tar.gz
tar xvf presage-0.8.9.tar.gz
cd presage-0.8.9
./configure
make
make install

# lz也忘了先后顺序了
wget http://download.fcitx-im.org/fcitx/fcitx-4.2.8.4.tar.xz
tar -xvf fcitx-4.2.8.4.tar.xz
cd fcitx-4.2.8.4
mkdir build && cd build
cmake .. # -DCMAKE_INSTALL_PREFIX=
make
make install

# 这个是configure的gui
git clone https://github.com/fcitx/kcm-fcitx.git
cd kcm-fcitx
mkdir build && cd build
cmake ..
make && make install

# 好像这个也是
git clone https://github.com/fcitx/fcitx-configtool.git
cd fcitx-configtool
mkdir build && cd build
cmake ..
make && make install

# 乱搞装拼音
yum install libpinyin libpinyin-devel libpinyin-tools libpinyin-data
git clone https://github.com/fcitx/fcitx-libpinyin.git
cd fcitx-libpinyin
mkdir build && cd build
cmake ..
make && make install

此外lz还创建了/etc/X11/xinit/xinput.d/fcitx.conf 其内容是

XIM=fcitx  
XIM_PROGRAM=/usr/local/bin/fcitx  
XIM_ARGS=”-d”  
GTK_IM_MODULE=fcitx  
QT_IM_MODULE=fcitx 

以下不知道是不是必要操作

mv /etc/alternatives/xinputrc /etc/alternatives/xinputrc.bak 
ln -s /etc/X11/xinit/xinput.d/fcitx.conf /etc/alternatives/xinputrc
export XIM=fcitx  
export GTK_IM_MODULE=xim  
export XMODIFIERS=@im=fcitx  
export QT_IM_MODULE=fcitx

最后 Settings -> Input Method Selector 里选 Fcitx 即可
im_selector

Sublime Text 3的乱搞部分

/*
sublime-imfix.c
Use LD_PRELOAD to interpose some function to fix sublime input method support for linux.
By Cjacker Huang <jianzhong.huang at i-soft.com.cn>
By whitequark@whitequark.org

How to compile:
gcc -shared -o libsublime-imfix.so sublime_imfix.c  `pkg-config --libs --cflags gtk+-2.0` -fPIC
How to use:
LD_PRELOAD=./libsublime-imfix.so sublime_text

Changes:
2014 06-09
1, Fix cursor position update for sublime text 3.
2, Combine the codes from whitequark(fix for xim immodule) and add cursor update support for XIM immodule.
*/

/*for RTLD_NEXT*/
#define _GNU_SOURCE

#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <assert.h>
#include <dlfcn.h>
#include <stdio.h>
#include <string.h>
#include <gtk/gtk.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

#ifdef VERBOSE
#define DEBUG(fmt, ...) do { \
    FILE* err = fopen("/tmp/libsublime-immethod-fix.log", "a"); \
    if (err) { \
      fprintf(err, fmt, __VA_ARGS__); \
      fclose(err); \
    } \
  } while(0)
#else
#define DEBUG(fmt, ...)
#endif


typedef GdkSegment GdkRegionBox;

struct _GdkRegion
{
  long size;
  long numRects;
  GdkRegionBox *rects;
  GdkRegionBox extents;
};

GtkIMContext *local_context;


//this func is interposed to support cursor position update.
void
gdk_region_get_clipbox (const GdkRegion *region,
            GdkRectangle    *rectangle)
{
  g_return_if_fail (region != NULL);
  g_return_if_fail (rectangle != NULL);

  rectangle->x = region->extents.x1;
  rectangle->y = region->extents.y1;
  rectangle->width = region->extents.x2 - region->extents.x1;
  rectangle->height = region->extents.y2 - region->extents.y1;
  GdkRectangle rect;
  rect.x = rectangle->x;
  rect.y = rectangle->y;
  rect.width = 0;
  rect.height = rectangle->height;
  //The caret width is 2 in sublime text 2
  //And is 1 in sublime text 3.
  //Maybe sometimes we will make a mistake, but for most of the time, it should be the caret.
  if((rectangle->width == 2 || rectangle->width == 1)  && GTK_IS_IM_CONTEXT(local_context)) {
        gtk_im_context_set_cursor_location(local_context, rectangle);
  }
}

//this is needed, for example, if you input something in file dialog and return back the edit area
//context will lost, so here we set it again.
static GdkFilterReturn event_filter (GdkXEvent *xevent, GdkEvent *event, gpointer im_context)
{
    XEvent *xev = (XEvent *)xevent;
    if(xev->type == KeyRelease && GTK_IS_IM_CONTEXT(im_context)) {
       GdkWindow * win = g_object_get_data(G_OBJECT(im_context),"window");
       if(GDK_IS_WINDOW(win))
         gtk_im_context_set_client_window(im_context, win);
    }
    return GDK_FILTER_CONTINUE;
}

void gtk_im_context_set_client_window (GtkIMContext *context,
          GdkWindow    *window)
{
    GtkIMContextClass *klass;
    g_return_if_fail (GTK_IS_IM_CONTEXT (context));
    klass = GTK_IM_CONTEXT_GET_CLASS (context);
    if (klass->set_client_window)
        klass->set_client_window (context, window);

    //below is our interposed codes to save the context to local_context.
    if(!GDK_IS_WINDOW (window))
        return;
    g_object_set_data(G_OBJECT(context),"window",window);
    int width = gdk_window_get_width(window);
    int height = gdk_window_get_height(window);
    if(width != 0 && height !=0) {
        gtk_im_context_focus_in(context);
        local_context = context;
    }
    //only add this event_filter when using 'fcitx' immodule.
    //for xim immodule, this function is as same as original from gtk2.
    const gchar * immodule = g_getenv("GTK_IM_MODULE");
    if(immodule && !strcmp(immodule, "fcitx")) {
        gdk_window_add_filter (window, event_filter, context);
    }
}


/*below codes is from whitequark, fix for xim immodule*/

/* See gtkimcontextxim.c */
GType gtk_type_im_context_xim = 0;

#define GTK_TYPE_IM_CONTEXT_XIM            (gtk_type_im_context_xim)
#define GTK_IM_CONTEXT_XIM(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_IM_CONTEXT_XIM, GtkIMContextXIM))
#define GTK_IM_CONTEXT_XIM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_IM_CONTEXT_XIM, GtkIMContextXIMClass))
#define GTK_IS_IM_CONTEXT_XIM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_IM_CONTEXT_XIM))
#define GTK_IS_IM_CONTEXT_XIM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_IM_CONTEXT_XIM))
#define GTK_IM_CONTEXT_XIM_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_IM_CONTEXT_XIM, GtkIMContextXIMClass))

typedef struct _GtkIMContextXIM       GtkIMContextXIM;
typedef struct _GtkIMContextXIMClass  GtkIMContextXIMClass;

struct _GtkIMContextXIMClass
{
  GtkIMContextClass parent_class;
};

typedef struct _StatusWindow StatusWindow;
typedef struct _GtkXIMInfo GtkXIMInfo;

struct _GtkIMContextXIM
{
  GtkIMContext object;

  GtkXIMInfo *im_info;

  gchar *locale;
  gchar *mb_charset;

  GdkWindow *client_window;
  GtkWidget *client_widget;

  /* The status window for this input context; we claim the
*    * status window when we are focused and have created an XIC
*       */
  StatusWindow *status_window;

  gint preedit_size;
  gint preedit_length;
  gunichar *preedit_chars;
  XIMFeedback *feedbacks;

  gint preedit_cursor;

  XIMCallback preedit_start_callback;
  XIMCallback preedit_done_callback;
  XIMCallback preedit_draw_callback;
  XIMCallback preedit_caret_callback;

  XIMCallback status_start_callback;
  XIMCallback status_done_callback;
  XIMCallback status_draw_callback;

  XIMCallback string_conversion_callback;

  XIC ic;

  guint filter_key_release : 1;
  guint use_preedit : 1;
  guint finalizing : 1;
  guint in_toplevel : 1;
  guint has_focus : 1;
};

static GClassInitFunc orig_gtk_im_context_xim_class_init;
static GType (*orig_g_type_module_register_type)(GTypeModule *,
                                                 GType, const gchar *,
                                                 const GTypeInfo *, GTypeFlags);
static gboolean (*orig_gtk_im_context_xim_filter_keypress)(GtkIMContext *context,
                                                           GdkEventKey *event);

static gboolean
hook_gtk_im_context_xim_filter_keypress(GtkIMContext *context, GdkEventKey *event) {
  GtkIMContextXIM *im_context_xim = GTK_IM_CONTEXT_XIM(context);
  if (!im_context_xim->client_window) {
    DEBUG("im_context_xim == %p\n", im_context_xim);
    DEBUG("event->window == %p\n", event->window);

    gtk_im_context_set_client_window(context, event->window);
  }

  return orig_gtk_im_context_xim_filter_keypress(context, event);
}

static void
hook_gtk_im_context_xim_class_init (GtkIMContextXIMClass *class) {
  orig_gtk_im_context_xim_class_init(class, NULL); /* wat? */

  GtkIMContextClass *im_context_class = GTK_IM_CONTEXT_CLASS (class);

  assert(!orig_gtk_im_context_xim_filter_keypress);
  orig_gtk_im_context_xim_filter_keypress = im_context_class->filter_keypress;
  im_context_class->filter_keypress = hook_gtk_im_context_xim_filter_keypress;
  DEBUG("orig_gtk_im_context_xim_filter_keypress: %p\n",
        orig_gtk_im_context_xim_filter_keypress);
}

GType
g_type_module_register_type (GTypeModule *module,
                             GType parent_type,
                             const gchar *type_name,
                             const GTypeInfo *type_info,
                             GTypeFlags flags) {
  if (!orig_g_type_module_register_type) {
    orig_g_type_module_register_type = dlsym(RTLD_NEXT, "g_type_module_register_type");
    assert(orig_g_type_module_register_type);
  }

  if (type_name && !strcmp(type_name, "GtkIMContextXIM")) {
    assert(!orig_gtk_im_context_xim_class_init);
    orig_gtk_im_context_xim_class_init = type_info->class_init;

    assert(sizeof(GtkIMContextXIM) == type_info->instance_size);

    const GTypeInfo hook_im_context_xim_info =
    {
      type_info->class_size,
      type_info->base_init,
      type_info->base_finalize,
      (GClassInitFunc) hook_gtk_im_context_xim_class_init,
      type_info->class_finalize,
      type_info->class_data,
      type_info->instance_size,
      type_info->n_preallocs,
      type_info->instance_init,
    };

    DEBUG("orig_gtk_im_context_xim_class_init: %p\n", orig_gtk_im_context_xim_class_init);

    gtk_type_im_context_xim =
      orig_g_type_module_register_type(module, parent_type, type_name,
                                       &hook_im_context_xim_info, flags);

    return gtk_type_im_context_xim;
  }

  return orig_g_type_module_register_type(module, parent_type, type_name, type_info, flags);
}

把上面这一段另存成文件 /home/fucker/.config/sublime-text-3/Packages/sublime_imfix.c,其实存哪儿都行,然后运行下面命令

gcc -shared -o libsublime-imfix.so sublime_imfix.c  `pkg-config --libs --cflags gtk+-2.0` -fPIC

就可以编译出libsublime-imfix.so,然后给sublime加个alias,比如在~/.bashrc里加上

alias sublime='LD_PRELOAD=/home/fucker/.config/sublime-text-3/Packages/libsublime-imfix.so /opt/sublime_text/sublime_text > /dev/null 2>&1 &'

st3_im

继续提升逼格,安装搜狗输入法

wget http://pinyin.sogou.com/linux/download.php?f=linux&bit=64
#双击打开,解出data.tar.xz
cd /
tar -xvf ~/Downloads/data.tar.xz
sudo cp /usr/lib/x86_64-linux-gnu/fcitx/fcitx-sogoupinyin.so  /usr/local/lib/fcitx/
chmod 755 /usr/local/lib/fcitx/fcitx-sogoupinyin.so
# 安装皮肤 
# 去这里下 http://packages.linuxdeepin.com/deepin/pool/main/f/fcitx-skins/ 同样解开

如果不想(其实不应该)像上面这样乱搞,应该

# 如果想用云拼音
git clone https://github.com/fcitx/fcitx-cloudpinyin.git
cd fcitx-cloudpinyin
mkdir build ; cd build
cmake ..
make
make install

上面乱搞装的搜狗想删掉,结果不小心把kickoff“开始菜单”里的.desktop文件都给删了,只好重装kde

# 怕进不了桌面,先开了ssh server
systemctl start sshd.service

# 然后ssh进去,因为lz当时不在电脑前
yum groupremove @kde-desktop
yum groupinstall @kde-desktop

听说应该直接用sunpinyin

# 装sunpinyin
yum install scons
git clone https://github.com/sunpinyin/sunpinyin.git
cd sunpinyin
scons #--prefix=/usr
scons install

# 装fcitx-sunpinyin
git clone https://github.com/fcitx/fcitx-sunpinyin.git
cd fcitx-sunpinyin
mkdir build && cd build
cmake ..
make 
make install

虽然不知道怎么回事,但是一顿乱设以后就有了,但是不知道如何启用sunpinyin … orz,现在用的还是默认的libpinyin

ref:
Fcitx – archLinux wiki
Development/Tutorials/KCM HowTo

Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s

%d 博主赞过: