5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Linux版Scratch1.4で日本語入力

Last updated at Posted at 2016-07-02

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=""

Scratchはを起動してみます。-compositioninputオプションを指定したことによってIMEが使えるようになっていますので試しに「あいうえお」と日本語を入力してみます。

16-06-30 scratch.png

めでたく?化け文字が入力できました!「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

https://packages.debian.org/ja/wheezy/squeak-vmhttp://ftp.de.debian.org/debian/pool/main/s/squeak-vm/ あたりから近いバージョンを探します。今回は同じバージョンがありましたので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を起動して日本語が入力できることを確認します。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?