diff options
Diffstat (limited to 'swaylock/seat.c')
-rw-r--r-- | swaylock/seat.c | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/swaylock/seat.c b/swaylock/seat.c new file mode 100644 index 00000000..522200f2 --- /dev/null +++ b/swaylock/seat.c | |||
@@ -0,0 +1,187 @@ | |||
1 | #include <assert.h> | ||
2 | #include <sys/mman.h> | ||
3 | #include <unistd.h> | ||
4 | #include <wlr/util/log.h> | ||
5 | #include <xkbcommon/xkbcommon.h> | ||
6 | #include "swaylock/swaylock.h" | ||
7 | #include "swaylock/seat.h" | ||
8 | |||
9 | const char *XKB_MASK_NAMES[MASK_LAST] = { | ||
10 | XKB_MOD_NAME_SHIFT, | ||
11 | XKB_MOD_NAME_CAPS, | ||
12 | XKB_MOD_NAME_CTRL, | ||
13 | XKB_MOD_NAME_ALT, | ||
14 | "Mod2", | ||
15 | "Mod3", | ||
16 | XKB_MOD_NAME_LOGO, | ||
17 | "Mod5", | ||
18 | }; | ||
19 | |||
20 | const enum mod_bit XKB_MODS[MASK_LAST] = { | ||
21 | MOD_SHIFT, | ||
22 | MOD_CAPS, | ||
23 | MOD_CTRL, | ||
24 | MOD_ALT, | ||
25 | MOD_MOD2, | ||
26 | MOD_MOD3, | ||
27 | MOD_LOGO, | ||
28 | MOD_MOD5 | ||
29 | }; | ||
30 | |||
31 | static void keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, | ||
32 | uint32_t format, int32_t fd, uint32_t size) { | ||
33 | struct swaylock_state *state = data; | ||
34 | if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { | ||
35 | close(fd); | ||
36 | wlr_log(L_ERROR, "Unknown keymap format %d, aborting", format); | ||
37 | exit(1); | ||
38 | } | ||
39 | char *map_shm = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); | ||
40 | if (map_shm == MAP_FAILED) { | ||
41 | close(fd); | ||
42 | wlr_log(L_ERROR, "Unable to initialize keymap shm, aborting"); | ||
43 | exit(1); | ||
44 | } | ||
45 | struct xkb_keymap *keymap = xkb_keymap_new_from_string( | ||
46 | state->xkb.context, map_shm, XKB_KEYMAP_FORMAT_TEXT_V1, 0); | ||
47 | munmap(map_shm, size); | ||
48 | close(fd); | ||
49 | assert(keymap); | ||
50 | struct xkb_state *xkb_state = xkb_state_new(keymap); | ||
51 | assert(xkb_state); | ||
52 | xkb_keymap_unref(state->xkb.keymap); | ||
53 | xkb_state_unref(state->xkb.state); | ||
54 | state->xkb.keymap = keymap; | ||
55 | state->xkb.state = xkb_state; | ||
56 | } | ||
57 | |||
58 | static void keyboard_enter(void *data, struct wl_keyboard *wl_keyboard, | ||
59 | uint32_t serial, struct wl_surface *surface, struct wl_array *keys) { | ||
60 | // Who cares | ||
61 | } | ||
62 | |||
63 | static void keyboard_leave(void *data, struct wl_keyboard *wl_keyboard, | ||
64 | uint32_t serial, struct wl_surface *surface) { | ||
65 | // Who cares | ||
66 | } | ||
67 | |||
68 | static void keyboard_key(void *data, struct wl_keyboard *wl_keyboard, | ||
69 | uint32_t serial, uint32_t time, uint32_t key, uint32_t _key_state) { | ||
70 | struct swaylock_state *state = data; | ||
71 | enum wl_keyboard_key_state key_state = _key_state; | ||
72 | xkb_keysym_t sym = xkb_state_key_get_one_sym(state->xkb.state, key + 8); | ||
73 | uint32_t keycode = key_state == WL_KEYBOARD_KEY_STATE_PRESSED ? | ||
74 | key + 8 : 0; | ||
75 | uint32_t codepoint = xkb_state_key_get_utf32(state->xkb.state, keycode); | ||
76 | wlr_log(L_DEBUG, "%c %d", codepoint, sym); | ||
77 | } | ||
78 | |||
79 | static void keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, | ||
80 | uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, | ||
81 | uint32_t mods_locked, uint32_t group) { | ||
82 | struct swaylock_state *state = data; | ||
83 | xkb_state_update_mask(state->xkb.state, | ||
84 | mods_depressed, mods_latched, mods_locked, 0, 0, group); | ||
85 | xkb_mod_mask_t mask = xkb_state_serialize_mods(state->xkb.state, | ||
86 | XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED); | ||
87 | state->xkb.modifiers = 0; | ||
88 | for (uint32_t i = 0; i < MASK_LAST; ++i) { | ||
89 | if (mask & state->xkb.masks[i]) { | ||
90 | state->xkb.modifiers |= XKB_MODS[i]; | ||
91 | } | ||
92 | } | ||
93 | } | ||
94 | |||
95 | static void keyboard_repeat_info(void *data, struct wl_keyboard *wl_keyboard, | ||
96 | int32_t rate, int32_t delay) { | ||
97 | // TODO | ||
98 | } | ||
99 | |||
100 | static const struct wl_keyboard_listener keyboard_listener = { | ||
101 | .keymap = keyboard_keymap, | ||
102 | .enter = keyboard_enter, | ||
103 | .leave = keyboard_leave, | ||
104 | .key = keyboard_key, | ||
105 | .modifiers = keyboard_modifiers, | ||
106 | .repeat_info = keyboard_repeat_info, | ||
107 | }; | ||
108 | |||
109 | static void wl_pointer_enter(void *data, struct wl_pointer *wl_pointer, | ||
110 | uint32_t serial, struct wl_surface *surface, | ||
111 | wl_fixed_t surface_x, wl_fixed_t surface_y) { | ||
112 | wl_pointer_set_cursor(wl_pointer, serial, NULL, 0, 0); | ||
113 | } | ||
114 | |||
115 | static void wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, | ||
116 | uint32_t serial, struct wl_surface *surface) { | ||
117 | // Who cares | ||
118 | } | ||
119 | |||
120 | static void wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, | ||
121 | uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) { | ||
122 | // Who cares | ||
123 | } | ||
124 | |||
125 | static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer, | ||
126 | uint32_t serial, uint32_t time, uint32_t button, uint32_t state) { | ||
127 | // Who cares | ||
128 | } | ||
129 | |||
130 | static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, | ||
131 | uint32_t time, uint32_t axis, wl_fixed_t value) { | ||
132 | // Who cares | ||
133 | } | ||
134 | |||
135 | static void wl_pointer_frame(void *data, struct wl_pointer *wl_pointer) { | ||
136 | // Who cares | ||
137 | } | ||
138 | |||
139 | static void wl_pointer_axis_source(void *data, struct wl_pointer *wl_pointer, | ||
140 | uint32_t axis_source) { | ||
141 | // Who cares | ||
142 | } | ||
143 | |||
144 | static void wl_pointer_axis_stop(void *data, struct wl_pointer *wl_pointer, | ||
145 | uint32_t time, uint32_t axis) { | ||
146 | // Who cares | ||
147 | } | ||
148 | |||
149 | static void wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer, | ||
150 | uint32_t axis, int32_t discrete) { | ||
151 | // Who cares | ||
152 | } | ||
153 | |||
154 | static const struct wl_pointer_listener pointer_listener = { | ||
155 | .enter = wl_pointer_enter, | ||
156 | .leave = wl_pointer_leave, | ||
157 | .motion = wl_pointer_motion, | ||
158 | .button = wl_pointer_button, | ||
159 | .axis = wl_pointer_axis, | ||
160 | .frame = wl_pointer_frame, | ||
161 | .axis_source = wl_pointer_axis_source, | ||
162 | .axis_stop = wl_pointer_axis_stop, | ||
163 | .axis_discrete = wl_pointer_axis_discrete, | ||
164 | }; | ||
165 | |||
166 | static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat, | ||
167 | enum wl_seat_capability caps) { | ||
168 | struct swaylock_state *state = data; | ||
169 | if ((caps & WL_SEAT_CAPABILITY_POINTER)) { | ||
170 | struct wl_pointer *pointer = wl_seat_get_pointer(wl_seat); | ||
171 | wl_pointer_add_listener(pointer, &pointer_listener, NULL); | ||
172 | } | ||
173 | if ((caps & WL_SEAT_CAPABILITY_KEYBOARD)) { | ||
174 | struct wl_keyboard *keyboard = wl_seat_get_keyboard(wl_seat); | ||
175 | wl_keyboard_add_listener(keyboard, &keyboard_listener, state); | ||
176 | } | ||
177 | } | ||
178 | |||
179 | static void seat_handle_name(void *data, struct wl_seat *wl_seat, | ||
180 | const char *name) { | ||
181 | // Who cares | ||
182 | } | ||
183 | |||
184 | const struct wl_seat_listener seat_listener = { | ||
185 | .capabilities = seat_handle_capabilities, | ||
186 | .name = seat_handle_name, | ||
187 | }; | ||