From 0a8f62d8c7116be9e344f351df679599908fb29c Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Thu, 4 Jun 2020 19:10:07 -0700 Subject: refactored --- sys/cmd/dwm/input.c | 333 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 333 insertions(+) create mode 100644 sys/cmd/dwm/input.c (limited to 'sys/cmd/dwm/input.c') diff --git a/sys/cmd/dwm/input.c b/sys/cmd/dwm/input.c new file mode 100644 index 0000000..b035e9a --- /dev/null +++ b/sys/cmd/dwm/input.c @@ -0,0 +1,333 @@ +#include "dwm.h" + +/* local callbacks */ +static void scroll(struct wl_listener *ev, void *arg); +static void frame(struct wl_listener *ev, void *arg); +static void click(struct wl_listener *ev, void *arg); +static void relmove(struct wl_listener *ev, void *arg); +static void absmove(struct wl_listener *ev, void *arg); + +static void setcursor(struct wl_listener *ev, void *arg); +static void setsel(struct wl_listener *ev, void *arg); +static void setpsel(struct wl_listener *ev, void *arg); + +static void keypress(struct wl_listener *ev, void *arg); +static void modifier(struct wl_listener *ev, void *arg); + +/* global variables */ +Mouse mouse = { + .mode = 0, + .manager = nil, + .cursor = nil, + .ev = { + .axis = {.notify=scroll}, + .button = {.notify=click}, + .frame = {.notify=frame}, + .motion = {.notify=relmove}, + .absmotion = {.notify=absmove}, + .cursor = {.notify=setcursor}, + .sel = {.notify=setsel}, + .psel = {.notify=setpsel}, + }, +}; + +Grab grab = { 0 }; + +// ----------------------------------------------------------------------- +// callback function implementations + +/* input devices */ +static +void +newkeyboard(struct wlr_input_device *dev) +{ + Keyboard *kb; + struct xkb_context *ctx; + struct xkb_keymap *map; + + kb = dev->data = calloc(1, sizeof(*kb)); + kb->dev = dev; + + ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + map = xkb_map_new_from_names(ctx, &xkb_rules, XKB_KEYMAP_COMPILE_NO_FLAGS); + + wlr_keyboard_set_keymap(dev->keyboard, map); + xkb_keymap_unref(map); + xkb_context_unref(ctx); + + wlr_keyboard_set_repeat_info(dev->keyboard, 25, 600); + + /* install callbacks */ + kb->ev.modifier.notify = modifier; + kb->ev.keypress.notify = keypress; + + wl_signal_add(&dev->keyboard->events.modifiers, &kb->ev.modifier); + wl_signal_add(&dev->keyboard->events.key, &kb->ev.keypress); + + /* NOTE: we only look at the last keyboard given right now */ + wlr_seat_set_keyboard(dwm.seat, dev); + + wl_list_insert(&dwm.keyboards, &kb->link); +} + +static +void +newmouse(struct wlr_input_device *dev) +{ + /* NOTE: we only look at one mouse right now */ + wlr_cursor_attach_input_device(mouse.cursor, dev); +} + +void +ev·newinput(struct wl_listener *ev, void *arg) +{ + uint32 c; + struct wlr_input_device *dev; + + dev = arg; + switch (dev->type) { + case WLR_INPUT_DEVICE_KEYBOARD: + newkeyboard(dev); + break; + case WLR_INPUT_DEVICE_POINTER: + newmouse(dev); + break; + default: + ; + } + + c = WL_SEAT_CAPABILITY_POINTER; + if (!wl_list_empty(&dwm.keyboards)) + c |= WL_SEAT_CAPABILITY_KEYBOARD; + wlr_seat_set_capabilities(dwm.seat, c); +} + +/* mouse input */ + +static +void +scroll(struct wl_listener *ev, void *arg) +{ + struct wlr_event_pointer_axis *axis; + + axis = arg; + wlr_seat_pointer_notify_axis(dwm.seat, + axis->time_msec, + axis->orientation, + axis->delta, + axis->delta_discrete, + axis->source); +} + +void +click(struct wl_listener *ev, void *arg) +{ + uint32 mods; + Client *c; + const Button *b; + struct wlr_surface *surf; + struct wlr_keyboard *keyb; + struct wlr_event_pointer_button *button; + + button = arg; + switch (button->state) { + case WLR_BUTTON_PRESSED: + if ((c = clientat(mouse.cursor->x, mouse.cursor->y))) { + surf = wlr_xdg_surface_surface_at(c->surf, + mouse.cursor->x - c->dim.x - c->bw, + mouse.cursor->y - c->dim.y - c->bw, + nil, nil + ); + setfocus(c, surf, 1); + } + + keyb = wlr_seat_get_keyboard(dwm.seat); + mods = wlr_keyboard_get_modifiers(keyb); + for (b = buttons; b < arrend(buttons); b++) { + if (CLEANMASK(mods) == CLEANMASK(b->mod) && + button->button == b->kind && b->func) { + b->func(&b->arg); + return; + } + } + break; + + case WLR_BUTTON_RELEASED: + if (mouse.mode != MouseNormal) { + wlr_xcursor_manager_set_cursor_image(mouse.manager, "left_ptr", mouse.cursor); + mouse.mode = MouseNormal; + monitor = monitorat(mouse.cursor->x, mouse.cursor->y); + setmonitor(grab.c, monitor, 0); + } + } + + wlr_seat_pointer_notify_button(dwm.seat, button->time_msec, button->button, button->state); +} + +static +void +frame(struct wl_listener *ev, void *arg) +{ + wlr_seat_pointer_notify_frame(dwm.seat); +} + +static +void +notify(uint32 time) +{ + Client *c; + double sx, sy; + struct wlr_surface *surf; + + if (sloppyfocus) + monitor = monitorat(mouse.cursor->x, mouse.cursor->y); + + switch (mouse.mode) { + case MouseMove: + resize(grab.c, + mouse.cursor->x - grab.x, + mouse.cursor->y - grab.y, + grab.c->dim.width, grab.c->dim.height, 1); + return; + + case MouseResize: + resize(grab.c, + grab.c->dim.x, grab.c->dim.y, + mouse.cursor->x - grab.c->dim.x, + mouse.cursor->y - grab.c->dim.y, 1); + return; + + case MouseNormal: + default: + ; + } + + surf = nil; + if ((c = clientat(mouse.cursor->x, mouse.cursor->y))) + surf = wlr_xdg_surface_surface_at(c->surf, + mouse.cursor->x - c->dim.x - c->bw, + mouse.cursor->y - c->dim.y - c->bw, + &sx, &sy); + + if (!surf) + wlr_xcursor_manager_set_cursor_image(mouse.manager, "left_ptr", mouse.cursor); + + pointerfocus(c, surf, sx, sy, time); +} + +static +void +relmove(struct wl_listener *ev, void *arg) +{ + struct wlr_event_pointer_motion *mv; + + mv = arg; + wlr_cursor_move(mouse.cursor, mv->device, mv->delta_x, mv->delta_y); + notify(mv->time_msec); +} + +static +void +absmove(struct wl_listener *ev, void *arg) +{ + struct wlr_event_pointer_motion_absolute *mv; + + mv = arg; + wlr_cursor_warp_absolute(mouse.cursor, mv->device, mv->x, mv->y); + notify(mv->time_msec); +} + +/* cursor images */ +static +void +setcursor(struct wl_listener *ev, void *arg) +{ + struct wlr_seat_pointer_request_set_cursor_event *cur; + + cur = arg; + if (mouse.mode != MouseNormal) + return; + + if (cur->seat_client == dwm.seat->pointer_state.focused_client) + wlr_cursor_set_surface(mouse.cursor, cur->surface, cur->hotspot_x, cur->hotspot_y); +} + +static +void +setpsel(struct wl_listener *ev, void *arg) +{ + struct wlr_seat_request_set_primary_selection_event *psel; + + psel = arg; + wlr_seat_set_primary_selection(dwm.seat, psel->source, psel->serial); +} + +static +void +setsel(struct wl_listener *ev, void *arg) +{ + struct wlr_seat_request_set_selection_event *sel; + + sel = arg; + wlr_seat_set_selection(dwm.seat, sel->source, sel->serial); +} + +/* keyboards */ + +static +int +dokey(uint32 mods, xkb_keysym_t sym) +{ + int h; + const Key *k, *e; + + h = 0; + for (k = keys, e = arrend(keys); k < e; k++) + if (CLEANMASK(mods) == CLEANMASK(k->mod) && sym == k->sym && k->func) { + k->func(&k->arg); + h = 1; + } + + return h; +} + +static +void +modifier(struct wl_listener *ev, void *arg) +{ + Keyboard *kb; + + kb = wl_container_of(ev, kb, ev.modifier); + wlr_seat_set_keyboard(dwm.seat, kb->dev); + + wlr_seat_keyboard_notify_modifiers(dwm.seat, &kb->dev->keyboard->modifiers); +} + +static +void +keypress(struct wl_listener *ev, void *arg) +{ + Keyboard *kb; + int i, n, hit; + uint32 code, mods; + const xkb_keysym_t *syms; + struct wlr_event_keyboard_key *key; + + key = arg; + kb = wl_container_of(ev, kb, ev.keypress); + + code = key->keycode + 8; + n = xkb_state_key_get_syms(kb->dev->keyboard->xkb_state, code, &syms); + mods = wlr_keyboard_get_modifiers(kb->dev->keyboard); + + hit = 0; + if (key->state == WLR_KEY_PRESSED) + for (i = 0; i < n; i++) + hit += dokey(mods, syms[i]); + + /* if no binding found, pass the event to the client */ + if (!hit) { + wlr_seat_set_keyboard(dwm.seat, kb->dev); + wlr_seat_keyboard_notify_key(dwm.seat, key->time_msec, key->keycode, key->state); + } +} -- cgit v1.2.1