Linux 버전 Scratch1.4에서 일본어 입력

Linux판의 Scratch1.4에서 일본어 입력 일본어 입력을 할 수 있도록 한 때의 메모입니다. Ubuntu12와 Raspberry Pi로 움직이는 Raspbian에서 움직이는 것을 확인하고 있습니다. ※Raspbian에 대해서는 QEMU상에서 검증이므로 실기에서는 검증하고 있지 않습니다만, 실기에서도 할 수 있었다고 하는 이야기는 듣고 있습니다.

어떻게 실현?



Scratch는 소스 코드는 Scratch 1.4 Source Code 로 공개되어 있습니다만 Scratch라는 이름이나 로고를 사용할 수 없거나, Scratch의 사이트에 업로드 할 수 없는 등의 조건이 있으므로, 이번은 Scratch 자체에 변경을 더하는 것이 아니라 VM의 (분)편에 변경을 더해 보려고 생각합니다.

이전 어딘가의 ML에서 Scratch는 utf32를 기대하고 있다는 것을 읽은 적이 있기 때문에, Scratch가 기대하는 utf32를 VM이 Scratch에 건네주도록 변경해 보겠습니다.

Scratch 설정 및 시작



먼저 Scratch를 설치합니다.
$ sudo apt-get install scratch

기본적으로 IME가 시작되지 않으므로 Scratch 시작 파일의 VMOPTIONS-compositioninput를 추가합니다.
$ sudo vi /usr/bin/scratch
@@ -7,7 +7,7 @@
 VM_VERSION=`find /usr/lib/squeak/ -name "squeakvm" -type f|cut -f5 -d"/"`
 SQ_DIR=/usr/lib/squeak/$VM_VERSION
 VM="$SQ_DIR/squeakvm"
-VMOPTIONS="-encoding UTF-8 -vm-display-x11 -plugins /usr/lib/scratch/plugins/:$SQ_DIR/"
+VMOPTIONS="-encoding UTF-8 -vm-display-x11 -plugins /usr/lib/scratch/plugins/:$SQ_DIR/ -compositioninput"
 IMAGE="/usr/share/scratch/Scratch.image"
 IMOPTIONS=""
 DOCUMENT=""

스크래치를 시작하려고합니다. -compositioninput 옵션을 지정한 것에 의해 IME를 사용할 수 있게 되어 있으므로 시험에 「아이우에오」라고 일본어를 입력해 봅니다.



보고 싶어? 유령 문자를 입력할 수 있었습니다! "0081""0082"근처에서 utf8 같은 것을 알 수 있습니다. 여기서 utf8 같은 분위기를 확인할 수 없으면 힘들 것 같았습니다만, 조금 한 사람 안심입니다.

VM 변경



먼저 VM을 컴파일하는 데 필요한 패키지를 설치합니다.
$ sudo apt-get install cmake g++ xorg-dev

계속해서 VM의 소스 코드를 다운로드하기 위해서 지금 사용하고 있는 VM의 버젼을 조사합니다. 버전을 확인하려면 ls -Al /usr/lib/squeak/를 실행하십시오. 내 환경에서는 4.4.7-2357임을 알 수 있습니다.
$ ls -Al /usr/lib/squeak/
total 4
drwxr-xr-x 2 root root 4096  6月  8 21:26 4.4.7-2357

htps : // 팹 c 게이 s. 데비안. 오 rg / 쟈 / 으아 zy / s 쿠에 아 k vm 또는 htp //ftp. 에서. 데비안. rg/데비안/포오l/마인/s/s쿠에아 kvm/ 근처에서 가까운 버전을 찾습니다. 이번에는 같은 버전이 있었으므로 squeak-vm_4.4.7.2357.orig.tar.gz를 다운로드합니다만, 만약 같은 버전이 없는 경우는 가까운 것을 다운로드해 시험해 보는 것이 됩니다.

압축을 풉니다.
$ tar xvfz squeak-vm_4.4.7.2357.orig.tar.gz

소스 코드를 변경합니다. 검증 코드라고 하는 것으로 역기로 썼기 때문에 긴 코드가 되어 버렸습니다만, 내용은 utf8을 utf32로 변환하는 것뿐입니다. 찾으면 보통 함수라든지 있을지도 모릅니다…
$ cd squeak-vm-4.4.7.2357.orig
$ vi unix/vm-display-X11/sqUnixX11.c

unix/vm-display-X11/sqUnixX11.c
@@ -1699,29 +1699,64 @@ static unsigned char *lookupKeys(int (*l

 static int recordPendingKeys(void)
 {
-  if (inputCount > 0)
-    {
-      int i= iebOut - iebIn;
-      for (i= (i > 0 ? i : IEB_SIZE + i) / 4; i > 0; -- i)
-   {
-# if defined(DEBUG_XIM)
-     fprintf(stderr, "%3d pending key %2d=0x%02x\n", inputCount, i, *pendingKey);
-# endif
-     recordKeyboardEvent(*pendingKey, EventKeyDown, modifierState, 0);
-     recordKeyboardEvent(*pendingKey, EventKeyChar, modifierState, 0);
-     recordKeystroke(*pendingKey);  /* DEPRECATED */
-     ++pendingKey;
-     if (--inputCount == 0) break;
-   }
-      return 1;
-    }
-  /* inputBuf is allocated by lookupKeys */
-  if (inputBuf != inputString)
-    {
+  if (inputCount <= 0) {
+    if (inputBuf != inputString) {
       free(inputBuf);
       inputBuf= inputString;
     }
-  return 0;
+    return 0;
+  }
+
+  int utf32 = 0;
+  while (inputCount > 0) {
+   //110x xxxx 10xx xxxx
+   if(inputCount >= 2 &&
+      pendingKey[0] >= 0xc0 && pendingKey[0] <= 0xdf && 
+      pendingKey[1] >= 0x80 && pendingKey[1] <= 0xbf)
+       {
+       utf32 = ((pendingKey[0] & 0x1f) << 6) | 
+            (pendingKey[1] & 0x3f);
+           recordKeyboardEvent(0, EventKeyDown, modifierState, utf32);
+           recordKeyboardEvent(0, EventKeyChar, modifierState, utf32);
+       pendingKey+=2;
+       inputCount-=2;
+   //1110 xxxx 10xx xxxx 10xx xxxx
+   } else if(inputCount >= 3 &&
+         pendingKey[0] >= 0xe0 && pendingKey[0] <= 0xef && 
+         pendingKey[1] >= 0x80 && pendingKey[1] <= 0xbf && 
+         pendingKey[2] >= 0x80 && pendingKey[2] <= 0xbf)
+       {
+       utf32 = ((pendingKey[0]  & 0x0f) << 12) | 
+           ((pendingKey[1] & 0x3f) << 6) | 
+            (pendingKey[2] & 0x3f);
+           recordKeyboardEvent(0, EventKeyDown, modifierState, utf32);
+           recordKeyboardEvent(0, EventKeyChar, modifierState, utf32);
+       pendingKey+=3;
+       inputCount-=3;
+   //1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx
+   } else if(inputCount >= 4 &&
+         pendingKey[0] >= 0xf0 && pendingKey[0] <= 0xf7 && 
+         pendingKey[1] >= 0x80 && pendingKey[1] <= 0xbf && 
+         pendingKey[2] >= 0x80 && pendingKey[2] <= 0xbf && 
+         pendingKey[3] >= 0x80 && pendingKey[3] <= 0xbf)
+       {
+       utf32 = ((pendingKey[0] & 0x07) << 18) | 
+           ((pendingKey[1] & 0x3f) << 12) |
+           ((pendingKey[2] & 0x3f) << 6) |
+            (pendingKey[3] & 0x3f);
+           recordKeyboardEvent(0, EventKeyDown, modifierState, utf32);
+           recordKeyboardEvent(0, EventKeyChar, modifierState, utf32);
+       pendingKey+=4;
+       inputCount-=4;
+   } else {
+           recordKeyboardEvent(*pendingKey, EventKeyDown, modifierState, 0);
+           recordKeyboardEvent(*pendingKey, EventKeyChar, modifierState, 0);
+           recordKeystroke(*pendingKey); /* DEPRECATED */
+       pendingKey++;
+       inputCount--;
+   }
+  }
+  return 1;
 }

 static int xkeysym2ucs4(KeySym keysym);

컴파일합니다. PC가 천천히 눈이므로 이번에는 vm-display-X11만 컴파일하고 설치해 보겠습니다. 설치는 조금 강인할지도 모르지만 기존의 so.vm-display-X11을 새로운 so.vm-display-X11로 바꾸는 것으로 실시합니다.
$ mkdir bld
$ cd bld
$ ../unix/cmake/configure
$ make vm-display-X11
$ sudo mv /usr/lib/squeak/4.4.7-2357/so.vm-display-X11 /usr/lib/squeak/4.4.7-2357/so.vm-display-X11.orig
$ sudo cp vm-display-X11/so.vm-display-X11 /usr/lib/squeak/4.4.7-2357/

오리지널 so.vm-display-X11과 새로운 fileso.vm-display-X11을 비교하면 상당히 커져 버렸습니다만, 우선은 신경쓰지 말아 둡니다.
$ ls -Al /usr/lib/squeak/4.4.7-2357/so.vm-display-X11*
-rwxr-xr-x 1 root root 279934  7月  2 12:26 so.vm-display-X11
-rw-r--r-- 1 root root  96860  4月 25  2012 so.vm-display-X11.orig

Scratch를 시작하여 일본어를 입력할 수 있는지 확인합니다.

좋은 웹페이지 즐겨찾기