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/>.
33 static bool session_feed_keyboard(Session *s, idev_data *data) {
34 idev_data_keyboard *kdata = &data->keyboard;
36 if (!data->resync && kdata->value == 1 && kdata->n_syms == 1) {
40 /* handle VT-switch requests */
43 switch (kdata->keysyms[0]) {
44 case XKB_KEY_F1 ... XKB_KEY_F12:
45 if (IDEV_KBDMATCH(kdata,
46 IDEV_KBDMOD_CTRL | IDEV_KBDMOD_ALT,
48 nr = kdata->keysyms[0] - XKB_KEY_F1 + 1;
50 case XKB_KEY_XF86Switch_VT_1 ... XKB_KEY_XF86Switch_VT_12:
51 nr = kdata->keysyms[0] - XKB_KEY_XF86Switch_VT_1 + 1;
56 seat = sysview_session_get_seat(s->sysview);
57 sysview_seat_switch_to(seat, nr);
65 static bool session_feed(Session *s, idev_data *data) {
67 case IDEV_DATA_KEYBOARD:
68 return session_feed_keyboard(s, data);
74 static int session_idev_fn(idev_session *idev, void *userdata, idev_event *event) {
75 Session *s = userdata;
77 switch (event->type) {
78 case IDEV_EVENT_DEVICE_ADD:
79 idev_device_enable(event->device_add.device);
81 case IDEV_EVENT_DEVICE_REMOVE:
82 idev_device_disable(event->device_remove.device);
84 case IDEV_EVENT_DEVICE_DATA:
85 if (!session_feed(s, &event->device_data.data))
86 workspace_feed(s->active_ws, &event->device_data.data);
93 static void session_grdev_fn(grdev_session *grdev, void *userdata, grdev_event *event) {
94 grdev_display *display;
95 Session *s = userdata;
99 switch (event->type) {
100 case GRDEV_EVENT_DISPLAY_ADD:
101 display = event->display_add.display;
103 r = display_new(&d, s, display);
105 log_error_errno(r, "Cannot create display '%s' on '%s': %m",
106 grdev_display_get_name(display), sysview_session_get_name(s->sysview));
110 grdev_display_set_userdata(display, d);
111 workspace_refresh(s->active_ws);
113 case GRDEV_EVENT_DISPLAY_REMOVE:
114 display = event->display_remove.display;
115 d = grdev_display_get_userdata(display);
120 workspace_refresh(s->active_ws);
122 case GRDEV_EVENT_DISPLAY_CHANGE:
123 display = event->display_remove.display;
124 d = grdev_display_get_userdata(display);
129 workspace_refresh(s->active_ws);
131 case GRDEV_EVENT_DISPLAY_FRAME:
132 display = event->display_remove.display;
133 d = grdev_display_get_userdata(display);
142 static int session_redraw_fn(sd_event_source *src, void *userdata) {
143 Session *s = userdata;
146 LIST_FOREACH(displays_by_session, d, s->display_list)
147 display_render(d, s->active_ws);
149 grdev_session_commit(s->grdev);
154 int session_new(Session **out, Manager *m, sysview_session *session) {
155 _cleanup_(session_freep) Session *s = NULL;
162 s = new0(Session, 1);
167 s->sysview = session;
169 r = grdev_session_new(&s->grdev,
171 GRDEV_SESSION_MANAGED,
172 sysview_session_get_name(session),
178 r = idev_session_new(&s->idev,
180 IDEV_SESSION_MANAGED,
181 sysview_session_get_name(session),
187 r = workspace_new(&s->my_ws, m);
191 s->active_ws = workspace_attach(s->my_ws, s);
193 r = sd_event_add_defer(m->event, &s->redraw_src, session_redraw_fn, s);
197 grdev_session_enable(s->grdev);
198 idev_session_enable(s->idev);
205 Session *session_free(Session *s) {
209 assert(!s->display_list);
211 sd_event_source_unref(s->redraw_src);
213 workspace_detach(s->active_ws, s);
214 workspace_unref(s->my_ws);
216 idev_session_free(s->idev);
217 grdev_session_free(s->grdev);
223 void session_dirty(Session *s) {
228 r = sd_event_source_set_enabled(s->redraw_src, SD_EVENT_ONESHOT);
230 log_error_errno(r, "Cannot enable redraw-source: %m");
233 void session_add_device(Session *s, sysview_device *device) {
239 type = sysview_device_get_type(device);
241 case SYSVIEW_DEVICE_DRM:
242 grdev_session_add_drm(s->grdev, sysview_device_get_ud(device));
244 case SYSVIEW_DEVICE_EVDEV:
245 idev_session_add_evdev(s->idev, sysview_device_get_ud(device));
250 void session_remove_device(Session *s, sysview_device *device) {
256 type = sysview_device_get_type(device);
258 case SYSVIEW_DEVICE_DRM:
259 grdev_session_remove_drm(s->grdev, sysview_device_get_ud(device));
261 case SYSVIEW_DEVICE_EVDEV:
262 idev_session_remove_evdev(s->idev, sysview_device_get_ud(device));
267 void session_refresh_device(Session *s, sysview_device *device, struct udev_device *ud) {
273 type = sysview_device_get_type(device);
275 case SYSVIEW_DEVICE_DRM:
276 grdev_session_hotplug_drm(s->grdev, sysview_device_get_ud(device));