パソコンなど

パソコンの話をします。

WacomのペンタブをX上でつかう

タブレットバイス

タブレットバイス(いわゆるペンタブ)は、絵や文字を描くときに便利な入力デバイスである。マウスやトラックポイントタッチパッドに比べて遥かに自然に線などを描くことができる。

X上で使う上での問題点

X上では、タブレットバイスは、スクリーン全体にマッピングされる。スクリーンののアスペクト比と、タブレットバイスの物理的なアスペクト比がほぼ一致している場合はそこまで問題にならない。しかし、マルチモニターなどによって、スクリーンとタブレットバイスアスペクト比が大きく異なる場合、普通に書き込むと描いた内容が引き伸ばされる。また、スクリーン上の小さな領域に描画したい場合、タブレットバイスの非常に小さな領域に描く必要があり、物理的なセンサー面の殆どが無駄になる。

私のデスクトップ環境は、2560x1600のモニターの右側に3840x2160のモニターを並べたマルチモニターとなっており、スクリーン全体は6400x2160の大きさである。一方使用しているタブレットバイスはセンサー面のサイズが21600x13500の16:10のアスペクト比となっている。スクリーン全体のアスペクト比を縦10に変換すると、29.63:10となり、倍弱ほど横長なスクリーン領域となる。そのため、普通にタブレットバイスマッピングして描くとかなり横に伸びてしまう。

私のデスクトップ環境

普通のマッピングで描いた様子、横にかなり引き伸ばされる。

目的の状態

横長のウィンドウへのマッピング

縦長のウィンドウへのマッピング

正しくマッピングされたウィンドウに描いた様子

対処法

  • xinputコマンドを用いることで、タブレットバイスマッピングされるスクリーン上の領域を変更できる。
    • xinput set-prop <device id> Coordinate\ Transformation\ Matrix <affine transformation matrix>
  • <device id>で、タブレットが割り当てられているIDを選択する。
  • <affine transformation matrix>は、マッピングされる領域を変換するアフィン行列を展開した9つのfloatの値を入力する。

device idを調べる

  • xinput listで繋がっているデバイスのリストが得られる。
    • ここでは、Wacom One by Wacom M Pen stylusがそれで、idは11であることがわかる。
$ xinput list
⎡ Virtual core pointer                        id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ ELAN0678:00 04F3:3195 Mouse               id=14   [slave  pointer  (2)]
⎜   ↳ ELAN0678:00 04F3:3195 Touchpad            id=15   [slave  pointer  (2)]
⎜   ↳ TPPS/2 Elan TrackPoint                    id=17   [slave  pointer  (2)]
⎜   ↳ Wacom One by Wacom M Pen stylus           id=11   [slave  pointer  (2)]
⎜   ↳ Wacom One by Wacom M Pen eraser           id=19   [slave  pointer  (2)]
⎣ Virtual core keyboard                       id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard                 id=5    [slave  keyboard (3)]
    ↳ Power Button                                id=6    [slave  keyboard (3)]
    ↳ Video Bus                                   id=7    [slave  keyboard (3)]
    ↳ Power Button                                id=8    [slave  keyboard (3)]
    ↳ Sleep Button                                id=9    [slave  keyboard (3)]
    ↳ Integrated Camera: Integrated C             id=12   [slave  keyboard (3)]
    ↳ Integrated Camera: Integrated I             id=13   [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard                id=16   [slave  keyboard (3)]
    ↳ ThinkPad Extra Buttons                      id=18   [slave  keyboard (3)]
    ↳ Solid State System Co.,Ltd. LCS USB Audio   id=10   [slave  keyboard (3)]
$
  • xsetwacom --list devicesWacomのデバイスに限定して調べられる。
    • 前のものと同じであることがわかる。
$ xsetwacom --list devicesp
Wacom One by Wacom M Pen stylus     id: 11  type: STYLUS
Wacom One by Wacom M Pen eraser     id: 19  type: ERASER
$

アフィン変換行列を求める

  • xinputのCoordinate Transformation Matrixの引数にはアフィン変換行列を与える。
  • スクリーン全体にマッピングされた状態から、目的の状態への変換行列を求める必要がある。
  • 具体的には、原点(左上)を中心に、ウィンドウサイズに合わせてスケーリングを行う変換行列と、ウィンドウの左上に合わせて平行移動を行う変換行列の積を求める。

スケーリング

平行移動

  • ウィンドウの左上の座標がスクリーン上でどこになるかを求める。
    • ウィンドウの位置
      • xdotool getwindowgeometry <window id>
    • スクリーンのサイズ
      • xdpyinfo
      • xrandr

実装

  • 上に示したようなコマンドを実行して結果をパースし、アフィン行列を計算、xinputでペンタブを設定するプログラムを実装した。

github.com

付録(それぞれのコマンドの出力)

  • $で始まる行はコマンド入力である。
  • ペンタブのサイズ: xinput watch-props <device id>
$ xinput watch-props 11
Device 'Wacom One by Wacom M Pen stylus':
    Device Enabled (163):   1
    Coordinate Transformation Matrix (165): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
    Device Accel Profile (290): 0
    Device Accel Constant Deceleration (291):   1.000000
    Device Accel Adaptive Deceleration (292):   1.000000
    Device Accel Velocity Scaling (293):    10.000000
    Device Node (287):  "/dev/input/event13"
    Wacom Tablet Area (300):    0, 0, 21600, 13500
    Wacom Rotation (301):   0
    Wacom Pressurecurve (302):  0, 0, 100, 100
    Wacom Serial IDs (303): 891, 0, 2, 0, 0
    Wacom Serial ID binding (304):  0
    Wacom Proximity Threshold (305):    30
    Wacom Pressure Threshold (306): 26
    Wacom Sample and Suppress (307):    2, 4
    Wacom Enable Touch (308):   0
    Wacom Hover Click (309):    1
    Wacom Enable Touch Gesture (310):   0
    Wacom Touch Gesture Parameters (311):   0, 0, 250
    Wacom Tool Type (312):  "STYLUS" (289)
    Wacom button action 0 (313):    1572865
    Wacom button action 1 (314):    1572866
    Wacom button action 2 (315):    1572867
    Wacom button action 3 (316):    1572872
    Wacom Button Actions (317): "Wacom button action 0" (313), "Wacom button action 1" (314), "Wacom button action 2" (315), "None" (0), "None" (0), "None" (0), "None" (0), "Wacom button action 3" (316)
    Wacom Pressure Recalibration (318): 1
    Wacom Panscroll Threshold (319):    1300
    Device Product ID (288):    1386, 891
    Wacom Debug Levels (320):   0, 0
$
  • ペンタブのサイズ: xsetwacom --get <device name> Area
$ xsetwacom --get "Wacom One By Wacom M Pen stylus" Area
0 0 21600 13500
$
  • ウィンドウのジオメトリ: xdotool getwindowgeometry <window id>
  • ウィンドウのID: xdotool selectwindow
$ xdotool getwindowgeometry $(xdotool selectwindow)
Window 4194313
  Position: 1280,0 (screen: 0)
  Geometry: 1280x1600
$
  • スクリーンのサイズ: xdpyinfo
$ xpyinfo | grep dimensions
  dimensions:    6400x2160 pixels (1684x568 millimeters)
$
  • スクリーンのサイズ: xrandr
$ xrandr | grep Screen
Screen 0: minimum 320 x 200, current 6400 x 2160, maximum 16384 x 16384
$