]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-terminal/idev.h
update TODO
[thirdparty/systemd.git] / src / libsystemd-terminal / idev.h
CommitLineData
e202fa31
DH
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22/*
23 * IDev
24 */
25
26#pragma once
27
28#include <inttypes.h>
c93e5a62
DH
29#include <libudev.h>
30#include <linux/input.h>
e202fa31
DH
31#include <stdbool.h>
32#include <stdlib.h>
33#include <systemd/sd-bus.h>
34#include <systemd/sd-event.h>
e06cc7b0 35#include <xkbcommon/xkbcommon.h>
e202fa31
DH
36#include "util.h"
37
38typedef struct idev_data idev_data;
c93e5a62 39typedef struct idev_data_evdev idev_data_evdev;
e06cc7b0 40typedef struct idev_data_keyboard idev_data_keyboard;
e202fa31
DH
41
42typedef struct idev_event idev_event;
43typedef struct idev_device idev_device;
44typedef struct idev_session idev_session;
45typedef struct idev_context idev_context;
46
47/*
48 * Types
49 */
50
51enum {
c93e5a62 52 IDEV_ELEMENT_EVDEV,
e202fa31
DH
53 IDEV_ELEMENT_CNT
54};
55
56enum {
e06cc7b0 57 IDEV_DEVICE_KEYBOARD,
e202fa31
DH
58 IDEV_DEVICE_CNT
59};
60
c93e5a62
DH
61/*
62 * Evdev Elements
63 */
64
65struct idev_data_evdev {
66 struct input_event event;
67};
68
e06cc7b0
DH
69/*
70 * Keyboard Devices
71 */
72
73struct xkb_state;
74
75enum {
76 IDEV_KBDMOD_IDX_SHIFT,
77 IDEV_KBDMOD_IDX_CTRL,
78 IDEV_KBDMOD_IDX_ALT,
79 IDEV_KBDMOD_IDX_LINUX,
80 IDEV_KBDMOD_IDX_CAPS,
81 IDEV_KBDMOD_CNT,
82
83 IDEV_KBDMOD_SHIFT = 1 << IDEV_KBDMOD_IDX_SHIFT,
84 IDEV_KBDMOD_CTRL = 1 << IDEV_KBDMOD_IDX_CTRL,
85 IDEV_KBDMOD_ALT = 1 << IDEV_KBDMOD_IDX_ALT,
86 IDEV_KBDMOD_LINUX = 1 << IDEV_KBDMOD_IDX_LINUX,
87 IDEV_KBDMOD_CAPS = 1 << IDEV_KBDMOD_IDX_CAPS,
88};
89
90enum {
91 IDEV_KBDLED_IDX_NUM,
92 IDEV_KBDLED_IDX_CAPS,
93 IDEV_KBDLED_IDX_SCROLL,
94 IDEV_KBDLED_CNT,
95
96 IDEV_KBDLED_NUM = 1 << IDEV_KBDLED_IDX_NUM,
97 IDEV_KBDLED_CAPS = 1 << IDEV_KBDLED_IDX_CAPS,
98 IDEV_KBDLED_SCROLL = 1 << IDEV_KBDLED_IDX_SCROLL,
99};
100
101struct idev_data_keyboard {
102 struct xkb_state *xkb_state;
103 int8_t ascii;
104 uint8_t value;
105 uint16_t keycode;
106 uint32_t mods;
107 uint32_t consumed_mods;
108 uint32_t n_syms;
109 uint32_t *keysyms;
110 uint32_t *codepoints;
111};
112
884964a9
DH
113static inline bool idev_kbdmatch(idev_data_keyboard *kdata,
114 uint32_t mods, uint32_t n_syms,
115 const uint32_t *syms) {
116 const uint32_t significant = IDEV_KBDMOD_SHIFT |
117 IDEV_KBDMOD_CTRL |
118 IDEV_KBDMOD_ALT |
119 IDEV_KBDMOD_LINUX;
120 uint32_t real;
121
122 if (n_syms != kdata->n_syms)
123 return false;
124
125 real = kdata->mods & ~kdata->consumed_mods & significant;
62d5068d 126 if (real != mods)
884964a9
DH
127 return false;
128
129 return !memcmp(syms, kdata->keysyms, n_syms * sizeof(*syms));
130}
131
132#define IDEV_KBDMATCH(_kdata, _mods, _sym) \
133 idev_kbdmatch((_kdata), (_mods), 1, (const uint32_t[]){ (_sym) })
134
e202fa31
DH
135/*
136 * Data Packets
137 */
138
139enum {
140 IDEV_DATA_RESYNC,
c93e5a62 141 IDEV_DATA_EVDEV,
e06cc7b0 142 IDEV_DATA_KEYBOARD,
e202fa31
DH
143 IDEV_DATA_CNT
144};
145
146struct idev_data {
147 unsigned int type;
148 bool resync : 1;
c93e5a62
DH
149
150 union {
151 idev_data_evdev evdev;
e06cc7b0 152 idev_data_keyboard keyboard;
c93e5a62 153 };
e202fa31
DH
154};
155
156/*
157 * Events
158 */
159
160enum {
161 IDEV_EVENT_DEVICE_ADD,
162 IDEV_EVENT_DEVICE_REMOVE,
163 IDEV_EVENT_DEVICE_DATA,
164 IDEV_EVENT_CNT
165};
166
167struct idev_event {
168 unsigned int type;
169 union {
170 struct {
171 idev_device *device;
172 } device_add, device_remove;
173
174 struct {
175 idev_device *device;
176 idev_data data;
177 } device_data;
178 };
179};
180
181typedef int (*idev_event_fn) (idev_session *s, void *userdata, idev_event *ev);
182
183/*
184 * Devices
185 */
186
187void idev_device_enable(idev_device *d);
188void idev_device_disable(idev_device *d);
189
190/*
191 * Sessions
192 */
193
194enum {
195 IDEV_SESSION_CUSTOM = (1 << 0),
196 IDEV_SESSION_MANAGED = (1 << 1),
197};
198
199int idev_session_new(idev_session **out,
200 idev_context *c,
201 unsigned int flags,
202 const char *name,
203 idev_event_fn event_fn,
204 void *userdata);
205idev_session *idev_session_free(idev_session *s);
206
207DEFINE_TRIVIAL_CLEANUP_FUNC(idev_session*, idev_session_free);
208
209bool idev_session_is_enabled(idev_session *s);
210void idev_session_enable(idev_session *s);
211void idev_session_disable(idev_session *s);
212
c93e5a62
DH
213int idev_session_add_evdev(idev_session *s, struct udev_device *ud);
214int idev_session_remove_evdev(idev_session *s, struct udev_device *ud);
215
e202fa31
DH
216/*
217 * Contexts
218 */
219
220int idev_context_new(idev_context **out, sd_event *event, sd_bus *sysbus);
221idev_context *idev_context_ref(idev_context *c);
222idev_context *idev_context_unref(idev_context *c);
223
224DEFINE_TRIVIAL_CLEANUP_FUNC(idev_context*, idev_context_unref);