ラップトップのI2C接続なタッチスクリーンをキャリブレーションして快適に使う

この記事は、NetBSD Advent Calendar 2019の3日目の記事です。

はじめに

HP Spectre x360 13-inch ae019TUというラップトップを使っています。 このラップトップには、ペンと指の両方で操作できるタッチスクリーンが搭載されています。 このタッチスクリーンは、NetBSD-currentだと、ims(4)として認識されます。 しかし、画面の表示と一致させるにはキャリブレーションが必要です。

キャリブレーションの方法

NetBSD-currentでは、src/sys/dev/i2c/ims.c 1.2以降、 tpcalibの仕組みでキャリブレーションができるようになっています。 これは、wsmouse_calibcoords構造体に条件を設定してioctl(2)を発行すると実行できます。

その際に与えるべき値は、options DEBUGを指定してビルドしたカーネルで起動すると、ブートメッセージに表示されます。 HP Spectre x360 13-inch ae019TUの場合には、タッチスクリーンは、X方向は0から18344、Y方向は0から10544の値を出力します。

ioctl(2)の実際

ペンで操作する場合のタッチスクリーンは、/dev/wsmouse2に割り当てられています。 この場合の概略の処理は以下のようです。

struct wsmouse_calibcoords calibcoords;
memset(&calibcoords, 0, sizeof(calibcoords));

int fd = open("/dev/wsmouse2", O_RDWR);

/* calibcoords構造体を設定する。 */

ioctl(fd, WSMOUSEIO_SCALIBCOORDS, &calibcoords);
つまり、設定されたcalibcoords構造体を、/dev/wsmouse2に対して、設定(WSMOUSEIO_SCALIBCOORDS)することで、 キャリブレーションができます。

では、calibcoords構造体には何を与えたら良いのでしょうか。 src/sys/dev/wscons/tpcalib.csrc/sys/dev/wscons/mra.cを読むと、 calibcoords.samples[0]に中央の座標、 calibcoords.samples[1]に左上の座標、 calibcoords.samples[2]に左下の座標、 calibcoords.samples[3]に右下の座標、 calibcoords.samples[4]に右上の座標 を指定すれば良いことが分かりました。 今回は、mra.cの想定するようにゆがんだ四角形を画面に合わせるのではありませんが、 簡単ですので、5点を指定してみます。

int X = 18344;
int Y = 10544;
int dispX = 3840 - 1;
int dispY = 2160 - 1;

calibcoords.minx = 0;
calibcoords.maxx = dispX;
calibcoords.miny = 0;
calibcoords.maxy = dispY;

/* center */
calibcoords.samples[0].rawx = X / 2;
calibcoords.samples[0].rawy = Y / 2;
calibcoords.samples[0].x = dispX / 2;
calibcoords.samples[0].y = dispY / 2;

/* top left */
calibcoords.samples[1].rawx = 0;
calibcoords.samples[1].rawy = 0;
calibcoords.samples[1].x = 0;
calibcoords.samples[1].y = 0;

/* bottom left */
calibcoords.samples[2].rawx = 0;
calibcoords.samples[2].rawy = Y;
calibcoords.samples[2].x = 0;
calibcoords.samples[2].y = dispY;

/* bottom right */
calibcoords.samples[3].rawx = X;
calibcoords.samples[3].rawy = Y;
calibcoords.samples[3].x = dispX;
calibcoords.samples[3].y = dispY;

/* top right */
calibcoords.samples[4].rawx = X;
calibcoords.samples[4].rawy = 0;
calibcoords.samples[4].x = dispX;
calibcoords.samples[4].y = 0;
これで、calibcoords構造体は準備できました。

実際に使用する

これをCコンパイラーでコンパイルして、/dev/wsmouse2が開かれて利用されていない状態で実行します。 それによって、以降例えばX window systemを立ち上げると、キャリブレーションされた状態で利用できます。

pkgsrc/editors/xournalppで使ってみます。

必要ない時には、以下のように切り離しておくのが良さそうです。

# /usr/sbin/wsmuxctl -f /dev/wsmux0 -r wsmouse2

No comments:

Post a Comment

NetBSD/amiga-current on WinUAE Amiga m68k emulator

この記事は、 NetBSD Advent Calendar 2019 の10日目の記事です。 はじめに ウェブを検索してみると、NetBSD/amigaをWinUAEというm68kを搭載したAmigaというマシンでNetBSD/amigaを動かした記録が見付かります。...