Using /dev/uinput and screen orientation problems

168 views
Skip to first unread message

Miha Valencic

unread,
Jun 4, 2014, 3:29:55 AM6/4/14
to android...@googlegroups.com
[I'm reposting this, because it seems that previous posting hasn't come through - perhaps the list is moderated?]

Hi!

I'm using custom input device to inject keyboard and touch events from the remote side. It is working in portrait mode, but not in landscape mode.

I'm testing this functionality on Galaxy S2 and Nexus7 hardware devices. Galaxy S2 has screen size 480x800, so I configure uinput device with:

uidev.absmin[ABS_MT_POSITION_X] = 0;
uidev.absmax[ABS_MT_POSITION_X] = 479;
uidev.absmin[ABS_MT_POSITION_Y] = 0;
uidev.absmax[ABS_MT_POSITION_X] = 799;

When the device is rotated, the width changes to 800 and height changes to 480. At first I thought that I'd need to translate coordinates, but it seems that Android does that itself. The problem here is, because I can't inject coordinates for X axis beyond 479, because this is what I've set for maximum.

If I change absmax property and set it to 799, Android will just "scale" the input coordinate space [0,799] to output [0,479], so that X value 799 comes out to 479.

So I haven't found a way to inject pointer events in landscape mode which exceed the "portrait width". I'm sure there's something I'm missing, though I don't know what.

uidev configuration I'm using:
    uinput_user_dev uidev;
    memset(&uidev, 0, sizeof(uidev));
    snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "uinput-custom");
    uidev.id.bustype = BUS_USB;
    uidev.id.vendor  = 0x1234;
    uidev.id.product = 0xfedc;
    uidev.id.version = 3;
    uidev.absmin[ABS_MT_SLOT] = 0;
    uidev.absmax[ABS_MT_SLOT] = 1; // two touches supported (well, someday, perhaps)
    uidev.absmin[ABS_MT_TOUCH_MAJOR] = 0; // touched area
    uidev.absmax[ABS_MT_TOUCH_MAJOR] = 255;
    uidev.absmin[ABS_MT_POSITION_X] = 0;
    uidev.absmax[ABS_MT_POSITION_X] = m_width-1; 
    uidev.absmin[ABS_MT_POSITION_Y] = 0;
    uidev.absmax[ABS_MT_POSITION_Y] = m_height-1;
    // uidev.absmin[ABS_X] = 0;
    // uidev.absmax[ABS_X] = m_width - 1;
    // uidev.absmin[ABS_Y] = 0;
    // uidev.absmax[ABS_Y] = m_height - 1;
    uidev.absmin[ABS_MT_TRACKING_ID] = 0; // new ID for each touch event
    uidev.absmax[ABS_MT_TRACKING_ID] = 65535;
    uidev.absmin[ABS_MT_PRESSURE] = 0;
    uidev.absmax[ABS_MT_PRESSURE] = 30;
    uidev.absmin[ABS_MT_TOOL_TYPE] = 0;
    uidev.absmax[ABS_MT_TOOL_TYPE] = 1;

And for each touch event, I'm using MT_TOOL_PEN, because MT_TOOL_FINGER didn't work (nothing happened).

I also tried to create uinput device while the device is in landscape mode using width=799 and height=479, but that just scales the output domain as well.

Kind regards,
 Miha.

Miha Valencic

unread,
Jun 6, 2014, 11:08:00 AM6/6/14
to android...@googlegroups.com
Hi!

FWIW, I haven't been able to solve this particular problem. I have, however, taken a different route. I decided to use one of the inputs already registered and I'm injecting events there. This approach is not as clean is a custom uinput device, but as long as it works...

Miha

grega.p...@gmail.com

unread,
Jan 13, 2017, 4:52:54 PM1/13/17
to Android Linux Kernel Development
Hi.

The solution is to set this INPUT_PROP_DIRECT on the virtual device:
 
ioctl(m_fd, UI_SET_PROPBIT, INPUT_PROP_DIRECT)

Grega
Reply all
Reply to author
Forward
0 new messages