X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fevdev-mt-touchpad-buttons.c;h=21417ab9fd2e27fb2df68d3cbde53a4618f5c638;hb=a721292c254bfc4074ea3ee1f328260feda7c936;hp=f6235a0a67435e66c643402449e942c29769c3a4;hpb=3a3d70a3a895140b91c58bc305c90ee3f9268346;p=platform%2Fupstream%2Flibinput.git diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c index f6235a0..21417ab 100644 --- a/src/evdev-mt-touchpad-buttons.c +++ b/src/evdev-mt-touchpad-buttons.c @@ -484,6 +484,67 @@ tp_process_button(struct tp_dispatch *tp, return 0; } +void +tp_release_all_buttons(struct tp_dispatch *tp, + uint64_t time) +{ + if (tp->buttons.state) { + tp->buttons.state = 0; + tp->queued |= TOUCHPAD_EVENT_BUTTON_RELEASE; + } +} + +void +tp_init_softbuttons(struct tp_dispatch *tp, + struct evdev_device *device, + double topbutton_size_mult) +{ + int width, height; + const struct input_absinfo *absinfo_x, *absinfo_y; + int xoffset, yoffset; + int yres; + + absinfo_x = device->abs.absinfo_x; + absinfo_y = device->abs.absinfo_y; + + xoffset = absinfo_x->minimum, + yoffset = absinfo_y->minimum; + yres = absinfo_y->resolution; + width = abs(absinfo_x->maximum - absinfo_x->minimum); + height = abs(absinfo_y->maximum - absinfo_y->minimum); + + /* button height: 10mm or 15% of the touchpad height, + whichever is smaller */ + if (yres > 1 && (height * 0.15/yres) > 10) { + tp->buttons.bottom_area.top_edge = + absinfo_y->maximum - 10 * yres; + } else { + tp->buttons.bottom_area.top_edge = height * .85 + yoffset; + } + + tp->buttons.bottom_area.rightbutton_left_edge = width/2 + xoffset; + + if (tp->buttons.has_topbuttons) { + /* T440s has the top button line 5mm from the top, event + analysis has shown events to start down to ~10mm from the + top - which maps to 15%. We allow the caller to enlarge the + area using a multiplier for the touchpad disabled case. */ + double topsize_mm = 10 * topbutton_size_mult; + double topsize_pct = .15 * topbutton_size_mult; + + if (yres > 1) { + tp->buttons.top_area.bottom_edge = + yoffset + topsize_mm * yres; + } else { + tp->buttons.top_area.bottom_edge = height * topsize_pct + yoffset; + } + tp->buttons.top_area.rightbutton_left_edge = width * .58 + xoffset; + tp->buttons.top_area.leftbutton_right_edge = width * .42 + xoffset; + } else { + tp->buttons.top_area.bottom_edge = INT_MIN; + } +} + int tp_init_buttons(struct tp_dispatch *tp, struct evdev_device *device) @@ -525,36 +586,7 @@ tp_init_buttons(struct tp_dispatch *tp, tp->buttons.use_clickfinger = true; if (tp->buttons.is_clickpad && !tp->buttons.use_clickfinger) { - int xoffset = absinfo_x->minimum, - yoffset = absinfo_y->minimum; - int yres = absinfo_y->resolution; - - /* button height: 10mm or 15% of the touchpad height, - whichever is smaller */ - if (yres > 1 && (height * 0.15/yres) > 10) { - tp->buttons.bottom_area.top_edge = - absinfo_y->maximum - 10 * yres; - } else { - tp->buttons.bottom_area.top_edge = height * .85 + yoffset; - } - - tp->buttons.bottom_area.rightbutton_left_edge = width/2 + xoffset; - - if (tp->buttons.has_topbuttons) { - /* T440s has the top button line 5mm from the top, - event analysis has shown events to start down to ~10mm - from the top - which maps to 15% */ - if (yres > 1) { - tp->buttons.top_area.bottom_edge = - yoffset + 10 * yres; - } else { - tp->buttons.top_area.bottom_edge = height * .15 + yoffset; - } - tp->buttons.top_area.rightbutton_left_edge = width * .58 + xoffset; - tp->buttons.top_area.leftbutton_right_edge = width * .42 + xoffset; - } else { - tp->buttons.top_area.bottom_edge = INT_MIN; - } + tp_init_softbuttons(tp, device, 1.0); } else { tp->buttons.bottom_area.top_edge = INT_MAX; tp->buttons.top_area.bottom_edge = INT_MIN; @@ -648,16 +680,46 @@ tp_post_physical_buttons(struct tp_dispatch *tp, uint64_t time) return 0; } +static void +tp_notify_softbutton(struct tp_dispatch *tp, + uint64_t time, + uint32_t button, + uint32_t is_topbutton, + enum libinput_button_state state) +{ + /* If we've a trackpoint, send top buttons through the trackpoint */ + if (is_topbutton && tp->buttons.trackpoint) { + struct evdev_dispatch *dispatch = tp->buttons.trackpoint->dispatch; + struct input_event event; + + event.time.tv_sec = time/1000; + event.time.tv_usec = (time % 1000) * 1000; + event.type = EV_KEY; + event.code = button; + event.value = (state == LIBINPUT_BUTTON_STATE_PRESSED) ? 1 : 0; + dispatch->interface->process(dispatch, tp->buttons.trackpoint, + &event, time); + return; + } + + /* Ignore button events not for the trackpoint while suspended */ + if (tp->device->suspended) + return; + + evdev_pointer_notify_button(tp->device, time, button, state); +} + static int tp_post_softbutton_buttons(struct tp_dispatch *tp, uint64_t time) { - uint32_t current, old, button; + uint32_t current, old, button, is_top; enum libinput_button_state state; enum { AREA = 0x01, LEFT = 0x02, MIDDLE = 0x04, RIGHT = 0x08 }; current = tp->buttons.state; old = tp->buttons.old_state; button = 0; + is_top = 0; if (!tp->buttons.click_pending && current == old) return 0; @@ -670,15 +732,18 @@ tp_post_softbutton_buttons(struct tp_dispatch *tp, uint64_t time) case BUTTON_EVENT_IN_AREA: button |= AREA; break; - case BUTTON_EVENT_IN_BOTTOM_L: case BUTTON_EVENT_IN_TOP_L: + is_top = 1; + case BUTTON_EVENT_IN_BOTTOM_L: button |= LEFT; break; case BUTTON_EVENT_IN_TOP_M: + is_top = 1; button |= MIDDLE; break; - case BUTTON_EVENT_IN_BOTTOM_R: case BUTTON_EVENT_IN_TOP_R: + is_top = 1; + case BUTTON_EVENT_IN_BOTTOM_R: button |= RIGHT; break; default: @@ -700,21 +765,21 @@ tp_post_softbutton_buttons(struct tp_dispatch *tp, uint64_t time) button = BTN_LEFT; tp->buttons.active = button; + tp->buttons.active_is_topbutton = is_top; state = LIBINPUT_BUTTON_STATE_PRESSED; } else { button = tp->buttons.active; + is_top = tp->buttons.active_is_topbutton; tp->buttons.active = 0; + tp->buttons.active_is_topbutton = 0; state = LIBINPUT_BUTTON_STATE_RELEASED; } tp->buttons.click_pending = false; - if (button) { - evdev_pointer_notify_button(tp->device, - time, - button, - state); - } + if (button) + tp_notify_softbutton(tp, time, button, is_top, state); + return 1; }