프로그램 사용/uinput
uinput touch 장치 흉내내기
구차니
2024. 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; } |