chiark / gitweb /
terminal: free xkb state on keyboard destruction
[elogind.git] / src / libsystemd-terminal / idev.h
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>
29 #include <libudev.h>
30 #include <linux/input.h>
31 #include <stdbool.h>
32 #include <stdlib.h>
33 #include <systemd/sd-bus.h>
34 #include <systemd/sd-event.h>
35 #include <xkbcommon/xkbcommon.h>
36 #include "util.h"
37
38 typedef struct idev_data                idev_data;
39 typedef struct idev_data_evdev          idev_data_evdev;
40 typedef struct idev_data_keyboard       idev_data_keyboard;
41
42 typedef struct idev_event               idev_event;
43 typedef struct idev_device              idev_device;
44 typedef struct idev_session             idev_session;
45 typedef struct idev_context             idev_context;
46
47 /*
48  * Types
49  */
50
51 enum {
52         IDEV_ELEMENT_EVDEV,
53         IDEV_ELEMENT_CNT
54 };
55
56 enum {
57         IDEV_DEVICE_KEYBOARD,
58         IDEV_DEVICE_CNT
59 };
60
61 /*
62  * Evdev Elements
63  */
64
65 struct idev_data_evdev {
66         struct input_event event;
67 };
68
69 /*
70  * Keyboard Devices
71  */
72
73 struct xkb_state;
74
75 enum {
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
90 enum {
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
101 struct 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
113 /*
114  * Data Packets
115  */
116
117 enum {
118         IDEV_DATA_RESYNC,
119         IDEV_DATA_EVDEV,
120         IDEV_DATA_KEYBOARD,
121         IDEV_DATA_CNT
122 };
123
124 struct idev_data {
125         unsigned int type;
126         bool resync : 1;
127
128         union {
129                 idev_data_evdev evdev;
130                 idev_data_keyboard keyboard;
131         };
132 };
133
134 /*
135  * Events
136  */
137
138 enum {
139         IDEV_EVENT_DEVICE_ADD,
140         IDEV_EVENT_DEVICE_REMOVE,
141         IDEV_EVENT_DEVICE_DATA,
142         IDEV_EVENT_CNT
143 };
144
145 struct idev_event {
146         unsigned int type;
147         union {
148                 struct {
149                         idev_device *device;
150                 } device_add, device_remove;
151
152                 struct {
153                         idev_device *device;
154                         idev_data data;
155                 } device_data;
156         };
157 };
158
159 typedef int (*idev_event_fn) (idev_session *s, void *userdata, idev_event *ev);
160
161 /*
162  * Devices
163  */
164
165 void idev_device_enable(idev_device *d);
166 void idev_device_disable(idev_device *d);
167
168 /*
169  * Sessions
170  */
171
172 enum {
173         IDEV_SESSION_CUSTOM                     = (1 << 0),
174         IDEV_SESSION_MANAGED                    = (1 << 1),
175 };
176
177 int idev_session_new(idev_session **out,
178                      idev_context *c,
179                      unsigned int flags,
180                      const char *name,
181                      idev_event_fn event_fn,
182                      void *userdata);
183 idev_session *idev_session_free(idev_session *s);
184
185 DEFINE_TRIVIAL_CLEANUP_FUNC(idev_session*, idev_session_free);
186
187 bool idev_session_is_enabled(idev_session *s);
188 void idev_session_enable(idev_session *s);
189 void idev_session_disable(idev_session *s);
190
191 int idev_session_add_evdev(idev_session *s, struct udev_device *ud);
192 int idev_session_remove_evdev(idev_session *s, struct udev_device *ud);
193
194 /*
195  * Contexts
196  */
197
198 int idev_context_new(idev_context **out, sd_event *event, sd_bus *sysbus);
199 idev_context *idev_context_ref(idev_context *c);
200 idev_context *idev_context_unref(idev_context *c);
201
202 DEFINE_TRIVIAL_CLEANUP_FUNC(idev_context*, idev_context_unref);