프로그램 사용/uinput2024. 3. 13. 14:49

실제 장치에서 터치 한번 하는걸 흉내냈는데 안되서, 프로토콜 대로 구현하니 된다.

 

linux 5.10.72 이긴 한데 그거 영향인진 모르겠지만

Protocol A 로 구현하니 커서나 클릭도 안되는 것 같고

Protocol B를 따라 구현하니 된다.

 

3.4. Protocol Example B
Here is what a minimal event sequence for a two-contact touch would look like for a type B device:

ABS_MT_SLOT 0
ABS_MT_TRACKING_ID 45
ABS_MT_POSITION_X x[0]
ABS_MT_POSITION_Y y[0]
ABS_MT_SLOT 1
ABS_MT_TRACKING_ID 46
ABS_MT_POSITION_X x[1]
ABS_MT_POSITION_Y y[1]
SYN_REPORT
Here is the sequence after moving contact 45 in the x direction:

ABS_MT_SLOT 0
ABS_MT_POSITION_X x[0]
SYN_REPORT
Here is the sequence after lifting the contact in slot 0:

ABS_MT_TRACKING_ID -1
SYN_REPORT

[링크 : https://docs.kernel.org/input/multi-touch-protocol.html]

 

 

초기화

    struct uinput_setup usetup;
    int keys[] = {BTN_TOUCH}; // BTN_LEFT, BTN_RIGHT, 

    fd_touch = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
    ioctl(fd_touch, UI_SET_EVBIT, EV_KEY);
    for(int i = 0; i < sizeof(keys) / sizeof(int); i++){
        ioctl(fd_touch, UI_SET_KEYBIT, keys[i]);
    }

    //Mouse Pointer events init
    ret = ioctl(fd_touch, UI_SET_EVBIT, EV_ABS);
    ret = ioctl(fd_touch, UI_SET_ABSBIT, ABS_MT_SLOT);
    ret = ioctl(fd_touch, UI_SET_ABSBIT, ABS_MT_POSITION_X);
    ret = ioctl(fd_touch, UI_SET_ABSBIT, ABS_MT_POSITION_Y);
    ret = ioctl(fd_touch, UI_SET_EVBIT, EV_SYN);

    struct uinput_abs_setup abs_setup_x;
    struct uinput_abs_setup abs_setup_y;
    memset(&abs_setup_x, 0, sizeof(abs_setup_x));
    memset(&abs_setup_y, 0, sizeof(abs_setup_y));
    abs_setup_x.code = ABS_MT_POSITION_X;
    abs_setup_x.absinfo.minimum = 0;
    abs_setup_x.absinfo.maximum = 1024;
    abs_setup_y.code = ABS_MT_POSITION_Y;
    abs_setup_y.absinfo.minimum = 0;
    abs_setup_y.absinfo.maximum = 768;
    ret = ioctl(fd_touch, UI_ABS_SETUP, &abs_setup_x);
    ret = ioctl(fd_touch, UI_ABS_SETUP, &abs_setup_y);

    memset(&usetup, 0, sizeof(usetup));
    usetup.id.bustype = BUS_USB;
    usetup.id.vendor = 0x4711;
    usetup.id.product = 0x0817;
    strcpy(usetup.name, "virtual touch device");
    ret = ioctl(fd_touch, UI_DEV_SETUP, &usetup);
    ret = ioctl(fd_touch, UI_DEV_CREATE);

 

터치(클릭) 처리

switch(buttonMask)
{
    default:
        printf("buttonMask[%02X]\n",buttonMask);
    break;
    
    case BUTTON_RELEASE:
        switch(prev_click)
        {
            case BUTTON_L_DOWN:
                printf("BUTTON_L_DOWN BUTTON_RELEASE\n");
                prev_click = -1;
                emit(fd_touch, EV_ABS, ABS_MT_TRACKING_ID, -1);
                emit(fd_touch, EV_SYN, SYN_REPORT, 0);
                break;
        }
        break;

    case BUTTON_L_DOWN:
        if(prev_click == -1)
        {
            printf("BUTTON_L_DOWN\n");
            prev_click = buttonMask;
            emit(fd_touch, EV_ABS, ABS_MT_SLOT, 0);
            emit(fd_touch, EV_ABS, ABS_MT_TRACKING_ID, track_id++);
            emit(fd_touch, EV_ABS, ABS_MT_POSITION_X, pos_x);
            emit(fd_touch, EV_ABS, ABS_MT_POSITION_Y, pos_y);
            emit(fd_touch, EV_ABS, ABS_X, pos_x);
            emit(fd_touch, EV_ABS, ABS_Y, pos_y);
            emit(fd_touch, EV_SYN, SYN_REPORT, 0);
        }
        else
        {
            printf("BUTTON_L_DOWN MOVE\n");
            emit(fd_touch, EV_ABS, ABS_MT_SLOT, 0);
            emit(fd_touch, EV_ABS, ABS_MT_POSITION_X, pos_x);
            emit(fd_touch, EV_ABS, ABS_MT_POSITION_Y, pos_y);
            emit(fd_touch, EV_ABS, ABS_X, pos_x);
            emit(fd_touch, EV_ABS, ABS_Y, pos_y);
            emit(fd_touch, EV_SYN, SYN_REPORT, 0);
        }
        break;
}

 

Posted by 구차니