void Android_OnTouch(int touch_device_id_in, int pointer_finger_id_in, int action, float x, float y, float p) { SDL_TouchID touchDeviceId = 0; SDL_FingerID fingerId = 0; int window_x, window_y; static SDL_FingerID pointerFingerID = 0; if (!Android_Window) { return; } touchDeviceId = (SDL_TouchID)touch_device_id_in; if (SDL_AddTouch(touchDeviceId, "") < 0) { SDL_Log("error: can't add touch %s, %d", __FILE__, __LINE__); } fingerId = (SDL_FingerID)pointer_finger_id_in; switch (action) { case ACTION_DOWN: /* Primary pointer down */ if (!separate_mouse_and_touch) { Android_GetWindowCoordinates(x, y, &window_x, &window_y); /* send moved event */ SDL_SendMouseMotion(Android_Window, SDL_TOUCH_MOUSEID, 0, window_x, window_y); /* send mouse down event */ SDL_SendMouseButton(Android_Window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT); } pointerFingerID = fingerId; case ACTION_POINTER_DOWN: /* Non primary pointer down */ SDL_SendTouch(touchDeviceId, fingerId, SDL_TRUE, x, y, p); break; case ACTION_MOVE: if (!pointerFingerID) { if (!separate_mouse_and_touch) { Android_GetWindowCoordinates(x, y, &window_x, &window_y); /* send moved event */ SDL_SendMouseMotion(Android_Window, SDL_TOUCH_MOUSEID, 0, window_x, window_y); } } SDL_SendTouchMotion(touchDeviceId, fingerId, x, y, p); break; case ACTION_UP: /* Primary pointer up */ if (!separate_mouse_and_touch) { /* send mouse up */ SDL_SendMouseButton(Android_Window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT); } pointerFingerID = (SDL_FingerID) 0; case ACTION_POINTER_UP: /* Non primary pointer up */ SDL_SendTouch(touchDeviceId, fingerId, SDL_FALSE, x, y, p); break; default: break; } }
void Android_OnTouch(int touch_device_id_in, int pointer_finger_id_in, int action, float x, float y, float p) { SDL_TouchID touchDeviceId = 0; SDL_FingerID fingerId = 0; int window_x, window_y; if (!Android_Window) { return; } touchDeviceId = (SDL_TouchID)touch_device_id_in; if (!SDL_GetTouch(touchDeviceId)) { if (SDL_AddTouch(touchDeviceId, "") < 0) { SDL_Log("error: can't add touch %s, %d", __FILE__, __LINE__); } } fingerId = (SDL_FingerID)pointer_finger_id_in; switch (action) { case ACTION_DOWN: case ACTION_POINTER_1_DOWN: if (!leftFingerDown) { Android_GetWindowCoordinates(x, y, &window_x, &window_y); /* send moved event */ SDL_SendMouseMotion(NULL, SDL_TOUCH_MOUSEID, 0, window_x, window_y); /* send mouse down event */ SDL_SendMouseButton(NULL, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT); leftFingerDown = fingerId; } SDL_SendTouch(touchDeviceId, fingerId, SDL_TRUE, x, y, p); break; case ACTION_MOVE: if (!leftFingerDown) { Android_GetWindowCoordinates(x, y, &window_x, &window_y); /* send moved event */ SDL_SendMouseMotion(NULL, SDL_TOUCH_MOUSEID, 0, window_x, window_y); } SDL_SendTouchMotion(touchDeviceId, fingerId, x, y, p); break; case ACTION_UP: case ACTION_POINTER_1_UP: if (fingerId == leftFingerDown) { /* send mouse up */ SDL_SendMouseButton(NULL, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT); leftFingerDown = 0; } SDL_SendTouch(touchDeviceId, fingerId, SDL_FALSE, x, y, p); break; default: break; } }
static void touch_handle_touch(void *data, struct qt_touch_extension *qt_touch_extension, uint32_t time, uint32_t id, uint32_t state, int32_t x, int32_t y, int32_t normalized_x, int32_t normalized_y, int32_t width, int32_t height, uint32_t pressure, int32_t velocity_x, int32_t velocity_y, uint32_t flags, struct wl_array *rawdata) { /** * Event is assembled in QtWayland in TouchExtensionGlobal::postTouchEvent * (src/compositor/wayland_wrapper/qwltouch.cpp) **/ float FIXED_TO_FLOAT = 1. / 10000.; float xf = FIXED_TO_FLOAT * x; float yf = FIXED_TO_FLOAT * y; float PRESSURE_TO_FLOAT = 1. / 255.; float pressuref = PRESSURE_TO_FLOAT * pressure; uint32_t touchState = state & 0xFFFF; /* Other fields that are sent by the server (qwltouch.cpp), but not used at the moment can be decoded in this way: uint32_t sentPointCount = state >> 16; uint32_t touchFlags = flags & 0xFFFF; uint32_t capabilities = flags >> 16; */ SDL_TouchID deviceId = 1; if (SDL_AddTouch(deviceId, "qt_touch_extension") < 0) { SDL_Log("error: can't add touch %s, %d", __FILE__, __LINE__); } switch (touchState) { case QtWaylandTouchPointPressed: case QtWaylandTouchPointReleased: SDL_SendTouch(deviceId, (SDL_FingerID)id, (touchState == QtWaylandTouchPointPressed) ? SDL_TRUE : SDL_FALSE, xf, yf, pressuref); break; case QtWaylandTouchPointMoved: SDL_SendTouchMotion(deviceId, (SDL_FingerID)id, xf, yf, pressuref); break; default: /* Should not happen */ break; } }
int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, float x, float y, float pressure) { SDL_Touch *touch; SDL_Finger *finger; int posted; float xrel, yrel, prel; touch = SDL_GetTouch(id); if (!touch) { return -1; } finger = SDL_GetFinger(touch,fingerid); if (!finger) { return SDL_SendTouch(id, fingerid, SDL_TRUE, x, y, pressure); } xrel = x - finger->x; yrel = y - finger->y; prel = pressure - finger->pressure; /* Drop events that don't change state */ if (!xrel && !yrel && !prel) { #if 0 printf("Touch event didn't change state - dropped!\n"); #endif return 0; } /* Update internal touch coordinates */ finger->x = x; finger->y = y; finger->pressure = pressure; /* Post the event, if desired */ posted = 0; if (SDL_GetEventState(SDL_FINGERMOTION) == SDL_ENABLE) { SDL_Event event; event.tfinger.type = SDL_FINGERMOTION; event.tfinger.touchId = id; event.tfinger.fingerId = fingerid; event.tfinger.x = x; event.tfinger.y = y; event.tfinger.dx = xrel; event.tfinger.dy = yrel; event.tfinger.pressure = pressure; posted = (SDL_PushEvent(&event) > 0); } return posted; }
static void HandleTouchPress(int device_id, int source_id, SDL_bool down, float x, float y, float pressure) { SDL_SendTouch(device_id, source_id, down, x, y, pressure); }
void SDL_EVDEV_Poll(void) { struct input_event events[32]; int i, j, len; SDL_evdevlist_item *item; SDL_Scancode scan_code; int mouse_button; SDL_Mouse *mouse; float norm_x, norm_y; if (!_this) { return; } #if SDL_USE_LIBUDEV SDL_UDEV_Poll(); #endif mouse = SDL_GetMouse(); for (item = _this->first; item != NULL; item = item->next) { while ((len = read(item->fd, events, (sizeof events))) > 0) { len /= sizeof(events[0]); for (i = 0; i < len; ++i) { /* special handling for touchscreen, that should eventually be used for all devices */ if (item->out_of_sync && item->is_touchscreen && events[i].type == EV_SYN && events[i].code != SYN_REPORT) { break; } switch (events[i].type) { case EV_KEY: if (events[i].code >= BTN_MOUSE && events[i].code < BTN_MOUSE + SDL_arraysize(EVDEV_MouseButtons)) { mouse_button = events[i].code - BTN_MOUSE; if (events[i].value == 0) { SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_RELEASED, EVDEV_MouseButtons[mouse_button]); } else if (events[i].value == 1) { SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_PRESSED, EVDEV_MouseButtons[mouse_button]); } break; } /* Probably keyboard */ scan_code = SDL_EVDEV_translate_keycode(events[i].code); if (scan_code != SDL_SCANCODE_UNKNOWN) { if (events[i].value == 0) { SDL_SendKeyboardKey(SDL_RELEASED, scan_code); } else if (events[i].value == 1 || events[i].value == 2 /* key repeated */) { SDL_SendKeyboardKey(SDL_PRESSED, scan_code); #ifdef SDL_INPUT_LINUXKD SDL_EVDEV_do_text_input(events[i].code); #endif /* SDL_INPUT_LINUXKD */ } } break; case EV_ABS: switch(events[i].code) { case ABS_MT_SLOT: if (!item->is_touchscreen) /* FIXME: temp hack */ break; item->touchscreen_data->current_slot = events[i].value; break; case ABS_MT_TRACKING_ID: if (!item->is_touchscreen) /* FIXME: temp hack */ break; if (events[i].value >= 0) { item->touchscreen_data->slots[item->touchscreen_data->current_slot].tracking_id = events[i].value; item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_DOWN; } else { item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_UP; } break; case ABS_MT_POSITION_X: if (!item->is_touchscreen) /* FIXME: temp hack */ break; item->touchscreen_data->slots[item->touchscreen_data->current_slot].x = events[i].value; if (item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta == EVDEV_TOUCH_SLOTDELTA_NONE) { item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_MOVE; } break; case ABS_MT_POSITION_Y: if (!item->is_touchscreen) /* FIXME: temp hack */ break; item->touchscreen_data->slots[item->touchscreen_data->current_slot].y = events[i].value; if (item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta == EVDEV_TOUCH_SLOTDELTA_NONE) { item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_MOVE; } break; case ABS_X: if (item->is_touchscreen) /* FIXME: temp hack */ break; SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_FALSE, events[i].value, mouse->y); break; case ABS_Y: if (item->is_touchscreen) /* FIXME: temp hack */ break; SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_FALSE, mouse->x, events[i].value); break; default: break; } break; case EV_REL: switch(events[i].code) { case REL_X: SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_TRUE, events[i].value, 0); break; case REL_Y: SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_TRUE, 0, events[i].value); break; case REL_WHEEL: SDL_SendMouseWheel(mouse->focus, mouse->mouseID, 0, events[i].value, SDL_MOUSEWHEEL_NORMAL); break; case REL_HWHEEL: SDL_SendMouseWheel(mouse->focus, mouse->mouseID, events[i].value, 0, SDL_MOUSEWHEEL_NORMAL); break; default: break; } break; case EV_SYN: switch (events[i].code) { case SYN_REPORT: if (!item->is_touchscreen) /* FIXME: temp hack */ break; for(j = 0; j < item->touchscreen_data->max_slots; j++) { norm_x = (float)(item->touchscreen_data->slots[j].x - item->touchscreen_data->min_x) / (float)item->touchscreen_data->range_x; norm_y = (float)(item->touchscreen_data->slots[j].y - item->touchscreen_data->min_y) / (float)item->touchscreen_data->range_y; switch(item->touchscreen_data->slots[j].delta) { case EVDEV_TOUCH_SLOTDELTA_DOWN: SDL_SendTouch(item->fd, item->touchscreen_data->slots[j].tracking_id, SDL_TRUE, norm_x, norm_y, 1.0f); item->touchscreen_data->slots[j].delta = EVDEV_TOUCH_SLOTDELTA_NONE; break; case EVDEV_TOUCH_SLOTDELTA_UP: SDL_SendTouch(item->fd, item->touchscreen_data->slots[j].tracking_id, SDL_FALSE, norm_x, norm_y, 1.0f); item->touchscreen_data->slots[j].tracking_id = -1; item->touchscreen_data->slots[j].delta = EVDEV_TOUCH_SLOTDELTA_NONE; break; case EVDEV_TOUCH_SLOTDELTA_MOVE: SDL_SendTouchMotion(item->fd, item->touchscreen_data->slots[j].tracking_id, norm_x, norm_y, 1.0f); item->touchscreen_data->slots[j].delta = EVDEV_TOUCH_SLOTDELTA_NONE; break; default: break; } } if (item->out_of_sync) item->out_of_sync = 0; break; case SYN_DROPPED: if (item->is_touchscreen) item->out_of_sync = 1; SDL_EVDEV_sync_device(item); break; default: break; } break; } } } } }
static int SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks) { SDL_Mouse *mouse = SDL_GetMouse(); int posted; Uint32 type; Uint32 buttonstate = mouse->buttonstate; /* SDL_HINT_MOUSE_TOUCH_EVENTS: controlling whether mouse events should generate synthetic touch events */ if (mouse->mouse_touch_events) { if (mouseID != SDL_TOUCH_MOUSEID && button == SDL_BUTTON_LEFT) { if (state == SDL_PRESSED) { track_mouse_down = SDL_TRUE; } else { track_mouse_down = SDL_FALSE; } if (window) { float fx = (float)mouse->x / (float)window->w; float fy = (float)mouse->y / (float)window->h; SDL_SendTouch(SDL_MOUSE_TOUCHID, 0, track_mouse_down, fx, fy, 1.0f); } } } /* Figure out which event to perform */ switch (state) { case SDL_PRESSED: type = SDL_MOUSEBUTTONDOWN; buttonstate |= SDL_BUTTON(button); break; case SDL_RELEASED: type = SDL_MOUSEBUTTONUP; buttonstate &= ~SDL_BUTTON(button); break; default: /* Invalid state -- bail */ return 0; } /* We do this after calculating buttonstate so button presses gain focus */ if (window && state == SDL_PRESSED) { SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate); } if (buttonstate == mouse->buttonstate) { /* Ignore this event, no state change */ return 0; } mouse->buttonstate = buttonstate; if (clicks < 0) { SDL_MouseClickState *clickstate = GetMouseClickState(mouse, button); if (clickstate) { if (state == SDL_PRESSED) { Uint32 now = SDL_GetTicks(); if (SDL_TICKS_PASSED(now, clickstate->last_timestamp + mouse->double_click_time) || SDL_abs(mouse->x - clickstate->last_x) > mouse->double_click_radius || SDL_abs(mouse->y - clickstate->last_y) > mouse->double_click_radius) { clickstate->click_count = 0; } clickstate->last_timestamp = now; clickstate->last_x = mouse->x; clickstate->last_y = mouse->y; if (clickstate->click_count < 255) { ++clickstate->click_count; } } clicks = clickstate->click_count; } else { clicks = 1; } } /* Post the event, if desired */ posted = 0; if (SDL_GetEventState(type) == SDL_ENABLE) { SDL_Event event; event.type = type; event.button.windowID = mouse->focus ? mouse->focus->id : 0; event.button.which = mouseID; event.button.state = state; event.button.button = button; event.button.clicks = (Uint8) SDL_min(clicks, 255); event.button.x = mouse->x; event.button.y = mouse->y; posted = (SDL_PushEvent(&event) > 0); } /* We do this after dispatching event so button releases can lose focus */ if (window && state == SDL_RELEASED) { SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate); } return posted; }