2 * uvtd - User-space VT daemon
4 * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com>
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
28 * Every virtual terminal forms a session inside of uvtd. Sessions are scheduled
29 * by the seat/session-scheduler and notified whenever they get active/inactive.
44 #include "uvtd_seat.h"
47 #define LOG_SUBSYSTEM "vt"
52 struct shl_hook *hook;
53 struct uvtd_session *session;
60 static void vt_hup(struct uvtd_vt *vt)
62 struct uvt_vt_event ev;
64 memset(&ev, 0, sizeof(ev));
67 shl_hook_call(vt->hook, vt, &ev);
70 static int vt_session_event(struct uvtd_session *session, unsigned int event,
73 struct uvtd_vt *vt = data;
76 case UVTD_SESSION_UNREGISTER:
80 case UVTD_SESSION_ACTIVATE:
81 log_debug("activate %p", vt);
83 case UVTD_SESSION_DEACTIVATE:
84 log_debug("deactivate %p", vt);
91 int uvtd_vt_new(struct uvtd_vt **out, struct uvt_ctx *uctx, unsigned int id,
92 struct uvtd_seat *seat, bool is_legacy)
100 vt = malloc(sizeof(*vt));
104 memset(vt, 0, sizeof(*vt));
107 vt->is_legacy = is_legacy;
109 vt->kbmode = K_UNICODE;
111 ret = shl_hook_new(&vt->hook);
115 ret = uvtd_seat_register_session(seat, &vt->session, id,
116 vt_session_event, vt);
120 uvt_ctx_ref(vt->uctx);
125 shl_hook_free(vt->hook);
131 void uvtd_vt_ref(struct uvtd_vt *vt)
139 void uvtd_vt_unref(struct uvtd_vt *vt)
141 if (!vt || !vt->ref || --vt->ref)
144 uvtd_session_unregister(vt->session);
145 shl_hook_free(vt->hook);
146 uvt_ctx_unref(vt->uctx);
150 int uvtd_vt_register_cb(struct uvtd_vt *vt, uvt_vt_cb cb, void *data)
155 return shl_hook_add_cast(vt->hook, cb, data, false);
158 void uvtd_vt_unregister_cb(struct uvtd_vt *vt, uvt_vt_cb cb, void *data)
163 shl_hook_rm_cast(vt->hook, cb, data);
166 int uvtd_vt_read(struct uvtd_vt *vt, uint8_t *mem, size_t len)
171 int uvtd_vt_write(struct uvtd_vt *vt, const uint8_t *mem, size_t len)
176 unsigned int uvtd_vt_poll(struct uvtd_vt *vt)
178 return UVT_TTY_WRITE;
181 static int vt_ioctl_TCFLSH(void *data, unsigned long arg)
195 static int vt_ioctl_VT_ACTIVATE(void *data, unsigned long arg)
200 static int vt_ioctl_VT_WAITACTIVE(void *data, unsigned long arg)
205 static int vt_ioctl_VT_GETSTATE(void *data, struct vt_stat *arg)
210 static int vt_ioctl_VT_OPENQRY(void *data, unsigned int *arg)
215 static int vt_ioctl_VT_GETMODE(void *data, struct vt_mode *arg)
220 static int vt_ioctl_VT_SETMODE(void *data, const struct vt_mode *arg)
225 static int vt_ioctl_VT_RELDISP(void *data, unsigned long arg)
230 static int vt_ioctl_KDGETMODE(void *data, unsigned int *arg)
232 struct uvtd_vt *vt = data;
238 static int vt_ioctl_KDSETMODE(void *data, unsigned int arg)
240 struct uvtd_vt *vt = data;
258 static int vt_ioctl_KDGKBMODE(void *data, unsigned int *arg)
260 struct uvtd_vt *vt = data;
266 static int vt_ioctl_KDSKBMODE(void *data, unsigned int arg)
268 struct uvtd_vt *vt = data;
272 /* TODO: what does K_RAW do? */
279 /* TODO: do we need these? */
288 /* compatibility to UVT-VT ops */
290 static void vt_ref(void *vt)
295 static void vt_unref(void *vt)
300 static int vt_register_cb(void *vt, uvt_vt_cb cb, void *data)
302 return uvtd_vt_register_cb(vt, cb, data);
305 static void vt_unregister_cb(void *vt, uvt_vt_cb cb, void *data)
307 uvtd_vt_register_cb(vt, cb, data);
310 static int vt_read(void *vt, uint8_t *mem, size_t len)
312 return uvtd_vt_read(vt, mem, len);
315 static int vt_write(void *vt, const uint8_t *mem, size_t len)
317 return uvtd_vt_write(vt, mem, len);
320 static unsigned int vt_poll(void *vt)
322 return uvtd_vt_poll(vt);
325 struct uvt_vt_ops uvtd_vt_ops = {
328 .register_cb = vt_register_cb,
329 .unregister_cb = vt_unregister_cb,
334 .ioctl_TCFLSH = vt_ioctl_TCFLSH,
336 .ioctl_VT_ACTIVATE = vt_ioctl_VT_ACTIVATE,
337 .ioctl_VT_WAITACTIVE = vt_ioctl_VT_WAITACTIVE,
338 .ioctl_VT_GETSTATE = vt_ioctl_VT_GETSTATE,
339 .ioctl_VT_OPENQRY = vt_ioctl_VT_OPENQRY,
340 .ioctl_VT_GETMODE = vt_ioctl_VT_GETMODE,
341 .ioctl_VT_SETMODE = vt_ioctl_VT_SETMODE,
342 .ioctl_VT_RELDISP = vt_ioctl_VT_RELDISP,
343 .ioctl_KDGETMODE = vt_ioctl_KDGETMODE,
344 .ioctl_KDSETMODE = vt_ioctl_KDSETMODE,
345 .ioctl_KDGKBMODE = vt_ioctl_KDGKBMODE,
346 .ioctl_KDSKBMODE = vt_ioctl_KDSKBMODE,