리눅스 데스크톱의
한국어 입력 개요
2018.05.19
Changwoo Ryu <cwryu@debian.org>
● 단순화해서 설명합니다
하드웨어
● Intel 8042 (AT 이후, “PS/2” 키보드 컨트롤러)
○ 요즘은 one-chip으로 메인 보드 칩셋에 내장
● USB HID (Human Interface Device) class
● Bluetooth HID (Human Interface Device) profile
● 각 표준에서 정한 하드웨어 키 코드가 (또는 “hardware scancode”) 입력됨.
OS
● Linux “input” subsystem 키코드로 변환
● Documentation/input/event-codes.txt
● /usr/include/linux/input-event-codes.h
● 리눅스 드라이버에서 하드웨어 코드를 리눅스 이벤트 코드 (“event code”) 변환
● "evdev" 인터페이스를 통해 유저랜드에서 접근 (/dev/input/event0)
GUI server (xorg / wayland compositor)
● (libinput - 키보드 포함 각종 입력 처리)
● XKB - 입력된 HW/OS 의존 키 코드를 논리적 코드로 (“key symbol”) 변환
○ 사용자 설정에 따라 달라짐. 예: Dvorak 사용, 독일어 AZERTY 레이아웃 사용
○ /usr/include/xkbcommon/xkbcommon-keysyms.h
○ 이름처럼 xorg용으로 만들어졌지만 wayland에서도 계속 사용
○ 한국어용 설정도 있음 - 오른쪽 Alt/Ctrl를 한영전환/한자 키로 바꾸기
● 한글?
○ XKB_KEY_Hangul_Kiyeog 등 한글 심볼 정의가 들어 있음 (?!)
○ 하지만 사용하지 않고 한글 입력할 때도 알파벳 사용. 그렇게 하려면 한영 전환, 두벌식 세벌식
설정 등을 GUI server에서 처리해야 하는데 어려움
● 이 키 이벤트가 포커스가 있는 app으로 전달되는데..
GUI client
● 이 key event를 받아서 아무 생각 없이 symbol을 뿌리면 서양 전용 GUI가 됨
● 텍스트 입력 상황일 경우, 이 event를 “입력기”에 의뢰를 하고 결과물 텍스트를
받아옴
입력기 용어
● 입력기 (input method)
○ server - ibus 등의 입력기
○ client - 각 GUI app, 보통 GTK+같은 GUI toolkit에서 처리
● 동작
○ preedit - 입력 중인 글자
■ root - 디스플레이의 구석에 표시 - 사용자 시선 분산으로 불편
■ off-the-spot - 해당 입력 창의 한 구석에 표시 - 마찬가지로 불편
■ over-the-spot - 입력 위치 위에 겹쳐서 쓰기 - font나 style 불일치 등의 문제 흔히 발생
■ on-the-spot - client가 직접 쓰기 - 가장 이상적이지만 GUI toolkit마다 고려해야 함
○ candidate - 사전 선택, 일본어/중국어의 경우에는 고려할 게 많음
○ commit - 확정된 입력 텍스트
XIM
● X Input Method
● 1993-1994, 아직도 최후의 대안인 레가시
● 실패 이유
○ 다른 X11 명세와 마찬가지로 spec이 너무 일반적
■ root, off-the-spot, over-the-spot, on-the-spot 클라이언트별로 다른 방식을 모두 지원하자
니 위치 정보 전달, 폰트 정보 전달 등 걸림돌이 많음
■ ibus, uim도 over-the-spot, on-the-spot 정도만 구현
○ reference 코드가 (IMdkit) 완전하지 않았고 버그 많았음
○ GUI toolkit인 Motif의 구현도 버그 많았고 closed-source라 고칠 수 없었음
시나리오 - XIM
X server App XIM server
Event Event
Preedit,
Commit
IBus, UIM, FCITX 등 입력기 프레임워크
● 다국어 입력 등 편리
● GUI toolkit마다 입력기 플러그인(“immodule”)을 붙일 수 있게 되면서 용이해짐
○ gtk 2 이후, qt 3 이후
● 장점: 각각의 모듈은 각자 역할에 집중하면 됨. 통신, 툴킷, UI 등에 신경 쓸 필
요가 적음.
● 단점: 모든 입력기가 각 GUI toolkit마다 특정 입력기에 대한 고려를 하는 상황
IBus
IBus
daemon
engine
(hangul …)
ibus client
(gtk, qt)
XIM
compat
XIM client
ibus server
candidate
UI,
settings, ...
시나리오 - IBus
X /
Wayland
App IBus server
Event Event
Preedit,
Commit
GUI 서버에서 입력기 처리
● wayland 프로토콜로 이런 게 있으나.. wl_input_method, wl_input_panel,
wl_text_model
○ http://mirrors.ustc.edu.cn/kde-
application/akademy/2012/slides/Wayland_Choosing_a_Better_Input_Method_Architecture_-
_Michael_Hasselmann.pdf
○ ibus-wayland
○ weston에만 구현
● mutter/gnome-shell 3.30 / 3.28.1 부터 “gtk-text-input” 프로토콜 추가
● 직접 ibus에 연결해서 받은 결과물을 클라이언트에 전달
● gtk에 ibus immodule 필요없어지고 wayland “gtk-text-input” 지원 필요
● 장점: GUI toolkit에서 입력기 의존 처리가 필요 없음. 스크린 키보드, 필기 입력,
음성 입력 등 데스크톱 연동이 쉬움.
● 단점: 표준화가 쉽지 않음. gtk-text-input은 gtk/gnome 전용
시나리오 - IBus from GUI server
gnome-shell /
mutter
App
IBus server
Event
Preedit,
Commit
Preedit,
Commit
보너스: libhangul
● “한글 오토마타” 알고리즘 구현
● 키를 입력하면 그 상태의 commit과 preedit string 상태를 알 수 있다.
● 한자 사전 검색
HangulInputContext* hangul_ic_new(const char* keyboard);
void hangul_ic_delete(HangulInputContext *hic);
bool hangul_ic_process(HangulInputContext *hic, int ascii);
const ucschar* hangul_ic_get_preedit_string(HangulInputContext *hic);
const ucschar* hangul_ic_get_commit_string(HangulInputContext *hic);
#include <hangul.h>
#include <glib.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
HangulInputContext *ic = hangul_ic_new("2");
for (char* k = &argv[1][0]; *k; k++)
hangul_ic_process(ic, *k);
const ucschar* preedit = hangul_ic_get_preedit_string(ic);
const ucschar* commit = hangul_ic_get_commit_string(ic);
// encoding conversion and print
char *str;
str = g_ucs4_to_utf8(commit, hangul_syllable_len(commit, -1), NULL, NULL, NULL);
printf("commit: %sn", str); g_free(str);
str = g_ucs4_to_utf8(preedit, hangul_syllable_len(preedit, -1), NULL, NULL, NULL);
printf("preedit: %sn", str); g_free(str);
hangul_ic_delete(ic);
}
$ ./a.out rmsh
commit: 그
preedit: 노
$
정리
● 앞으로는?
○ 여러가지가 호환성 유지되면서 변화
○ XIM은 없어지겠지…
○ 마지막 GUI server 쪽에서 입력기에 연결하는 방식이 더 발전적
● 입력 문제는 입력기 탓만 하기에는 여러가지 엮인 소프트웨어가 많다
○ 관련된 여러가지 데스크톱 소프트웨어의 이슈와 개발 방향에 관심이 필요

Korean input overview in the linux desktop

  • 1.
    리눅스 데스크톱의 한국어 입력개요 2018.05.19 Changwoo Ryu <cwryu@debian.org>
  • 2.
  • 3.
    하드웨어 ● Intel 8042(AT 이후, “PS/2” 키보드 컨트롤러) ○ 요즘은 one-chip으로 메인 보드 칩셋에 내장 ● USB HID (Human Interface Device) class ● Bluetooth HID (Human Interface Device) profile ● 각 표준에서 정한 하드웨어 키 코드가 (또는 “hardware scancode”) 입력됨.
  • 4.
    OS ● Linux “input”subsystem 키코드로 변환 ● Documentation/input/event-codes.txt ● /usr/include/linux/input-event-codes.h ● 리눅스 드라이버에서 하드웨어 코드를 리눅스 이벤트 코드 (“event code”) 변환 ● "evdev" 인터페이스를 통해 유저랜드에서 접근 (/dev/input/event0)
  • 5.
    GUI server (xorg/ wayland compositor) ● (libinput - 키보드 포함 각종 입력 처리) ● XKB - 입력된 HW/OS 의존 키 코드를 논리적 코드로 (“key symbol”) 변환 ○ 사용자 설정에 따라 달라짐. 예: Dvorak 사용, 독일어 AZERTY 레이아웃 사용 ○ /usr/include/xkbcommon/xkbcommon-keysyms.h ○ 이름처럼 xorg용으로 만들어졌지만 wayland에서도 계속 사용 ○ 한국어용 설정도 있음 - 오른쪽 Alt/Ctrl를 한영전환/한자 키로 바꾸기 ● 한글? ○ XKB_KEY_Hangul_Kiyeog 등 한글 심볼 정의가 들어 있음 (?!) ○ 하지만 사용하지 않고 한글 입력할 때도 알파벳 사용. 그렇게 하려면 한영 전환, 두벌식 세벌식 설정 등을 GUI server에서 처리해야 하는데 어려움 ● 이 키 이벤트가 포커스가 있는 app으로 전달되는데..
  • 6.
    GUI client ● 이key event를 받아서 아무 생각 없이 symbol을 뿌리면 서양 전용 GUI가 됨 ● 텍스트 입력 상황일 경우, 이 event를 “입력기”에 의뢰를 하고 결과물 텍스트를 받아옴
  • 7.
    입력기 용어 ● 입력기(input method) ○ server - ibus 등의 입력기 ○ client - 각 GUI app, 보통 GTK+같은 GUI toolkit에서 처리 ● 동작 ○ preedit - 입력 중인 글자 ■ root - 디스플레이의 구석에 표시 - 사용자 시선 분산으로 불편 ■ off-the-spot - 해당 입력 창의 한 구석에 표시 - 마찬가지로 불편 ■ over-the-spot - 입력 위치 위에 겹쳐서 쓰기 - font나 style 불일치 등의 문제 흔히 발생 ■ on-the-spot - client가 직접 쓰기 - 가장 이상적이지만 GUI toolkit마다 고려해야 함 ○ candidate - 사전 선택, 일본어/중국어의 경우에는 고려할 게 많음 ○ commit - 확정된 입력 텍스트
  • 8.
    XIM ● X InputMethod ● 1993-1994, 아직도 최후의 대안인 레가시 ● 실패 이유 ○ 다른 X11 명세와 마찬가지로 spec이 너무 일반적 ■ root, off-the-spot, over-the-spot, on-the-spot 클라이언트별로 다른 방식을 모두 지원하자 니 위치 정보 전달, 폰트 정보 전달 등 걸림돌이 많음 ■ ibus, uim도 over-the-spot, on-the-spot 정도만 구현 ○ reference 코드가 (IMdkit) 완전하지 않았고 버그 많았음 ○ GUI toolkit인 Motif의 구현도 버그 많았고 closed-source라 고칠 수 없었음
  • 9.
    시나리오 - XIM Xserver App XIM server Event Event Preedit, Commit
  • 10.
    IBus, UIM, FCITX등 입력기 프레임워크 ● 다국어 입력 등 편리 ● GUI toolkit마다 입력기 플러그인(“immodule”)을 붙일 수 있게 되면서 용이해짐 ○ gtk 2 이후, qt 3 이후 ● 장점: 각각의 모듈은 각자 역할에 집중하면 됨. 통신, 툴킷, UI 등에 신경 쓸 필 요가 적음. ● 단점: 모든 입력기가 각 GUI toolkit마다 특정 입력기에 대한 고려를 하는 상황
  • 11.
    IBus IBus daemon engine (hangul …) ibus client (gtk,qt) XIM compat XIM client ibus server candidate UI, settings, ...
  • 12.
    시나리오 - IBus X/ Wayland App IBus server Event Event Preedit, Commit
  • 13.
    GUI 서버에서 입력기처리 ● wayland 프로토콜로 이런 게 있으나.. wl_input_method, wl_input_panel, wl_text_model ○ http://mirrors.ustc.edu.cn/kde- application/akademy/2012/slides/Wayland_Choosing_a_Better_Input_Method_Architecture_- _Michael_Hasselmann.pdf ○ ibus-wayland ○ weston에만 구현 ● mutter/gnome-shell 3.30 / 3.28.1 부터 “gtk-text-input” 프로토콜 추가 ● 직접 ibus에 연결해서 받은 결과물을 클라이언트에 전달 ● gtk에 ibus immodule 필요없어지고 wayland “gtk-text-input” 지원 필요 ● 장점: GUI toolkit에서 입력기 의존 처리가 필요 없음. 스크린 키보드, 필기 입력, 음성 입력 등 데스크톱 연동이 쉬움. ● 단점: 표준화가 쉽지 않음. gtk-text-input은 gtk/gnome 전용
  • 14.
    시나리오 - IBusfrom GUI server gnome-shell / mutter App IBus server Event Preedit, Commit Preedit, Commit
  • 15.
    보너스: libhangul ● “한글오토마타” 알고리즘 구현 ● 키를 입력하면 그 상태의 commit과 preedit string 상태를 알 수 있다. ● 한자 사전 검색 HangulInputContext* hangul_ic_new(const char* keyboard); void hangul_ic_delete(HangulInputContext *hic); bool hangul_ic_process(HangulInputContext *hic, int ascii); const ucschar* hangul_ic_get_preedit_string(HangulInputContext *hic); const ucschar* hangul_ic_get_commit_string(HangulInputContext *hic);
  • 16.
    #include <hangul.h> #include <glib.h> #include<stdio.h> int main(int argc, char *argv[]) { HangulInputContext *ic = hangul_ic_new("2"); for (char* k = &argv[1][0]; *k; k++) hangul_ic_process(ic, *k); const ucschar* preedit = hangul_ic_get_preedit_string(ic); const ucschar* commit = hangul_ic_get_commit_string(ic); // encoding conversion and print char *str; str = g_ucs4_to_utf8(commit, hangul_syllable_len(commit, -1), NULL, NULL, NULL); printf("commit: %sn", str); g_free(str); str = g_ucs4_to_utf8(preedit, hangul_syllable_len(preedit, -1), NULL, NULL, NULL); printf("preedit: %sn", str); g_free(str); hangul_ic_delete(ic); } $ ./a.out rmsh commit: 그 preedit: 노 $
  • 17.
    정리 ● 앞으로는? ○ 여러가지가호환성 유지되면서 변화 ○ XIM은 없어지겠지… ○ 마지막 GUI server 쪽에서 입력기에 연결하는 방식이 더 발전적 ● 입력 문제는 입력기 탓만 하기에는 여러가지 엮인 소프트웨어가 많다 ○ 관련된 여러가지 데스크톱 소프트웨어의 이슈와 개발 방향에 관심이 필요