Microsoft ペン プロトコルのサポート

Microsoft ペン プロトコルのサポート

私は Dell Inspiron 13 7000 2-in-1 Black Edition (7391) で Ubuntu 19.10 を実行しています。このノートパソコンには、Dell PN350M Active Pen という非常に優れたスタイラスが付属していますが、残念ながら私のシステムではまったく機能しません。Web で少し調べてみると、このペンは Bluetooth ではなく Microsoft Pen Protocol を使用してノートパソコンとペアリングしていることがわかりました。これらはサポートされているのでしょうか? Google で検索しても答えは見つかりません。

編集:

以下は xinput の更新された出力です。ここには疑わしい点があり、特に「UNKNOWN」の部分です。

~> xinput list
⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ DELL0960:00 04F3:30E4 Touchpad            id=9    [slave  pointer  (2)]
⎜   ↳ CUST0000:00 27C6:0111                     id=10   [slave  pointer  (2)]
⎜   ↳ CUST0000:00 27C6:0111 UNKNOWN             id=11   [slave  pointer  (2)]
⎜   ↳ PS/2 Generic Mouse                        id=16   [slave  pointer  (2)]
⎜   ↳ M585/M590 Mouse                           id=18   [slave  pointer  (2)]
⎣ Virtual core keyboard                     id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ Power Button                              id=7    [slave  keyboard (3)]
    ↳ Video Bus                                 id=6    [slave  keyboard (3)]
    ↳ Dell WMI hotkeys                          id=14   [slave  keyboard (3)]
    ↳ Intel HID 5 button array                  id=13   [slave  keyboard (3)]
    ↳ Intel HID events                          id=12   [slave  keyboard (3)]
    ↳ Integrated_Webcam_HD: Integrate           id=8    [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard              id=15   [slave  keyboard (3)]
    ↳ M585/M590 Keyboard                        id=17   [slave  keyboard (3)]


答え1

evdev および libevdev ライブラリを使用して Python ドライバーを作成することができました。仮想デバイスを作成し、スタイラスから見つけたイベントを単に渡しています。圧力イベントと追跡は機能していますが、ボタンは機能しませんでした。

これをコピーして実行可能としてマークすると、「カスタム スタイラス」というデバイスが表示され、動作するはずです。さらにシームレスにするために、gnome-session-properties起動時にスクリプトが実行されるようにこれを追加しました。

お役に立てれば!

#!/usr/bin/env python3
import sys
import libevdev
import time
import evdev
from evdev import UInput, AbsInfo, ecodes
import os


def main(args):
    p = 0
    i = 0
    devices = evdev.list_devices()

    for dev in devices:
        # print('%-12i%s' % (p, evdev.InputDevice(dev).name))
        if evdev.InputDevice(dev).name == 'CUST0000:00 27C6:0118 Stylus':
            i = p
        p += 1

    # i=int(input("Enter number: "))

    device = evdev.InputDevice(devices[i])

    print(device)

    # print(mouse.capabilities(verbose=True))

    device.grab()

    x, y = 0, 0

    dev = libevdev.Device()
    dev.name = "Custom Stylus"

    dev.enable(libevdev.INPUT_PROP_DIRECT)
    dev.enable(libevdev.EV_KEY.BTN_TOOL_PEN)
    dev.enable(libevdev.EV_KEY.BTN_TOOL_RUBBER)
    # Click
    dev.enable(libevdev.EV_KEY.BTN_TOUCH)
    # Press button 1 on pen
    dev.enable(libevdev.EV_KEY.BTN_STYLUS)
    # Press button 2 on pen, see great doc
    dev.enable(libevdev.EV_KEY.BTN_STYLUS2)
    # Send absolute X coordinate
    dev.enable(libevdev.EV_ABS.ABS_X,
               libevdev.InputAbsInfo(minimum=0, maximum=5760, resolution=17))
    # Send absolute Y coordinate
    dev.enable(libevdev.EV_ABS.ABS_Y,
               libevdev.InputAbsInfo(minimum=0, maximum=3240, resolution=17))
    # Send absolute pressure
    dev.enable(libevdev.EV_ABS.ABS_PRESSURE,
               libevdev.InputAbsInfo(minimum=0, maximum=1023))
    dev.enable(libevdev.EV_SYN.SYN_REPORT)
    dev.enable(libevdev.EV_SYN.SYN_DROPPED)
    try:
        uinput = dev.create_uinput_device()
        print("New device at {} ({})".format(uinput.devnode, uinput.syspath))
        # Sleep for a bit so udev, libinput, Xorg, Wayland, ...
        # all have had a chance to see the device and initialize
        # it. Otherwise the event will be sent by the kernel but
        # nothing is ready to listen to the device yet. And it
        # will never be detected in the futur ;-)
        time.sleep(1)
        # Reports that the PEN is close to the surface
        # Important to make sure xinput can detect (and list)
        # the pen. Otherwise, it won't write anything in gimp.
        uinput.send_events([
            libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH,
                                value=0),
            libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN,
                                value=1),
            libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT,
                                value=0),
        ])
        # Says that the pen it out of range of the tablet. Useful
        # to make sure you can move your mouse, and to avoid
        # strange things during the first draw.
        uinput.send_events([
            libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH,
                                value=0),
            libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN,
                                value=0),
            libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT,
                                value=0),
        ])

        for event in device.read_loop():
            code, val = event.code, event.value

            if code == ecodes.ABS_MT_POSITION_X:
                uinput.send_events([
                    libevdev.InputEvent(libevdev.EV_ABS.ABS_X,
                                        value=int(val)),
                    libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH,
                                        value=1),
                    libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS,
                                        value=0),
                    libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS2,
                                        value=0),
                    libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN,
                                        value=1),
                    libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT,
                                        value=0)])
                # vpen.write(ecodes.EV_ABS, ecodes.ABS_X, int(val))

            if code == ecodes.ABS_MT_POSITION_Y:
                uinput.send_events([
                    libevdev.InputEvent(libevdev.EV_ABS.ABS_Y,
                                        value=int(val)),
                    libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH,
                                        value=1),
                    libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS,
                                        value=0),
                    libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS2,
                                        value=0),
                    libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN,
                                        value=1),
                    libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT,
                                        value=0)])

            if code == ecodes.ABS_MT_PRESSURE:
                uinput.send_events([
                    libevdev.InputEvent(libevdev.EV_ABS.ABS_PRESSURE,
                                        value=int(val)),
                    libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH,
                                        value=1),
                    libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS,
                                        value=0),
                    libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS2,
                                        value=0),
                    libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN,
                                        value=1),
                    libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT,
                                        value=0)])

        device.ungrab()

    except KeyboardInterrupt:
        pass


if __name__ == "__main__":
    main(sys.argv)

答え2

同じ質問があります。私は15インチのシルバーを使用しています。そのプロトコルを使用するワコムのドライバーを使用できる可能性があると考えていましたが、それ以外では、MPPドライバーを何らかの方法で入手する必要がありますが、どこで入手できるかはわかりません。

関連情報