kmscon: add --xkb-repeat-rate/delay command-line arguments
[platform/upstream/kmscon.git] / src / uterm.h
1 /*
2  * uterm - Linux User-Space Terminal
3  *
4  * Copyright (c) 2011-2012 David Herrmann <dh.herrmann@googlemail.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files
8  * (the "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25
26 /*
27  * Linux User-Space Terminal
28  * Historically, terminals were implemented in kernel-space on linux. With the
29  * development of KMS and the linux input-API it is now possible to implement
30  * all we need in user-space. This allows to disable the in-kernel CONFIG_VT and
31  * similar options and reduce the kernel-overhead.
32  * This library provides an API to implement terminals in user-space. This is
33  * not limited to classic text-terminals but rather to all kind of applications
34  * that need graphical output (with OpenGL) or direct keyboard/mouse/etc. input
35  * from the kernel.
36  */
37
38 #ifndef UTERM_UTERM_H
39 #define UTERM_UTERM_H
40
41 #include <inttypes.h>
42 #include <stdbool.h>
43 #include <stdlib.h>
44 #include "eloop.h"
45
46 /*
47  * Video Control
48  * Linux provides 2 famous ways to access the video hardware: fbdev and drm
49  * fbdev is the older one of both and is simply a mmap() of the framebuffer into
50  * main memory. It does not allow 3D acceleration and if you need 2D
51  * acceleration you should use libraries like cairo to draw into the framebuffer
52  * provided by this library.
53  * DRM is the new approach which provides 3D acceleration with mesa. It allows
54  * much more configuration as fbdev and is the recommended way to access video
55  * hardware on modern computers.
56  * Modern mesa provides 3D acceleration on fbdev, too. This is used in systems
57  * like Android. This will allow us to provide an fbdev backend here.
58  *
59  * Famous linux graphics systems like X.Org/X11 or Wayland use fbdev or DRM
60  * internally to access the video hardware. This API allows low-level access to
61  * fbdev and DRM without the need of X.Org/X11 or Wayland. If VT support is
62  * enabled in your kernel, each application can run on a different VT. For
63  * instance, X.Org may run on VT-7, Wayland on VT-8, your application on VT-9
64  * and default consoles on VT-1 to VT-6. You can switch between them with
65  * ctrl-alt-F1-F12.
66  * If VT support is not available (very unlikely) you need other ways to switch
67  * between applications.
68  *
69  * The main object by this API is uterm_video. This object attaches to a single
70  * graphics card via DRM or on a single frambuffer via fbdev. Many DRM drivers
71  * also provide an fbdev driver so you must go sure not to write to both
72  * simulatneously. Use "UTERM_VIDEO_DRM" to scan for DRM devices. Otherwise,
73  * fbdev is used. DRM is the recommended way. Use fbdev only on embedded devices
74  * which do not come with an DRM driver.
75  * The uterm_video object scans for graphic-cards and connected displays. Each
76  * display is represented as a uterm_display object. The uterm_video object is
77  * hotplug-capable so it reports if a display is connected or disconnected.
78  * Each uterm_display object can be activated/deactivated independently of the
79  * other displays. To draw to a display you need to create a uterm_screen object
80  * and add your display to the screen. The screen object allows to spread a
81  * single screen onto multiple displays. Currently, the uterm_screen object
82  * allows only one display per screen but we may extend this in the future.
83  *
84  * If you are using fbdev, you *must* correctly destroy your uterm_video object
85  * and also call uterm_video_segfault() if you abnormally abort your
86  * application. Otherwise your video device remains in undefined state and other
87  * applications might not display correctly.
88  * If you use DRM, the same operations are recommended but not required as the
89  * kernel can correctly reset video devices on its own.
90  */
91
92 struct uterm_screen;
93 struct uterm_mode;
94 struct uterm_display;
95 struct uterm_video;
96
97 enum uterm_display_state {
98         UTERM_DISPLAY_ACTIVE,
99         UTERM_DISPLAY_ASLEEP,
100         UTERM_DISPLAY_INACTIVE,
101         UTERM_DISPLAY_GONE,
102 };
103
104 enum uterm_display_dpms {
105         UTERM_DPMS_ON,
106         UTERM_DPMS_STANDBY,
107         UTERM_DPMS_SUSPEND,
108         UTERM_DPMS_OFF,
109         UTERM_DPMS_UNKNOWN,
110 };
111
112 enum uterm_video_type {
113         UTERM_VIDEO_DRM,
114         UTERM_VIDEO_DUMB,
115         UTERM_VIDEO_FBDEV,
116 };
117
118 enum uterm_video_action {
119         UTERM_WAKE_UP,
120         UTERM_SLEEP,
121         UTERM_NEW,
122         UTERM_GONE,
123 };
124
125 struct uterm_video_hotplug {
126         struct uterm_display *display;
127         int action;
128 };
129
130 enum uterm_video_format {
131         UTERM_FORMAT_GREY,
132         UTERM_FORMAT_XRGB32,
133 };
134
135 struct uterm_video_buffer {
136         unsigned int width;
137         unsigned int height;
138         unsigned int stride;
139         unsigned int format;
140         uint8_t *data;
141 };
142
143 struct uterm_video_blend_req {
144         const struct uterm_video_buffer *buf;
145         unsigned int x;
146         unsigned int y;
147         uint8_t fr;
148         uint8_t fg;
149         uint8_t fb;
150         uint8_t br;
151         uint8_t bg;
152         uint8_t bb;
153 };
154
155 typedef void (*uterm_video_cb) (struct uterm_video *video,
156                                 struct uterm_video_hotplug *arg,
157                                 void *data);
158
159 /* misc */
160
161 const char *uterm_dpms_to_name(int dpms);
162
163 /* screen interface */
164
165 int uterm_screen_new_single(struct uterm_screen **out,
166                                 struct uterm_display *disp);
167 void uterm_screen_ref(struct uterm_screen *screen);
168 void uterm_screen_unref(struct uterm_screen *screen);
169
170 unsigned int uterm_screen_width(struct uterm_screen *screen);
171 unsigned int uterm_screen_height(struct uterm_screen *screen);
172
173 int uterm_screen_use(struct uterm_screen *screen);
174 int uterm_screen_swap(struct uterm_screen *screen);
175 int uterm_screen_blit(struct uterm_screen *screen,
176                       const struct uterm_video_buffer *buf,
177                       unsigned int x, unsigned int y);
178 int uterm_screen_blend(struct uterm_screen *screen,
179                        const struct uterm_video_buffer *buf,
180                        unsigned int x, unsigned int y,
181                        uint8_t fr, uint8_t fg, uint8_t fb,
182                        uint8_t br, uint8_t bg, uint8_t bb);
183 int uterm_screen_blendv(struct uterm_screen *screen,
184                         const struct uterm_video_blend_req *req, size_t num);
185 int uterm_screen_fill(struct uterm_screen *screen,
186                       uint8_t r, uint8_t g, uint8_t b,
187                       unsigned int x, unsigned int y,
188                       unsigned int width, unsigned int height);
189
190 /* display modes interface */
191
192 void uterm_mode_ref(struct uterm_mode *mode);
193 void uterm_mode_unref(struct uterm_mode *mode);
194 struct uterm_mode *uterm_mode_next(struct uterm_mode *mode);
195
196 const char *uterm_mode_get_name(const struct uterm_mode *mode);
197 unsigned int uterm_mode_get_width(const struct uterm_mode *mode);
198 unsigned int uterm_mode_get_height(const struct uterm_mode *mode);
199
200 /* display interface */
201
202 void uterm_display_ref(struct uterm_display *disp);
203 void uterm_display_unref(struct uterm_display *disp);
204 struct uterm_display *uterm_display_next(struct uterm_display *disp);
205
206 struct uterm_mode *uterm_display_get_modes(struct uterm_display *disp);
207 struct uterm_mode *uterm_display_get_current(struct uterm_display *disp);
208 struct uterm_mode *uterm_display_get_default(struct uterm_display *disp);
209
210 int uterm_display_get_state(struct uterm_display *disp);
211 int uterm_display_activate(struct uterm_display *disp, struct uterm_mode *mode);
212 void uterm_display_deactivate(struct uterm_display *disp);
213 int uterm_display_set_dpms(struct uterm_display *disp, int state);
214 int uterm_display_get_dpms(const struct uterm_display *disp);
215
216 int uterm_display_use(struct uterm_display *disp);
217 int uterm_display_swap(struct uterm_display *disp);
218
219 int uterm_display_fake_blend(struct uterm_display *disp,
220                              const struct uterm_video_buffer *buf,
221                              unsigned int x, unsigned int y,
222                              uint8_t fr, uint8_t fg, uint8_t fb,
223                              uint8_t br, uint8_t bg, uint8_t bb);
224 int uterm_display_fake_blendv(struct uterm_display *disp,
225                               const struct uterm_video_blend_req *req,
226                               size_t num);
227
228 /* video interface */
229
230 int uterm_video_new(struct uterm_video **out,
231                         struct ev_eloop *eloop,
232                         unsigned int type,
233                         const char *node);
234 void uterm_video_ref(struct uterm_video *video);
235 void uterm_video_unref(struct uterm_video *video);
236
237 void uterm_video_segfault(struct uterm_video *video);
238 int uterm_video_use(struct uterm_video *video);
239 struct uterm_display *uterm_video_get_displays(struct uterm_video *video);
240 int uterm_video_register_cb(struct uterm_video *video, uterm_video_cb cb,
241                                 void *data);
242 void uterm_video_unregister_cb(struct uterm_video *video, uterm_video_cb cb,
243                                 void *data);
244
245 void uterm_video_sleep(struct uterm_video *video);
246 int uterm_video_wake_up(struct uterm_video *video);
247 bool uterm_video_is_awake(struct uterm_video *video);
248 void uterm_video_poll(struct uterm_video *video);
249
250 /*
251  * Input Devices
252  * This input object can combine multiple linux input devices into a single
253  * device and notifies the application about events. It has several different
254  * keyboard backends so the full XKB feature set is available.
255  */
256
257 struct uterm_input;
258
259 /* keep in sync with shl_xkb_mods */
260 enum uterm_input_modifier {
261         UTERM_SHIFT_MASK        = (1 << 0),
262         UTERM_LOCK_MASK         = (1 << 1),
263         UTERM_CONTROL_MASK      = (1 << 2),
264         UTERM_ALT_MASK          = (1 << 3),
265         UTERM_LOGO_MASK         = (1 << 4),
266 };
267
268 /* keep in sync with TSM_VTE_INVALID */
269 #define UTERM_INPUT_INVALID 0xffffffff
270
271 struct uterm_input_event {
272         bool handled;           /* user-controlled, default is false */
273         uint16_t keycode;       /* linux keycode - KEY_* - linux/input.h */
274         uint32_t ascii;         /* ascii keysym for @keycode */
275         unsigned int mods;      /* active modifiers - uterm_modifier mask */
276
277         unsigned int num_syms;  /* number of keysyms */
278         uint32_t *keysyms;      /* XKB-common keysym-array - XKB_KEY_* */
279         uint32_t *codepoints;   /* ucs4 unicode value or UTERM_INPUT_INVALID */
280 };
281
282 #define UTERM_INPUT_HAS_MODS(_ev, _mods) (((_ev)->mods & (_mods)) == (_mods))
283
284 typedef void (*uterm_input_cb) (struct uterm_input *input,
285                                 struct uterm_input_event *ev,
286                                 void *data);
287
288 int uterm_input_new(struct uterm_input **out, struct ev_eloop *eloop,
289                     const char *layout,
290                     const char *variant,
291                     const char *options,
292                     unsigned int repeat_delay,
293                     unsigned int repeat_rate);
294 void uterm_input_ref(struct uterm_input *input);
295 void uterm_input_unref(struct uterm_input *input);
296
297 void uterm_input_add_dev(struct uterm_input *input, const char *node);
298 void uterm_input_remove_dev(struct uterm_input *input, const char *node);
299
300 int uterm_input_register_cb(struct uterm_input *input,
301                                 uterm_input_cb cb,
302                                 void *data);
303 void uterm_input_unregister_cb(struct uterm_input *input,
304                                 uterm_input_cb cb,
305                                 void *data);
306
307 void uterm_input_sleep(struct uterm_input *input);
308 void uterm_input_wake_up(struct uterm_input *input);
309 bool uterm_input_is_awake(struct uterm_input *input);
310
311 void uterm_input_keysym_to_string(struct uterm_input *input,
312                                   uint32_t keysym, char *str, size_t size);
313 int uterm_input_string_to_keysym(struct uterm_input *input, const char *n,
314                                  uint32_t *out);
315
316 /*
317  * Virtual Terminals
318  * Virtual terminals allow controlling multiple virtual terminals on one real
319  * terminal. It is multi-seat capable and fully asynchronous.
320  */
321
322 struct uterm_vt;
323 struct uterm_vt_master;
324
325 enum uterm_vt_action {
326         UTERM_VT_ACTIVATE,
327         UTERM_VT_DEACTIVATE,
328 };
329
330 enum uterm_vt_mode {
331         UTERM_VT_REAL,
332         UTERM_VT_FAKE,
333 };
334
335 typedef int (*uterm_vt_cb) (struct uterm_vt *vt, unsigned int action,
336                             void *data);
337
338 int uterm_vt_master_new(struct uterm_vt_master **out,
339                         struct ev_eloop *eloop);
340 void uterm_vt_master_ref(struct uterm_vt_master *vtm);
341 void uterm_vt_master_unref(struct uterm_vt_master *vtm);
342
343 int uterm_vt_master_activate_all(struct uterm_vt_master *vtm);
344 int uterm_vt_master_deactivate_all(struct uterm_vt_master *vtm);
345
346 int uterm_vt_allocate(struct uterm_vt_master *vt, struct uterm_vt **out,
347                       const char *seat, struct uterm_input *input,
348                       const char *vt_for_seat0, uterm_vt_cb cb, void *data);
349 void uterm_vt_deallocate(struct uterm_vt *vt);
350 void uterm_vt_ref(struct uterm_vt *vt);
351 void uterm_vt_unref(struct uterm_vt *vt);
352
353 int uterm_vt_activate(struct uterm_vt *vt);
354 int uterm_vt_deactivate(struct uterm_vt *vt);
355
356 /*
357  * System Monitor
358  * This watches the system for new seats, graphics devices or other devices that
359  * are used by terminals.
360  */
361
362 struct uterm_monitor;
363 struct uterm_monitor_seat;
364 struct uterm_monitor_dev;
365
366 enum uterm_monitor_event_type {
367         UTERM_MONITOR_NEW_SEAT,
368         UTERM_MONITOR_FREE_SEAT,
369         UTERM_MONITOR_NEW_DEV,
370         UTERM_MONITOR_FREE_DEV,
371         UTERM_MONITOR_HOTPLUG_DEV,
372 };
373
374 enum uterm_monitor_dev_type {
375         UTERM_MONITOR_DRM,
376         UTERM_MONITOR_FBDEV,
377         UTERM_MONITOR_FBDEV_DRM,
378         UTERM_MONITOR_INPUT,
379 };
380
381 struct uterm_monitor_event {
382         unsigned int type;
383
384         struct uterm_monitor_seat *seat;
385         const char *seat_name;
386         void *seat_data;
387
388         struct uterm_monitor_dev *dev;
389         unsigned int dev_type;
390         const char *dev_node;
391         void *dev_data;
392 };
393
394 typedef void (*uterm_monitor_cb) (struct uterm_monitor *mon,
395                                         struct uterm_monitor_event *event,
396                                         void *data);
397
398 int uterm_monitor_new(struct uterm_monitor **out,
399                         struct ev_eloop *eloop,
400                         uterm_monitor_cb cb,
401                         void *data);
402 void uterm_monitor_ref(struct uterm_monitor *mon);
403 void uterm_monitor_unref(struct uterm_monitor *mon);
404 void uterm_monitor_scan(struct uterm_monitor *mon);
405
406 void uterm_monitor_set_seat_data(struct uterm_monitor_seat *seat, void *data);
407 void uterm_monitor_set_dev_data(struct uterm_monitor_dev *dev, void *data);
408
409 #endif /* UTERM_UTERM_H */