1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2014 David Herrmann <dh.herrmann@gmail.com>
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.
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.
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/>.
37 static bool session_feed_keyboard(Session *s, idev_data *data) {
38 idev_data_keyboard *kdata = &data->keyboard;
40 if (!data->resync && kdata->value == 1 && kdata->n_syms == 1) {
44 /* handle VT-switch requests */
47 switch (kdata->keysyms[0]) {
48 case XKB_KEY_F1 ... XKB_KEY_F12:
49 if (IDEV_KBDMATCH(kdata,
50 IDEV_KBDMOD_CTRL | IDEV_KBDMOD_ALT,
52 nr = kdata->keysyms[0] - XKB_KEY_F1 + 1;
54 case XKB_KEY_XF86Switch_VT_1 ... XKB_KEY_XF86Switch_VT_12:
55 nr = kdata->keysyms[0] - XKB_KEY_XF86Switch_VT_1 + 1;
60 seat = sysview_session_get_seat(s->sysview);
61 sysview_seat_switch_to(seat, nr);
69 static bool session_feed(Session *s, idev_data *data) {
71 case IDEV_DATA_KEYBOARD:
72 return session_feed_keyboard(s, data);
78 static int session_idev_fn(idev_session *idev, void *userdata, idev_event *event) {
79 Session *s = userdata;
81 switch (event->type) {
82 case IDEV_EVENT_DEVICE_ADD:
83 idev_device_enable(event->device_add.device);
85 case IDEV_EVENT_DEVICE_REMOVE:
86 idev_device_disable(event->device_remove.device);
88 case IDEV_EVENT_DEVICE_DATA:
89 if (!session_feed(s, &event->device_data.data))
90 workspace_feed(s->active_ws, &event->device_data.data);
97 static void session_grdev_fn(grdev_session *grdev, void *userdata, grdev_event *event) {
98 grdev_display *display;
99 Session *s = userdata;
103 switch (event->type) {
104 case GRDEV_EVENT_DISPLAY_ADD:
105 display = event->display_add.display;
107 r = display_new(&d, s, display);
109 log_error_errno(r, "Cannot create display '%s' on '%s': %m",
110 grdev_display_get_name(display), sysview_session_get_name(s->sysview));
114 grdev_display_set_userdata(display, d);
115 workspace_refresh(s->active_ws);
117 case GRDEV_EVENT_DISPLAY_REMOVE:
118 display = event->display_remove.display;
119 d = grdev_display_get_userdata(display);
124 workspace_refresh(s->active_ws);
126 case GRDEV_EVENT_DISPLAY_CHANGE:
127 display = event->display_remove.display;
128 d = grdev_display_get_userdata(display);
133 workspace_refresh(s->active_ws);
135 case GRDEV_EVENT_DISPLAY_FRAME:
136 display = event->display_remove.display;
137 d = grdev_display_get_userdata(display);
146 static int session_redraw_fn(sd_event_source *src, void *userdata) {
147 Session *s = userdata;
150 LIST_FOREACH(displays_by_session, d, s->display_list)
151 display_render(d, s->active_ws);
153 grdev_session_commit(s->grdev);
158 int session_new(Session **out, Manager *m, sysview_session *session) {
159 _cleanup_(session_freep) Session *s = NULL;
166 s = new0(Session, 1);
171 s->sysview = session;
173 r = grdev_session_new(&s->grdev,
175 GRDEV_SESSION_MANAGED,
176 sysview_session_get_name(session),
182 r = idev_session_new(&s->idev,
184 IDEV_SESSION_MANAGED,
185 sysview_session_get_name(session),
191 r = workspace_new(&s->my_ws, m);
195 s->active_ws = workspace_attach(s->my_ws, s);
197 r = sd_event_add_defer(m->event, &s->redraw_src, session_redraw_fn, s);
201 grdev_session_enable(s->grdev);
202 idev_session_enable(s->idev);
209 Session *session_free(Session *s) {
213 assert(!s->display_list);
215 sd_event_source_unref(s->redraw_src);
217 workspace_detach(s->active_ws, s);
218 workspace_unref(s->my_ws);
220 idev_session_free(s->idev);
221 grdev_session_free(s->grdev);
227 void session_dirty(Session *s) {
232 r = sd_event_source_set_enabled(s->redraw_src, SD_EVENT_ONESHOT);
234 log_error_errno(r, "Cannot enable redraw-source: %m");
237 void session_add_device(Session *s, sysview_device *device) {
243 type = sysview_device_get_type(device);
245 case SYSVIEW_DEVICE_DRM:
246 grdev_session_add_drm(s->grdev, sysview_device_get_ud(device));
248 case SYSVIEW_DEVICE_EVDEV:
249 idev_session_add_evdev(s->idev, sysview_device_get_ud(device));
254 void session_remove_device(Session *s, sysview_device *device) {
260 type = sysview_device_get_type(device);
262 case SYSVIEW_DEVICE_DRM:
263 grdev_session_remove_drm(s->grdev, sysview_device_get_ud(device));
265 case SYSVIEW_DEVICE_EVDEV:
266 idev_session_remove_evdev(s->idev, sysview_device_get_ud(device));
271 void session_refresh_device(Session *s, sysview_device *device, struct udev_device *ud) {
277 type = sysview_device_get_type(device);
279 case SYSVIEW_DEVICE_DRM:
280 grdev_session_hotplug_drm(s->grdev, sysview_device_get_ud(device));