aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/dwm/input.c
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2020-06-04 19:10:07 -0700
committerNicholas Noll <nbnoll@eml.cc>2020-06-04 19:10:07 -0700
commit0a8f62d8c7116be9e344f351df679599908fb29c (patch)
treebcf7fcf995b4cb97cec0b947e2b299d6bcc8ae1d /sys/cmd/dwm/input.c
parentea50cbe1bf103372a3461c80cb172f4fb4167088 (diff)
refactored
Diffstat (limited to 'sys/cmd/dwm/input.c')
-rw-r--r--sys/cmd/dwm/input.c333
1 files changed, 333 insertions, 0 deletions
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);
+ }
+}