diff options
Diffstat (limited to 'src/console')
l--------- | src/console/Makefile | 1 | ||||
-rw-r--r-- | src/console/consoled-display.c | 81 | ||||
-rw-r--r-- | src/console/consoled-manager.c | 284 | ||||
-rw-r--r-- | src/console/consoled-session.c | 279 | ||||
-rw-r--r-- | src/console/consoled-terminal.c | 358 | ||||
-rw-r--r-- | src/console/consoled-workspace.c | 167 | ||||
-rw-r--r-- | src/console/consoled.c | 66 | ||||
-rw-r--r-- | src/console/consoled.h | 164 |
8 files changed, 0 insertions, 1400 deletions
diff --git a/src/console/Makefile b/src/console/Makefile deleted file mode 120000 index d0b0e8e008..0000000000 --- a/src/console/Makefile +++ /dev/null @@ -1 +0,0 @@ -../Makefile
\ No newline at end of file diff --git a/src/console/consoled-display.c b/src/console/consoled-display.c deleted file mode 100644 index 569c011dc0..0000000000 --- a/src/console/consoled-display.c +++ /dev/null @@ -1,81 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 David Herrmann <dh.herrmann@gmail.com> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <errno.h> -#include <stdlib.h> -#include "consoled.h" -#include "grdev.h" -#include "list.h" -#include "macro.h" -#include "util.h" - -int display_new(Display **out, Session *s, grdev_display *display) { - _cleanup_(display_freep) Display *d = NULL; - - assert(out); - assert(s); - assert(display); - - d = new0(Display, 1); - if (!d) - return -ENOMEM; - - d->session = s; - d->grdev = display; - d->width = grdev_display_get_width(display); - d->height = grdev_display_get_height(display); - LIST_PREPEND(displays_by_session, d->session->display_list, d); - - grdev_display_enable(display); - - *out = d; - d = NULL; - return 0; -} - -Display *display_free(Display *d) { - if (!d) - return NULL; - - LIST_REMOVE(displays_by_session, d->session->display_list, d); - free(d); - - return NULL; -} - -void display_refresh(Display *d) { - assert(d); - - d->width = grdev_display_get_width(d->grdev); - d->height = grdev_display_get_height(d->grdev); -} - -void display_render(Display *d, Workspace *w) { - const grdev_display_target *target; - - assert(d); - assert(w); - - GRDEV_DISPLAY_FOREACH_TARGET(d->grdev, target) { - if (workspace_draw(w, target)) - grdev_display_flip_target(d->grdev, target); - } -} diff --git a/src/console/consoled-manager.c b/src/console/consoled-manager.c deleted file mode 100644 index 20424eb267..0000000000 --- a/src/console/consoled-manager.c +++ /dev/null @@ -1,284 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 David Herrmann <dh.herrmann@gmail.com> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <errno.h> -#include <stdlib.h> -#include "sd-bus.h" -#include "sd-event.h" -#include "sd-login.h" -#include "log.h" -#include "signal-util.h" -#include "util.h" -#include "consoled.h" -#include "idev.h" -#include "grdev.h" -#include "sysview.h" -#include "unifont.h" - -int manager_new(Manager **out) { - _cleanup_(manager_freep) Manager *m = NULL; - int r; - - assert(out); - - m = new0(Manager, 1); - if (!m) - return -ENOMEM; - - r = sd_event_default(&m->event); - if (r < 0) - return r; - - r = sd_event_set_watchdog(m->event, true); - if (r < 0) - return r; - - r = sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGQUIT, SIGINT, SIGWINCH, SIGCHLD, -1); - if (r < 0) - return r; - - r = sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL); - if (r < 0) - return r; - - r = sd_event_add_signal(m->event, NULL, SIGQUIT, NULL, NULL); - if (r < 0) - return r; - - r = sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL); - if (r < 0) - return r; - - r = sd_bus_open_system(&m->sysbus); - if (r < 0) - return r; - - r = sd_bus_attach_event(m->sysbus, m->event, SD_EVENT_PRIORITY_NORMAL); - if (r < 0) - return r; - - r = unifont_new(&m->uf); - if (r < 0) - return r; - - r = sysview_context_new(&m->sysview, - SYSVIEW_CONTEXT_SCAN_LOGIND | - SYSVIEW_CONTEXT_SCAN_EVDEV | - SYSVIEW_CONTEXT_SCAN_DRM, - m->event, - m->sysbus, - NULL); - if (r < 0) - return r; - - r = grdev_context_new(&m->grdev, m->event, m->sysbus); - if (r < 0) - return r; - - r = idev_context_new(&m->idev, m->event, m->sysbus); - if (r < 0) - return r; - - *out = m; - m = NULL; - return 0; -} - -Manager *manager_free(Manager *m) { - if (!m) - return NULL; - - assert(!m->workspace_list); - - m->idev = idev_context_unref(m->idev); - m->grdev = grdev_context_unref(m->grdev); - m->sysview = sysview_context_free(m->sysview); - m->uf = unifont_unref(m->uf); - m->sysbus = sd_bus_unref(m->sysbus); - m->event = sd_event_unref(m->event); - free(m); - - return NULL; -} - -static int manager_sysview_session_filter(Manager *m, sysview_event *event) { - const char *sid = event->session_filter.id; - _cleanup_free_ char *desktop = NULL; - int r; - - assert(sid); - - r = sd_session_get_desktop(sid, &desktop); - if (r < 0) - return 0; - - return streq(desktop, "systemd-console"); -} - -static int manager_sysview_session_add(Manager *m, sysview_event *event) { - sysview_session *session = event->session_add.session; - Session *s; - int r; - - r = sysview_session_take_control(session); - if (r < 0) - return log_error_errno(r, "Cannot request session control on '%s': %m", - sysview_session_get_name(session)); - - r = session_new(&s, m, session); - if (r < 0) { - log_error_errno(r, "Cannot create session on '%s': %m", - sysview_session_get_name(session)); - sysview_session_release_control(session); - return r; - } - - sysview_session_set_userdata(session, s); - - return 0; -} - -static int manager_sysview_session_remove(Manager *m, sysview_event *event) { - sysview_session *session = event->session_remove.session; - Session *s; - - s = sysview_session_get_userdata(session); - if (!s) - return 0; - - session_free(s); - - return 0; -} - -static int manager_sysview_session_attach(Manager *m, sysview_event *event) { - sysview_session *session = event->session_attach.session; - sysview_device *device = event->session_attach.device; - Session *s; - - s = sysview_session_get_userdata(session); - if (!s) - return 0; - - session_add_device(s, device); - - return 0; -} - -static int manager_sysview_session_detach(Manager *m, sysview_event *event) { - sysview_session *session = event->session_detach.session; - sysview_device *device = event->session_detach.device; - Session *s; - - s = sysview_session_get_userdata(session); - if (!s) - return 0; - - session_remove_device(s, device); - - return 0; -} - -static int manager_sysview_session_refresh(Manager *m, sysview_event *event) { - sysview_session *session = event->session_refresh.session; - sysview_device *device = event->session_refresh.device; - struct udev_device *ud = event->session_refresh.ud; - Session *s; - - s = sysview_session_get_userdata(session); - if (!s) - return 0; - - session_refresh_device(s, device, ud); - - return 0; -} - -static int manager_sysview_session_control(Manager *m, sysview_event *event) { - sysview_session *session = event->session_control.session; - int error = event->session_control.error; - Session *s; - - s = sysview_session_get_userdata(session); - if (!s) - return 0; - - if (error < 0) { - log_error_errno(error, "Cannot take session control on '%s': %m", - sysview_session_get_name(session)); - session_free(s); - sysview_session_set_userdata(session, NULL); - return error; - } - - return 0; -} - -static int manager_sysview_fn(sysview_context *sysview, void *userdata, sysview_event *event) { - Manager *m = userdata; - int r; - - assert(m); - - switch (event->type) { - case SYSVIEW_EVENT_SESSION_FILTER: - r = manager_sysview_session_filter(m, event); - break; - case SYSVIEW_EVENT_SESSION_ADD: - r = manager_sysview_session_add(m, event); - break; - case SYSVIEW_EVENT_SESSION_REMOVE: - r = manager_sysview_session_remove(m, event); - break; - case SYSVIEW_EVENT_SESSION_ATTACH: - r = manager_sysview_session_attach(m, event); - break; - case SYSVIEW_EVENT_SESSION_DETACH: - r = manager_sysview_session_detach(m, event); - break; - case SYSVIEW_EVENT_SESSION_REFRESH: - r = manager_sysview_session_refresh(m, event); - break; - case SYSVIEW_EVENT_SESSION_CONTROL: - r = manager_sysview_session_control(m, event); - break; - default: - r = 0; - break; - } - - return r; -} - -int manager_run(Manager *m) { - int r; - - assert(m); - - r = sysview_context_start(m->sysview, manager_sysview_fn, m); - if (r < 0) - return r; - - r = sd_event_loop(m->event); - - sysview_context_stop(m->sysview); - return r; -} diff --git a/src/console/consoled-session.c b/src/console/consoled-session.c deleted file mode 100644 index 264a4d009a..0000000000 --- a/src/console/consoled-session.c +++ /dev/null @@ -1,279 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 David Herrmann <dh.herrmann@gmail.com> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <errno.h> -#include <stdlib.h> -#include "consoled.h" -#include "grdev.h" -#include "idev.h" -#include "list.h" -#include "macro.h" -#include "sd-event.h" -#include "sysview.h" -#include "util.h" - -static bool session_feed_keyboard(Session *s, idev_data *data) { - idev_data_keyboard *kdata = &data->keyboard; - - if (!data->resync && kdata->value == 1 && kdata->n_syms == 1) { - uint32_t nr; - sysview_seat *seat; - - /* handle VT-switch requests */ - nr = 0; - - switch (kdata->keysyms[0]) { - case XKB_KEY_F1 ... XKB_KEY_F12: - if (IDEV_KBDMATCH(kdata, - IDEV_KBDMOD_CTRL | IDEV_KBDMOD_ALT, - kdata->keysyms[0])) - nr = kdata->keysyms[0] - XKB_KEY_F1 + 1; - break; - case XKB_KEY_XF86Switch_VT_1 ... XKB_KEY_XF86Switch_VT_12: - nr = kdata->keysyms[0] - XKB_KEY_XF86Switch_VT_1 + 1; - break; - } - - if (nr != 0) { - seat = sysview_session_get_seat(s->sysview); - sysview_seat_switch_to(seat, nr); - return true; - } - } - - return false; -} - -static bool session_feed(Session *s, idev_data *data) { - switch (data->type) { - case IDEV_DATA_KEYBOARD: - return session_feed_keyboard(s, data); - default: - return false; - } -} - -static int session_idev_fn(idev_session *idev, void *userdata, idev_event *event) { - Session *s = userdata; - - switch (event->type) { - case IDEV_EVENT_DEVICE_ADD: - idev_device_enable(event->device_add.device); - break; - case IDEV_EVENT_DEVICE_REMOVE: - idev_device_disable(event->device_remove.device); - break; - case IDEV_EVENT_DEVICE_DATA: - if (!session_feed(s, &event->device_data.data)) - workspace_feed(s->active_ws, &event->device_data.data); - break; - } - - return 0; -} - -static void session_grdev_fn(grdev_session *grdev, void *userdata, grdev_event *event) { - grdev_display *display; - Session *s = userdata; - Display *d; - int r; - - switch (event->type) { - case GRDEV_EVENT_DISPLAY_ADD: - display = event->display_add.display; - - r = display_new(&d, s, display); - if (r < 0) { - log_error_errno(r, "Cannot create display '%s' on '%s': %m", - grdev_display_get_name(display), sysview_session_get_name(s->sysview)); - break; - } - - grdev_display_set_userdata(display, d); - workspace_refresh(s->active_ws); - break; - case GRDEV_EVENT_DISPLAY_REMOVE: - display = event->display_remove.display; - d = grdev_display_get_userdata(display); - if (!d) - break; - - display_free(d); - workspace_refresh(s->active_ws); - break; - case GRDEV_EVENT_DISPLAY_CHANGE: - display = event->display_remove.display; - d = grdev_display_get_userdata(display); - if (!d) - break; - - display_refresh(d); - workspace_refresh(s->active_ws); - break; - case GRDEV_EVENT_DISPLAY_FRAME: - display = event->display_remove.display; - d = grdev_display_get_userdata(display); - if (!d) - break; - - session_dirty(s); - break; - } -} - -static int session_redraw_fn(sd_event_source *src, void *userdata) { - Session *s = userdata; - Display *d; - - LIST_FOREACH(displays_by_session, d, s->display_list) - display_render(d, s->active_ws); - - grdev_session_commit(s->grdev); - - return 0; -} - -int session_new(Session **out, Manager *m, sysview_session *session) { - _cleanup_(session_freep) Session *s = NULL; - int r; - - assert(out); - assert(m); - assert(session); - - s = new0(Session, 1); - if (!s) - return -ENOMEM; - - s->manager = m; - s->sysview = session; - - r = grdev_session_new(&s->grdev, - m->grdev, - GRDEV_SESSION_MANAGED, - sysview_session_get_name(session), - session_grdev_fn, - s); - if (r < 0) - return r; - - r = idev_session_new(&s->idev, - m->idev, - IDEV_SESSION_MANAGED, - sysview_session_get_name(session), - session_idev_fn, - s); - if (r < 0) - return r; - - r = workspace_new(&s->my_ws, m); - if (r < 0) - return r; - - s->active_ws = workspace_attach(s->my_ws, s); - - r = sd_event_add_defer(m->event, &s->redraw_src, session_redraw_fn, s); - if (r < 0) - return r; - - grdev_session_enable(s->grdev); - idev_session_enable(s->idev); - - *out = s; - s = NULL; - return 0; -} - -Session *session_free(Session *s) { - if (!s) - return NULL; - - assert(!s->display_list); - - sd_event_source_unref(s->redraw_src); - - workspace_detach(s->active_ws, s); - workspace_unref(s->my_ws); - - idev_session_free(s->idev); - grdev_session_free(s->grdev); - free(s); - - return NULL; -} - -void session_dirty(Session *s) { - int r; - - assert(s); - - r = sd_event_source_set_enabled(s->redraw_src, SD_EVENT_ONESHOT); - if (r < 0) - log_error_errno(r, "Cannot enable redraw-source: %m"); -} - -void session_add_device(Session *s, sysview_device *device) { - unsigned int type; - - assert(s); - assert(device); - - type = sysview_device_get_type(device); - switch (type) { - case SYSVIEW_DEVICE_DRM: - grdev_session_add_drm(s->grdev, sysview_device_get_ud(device)); - break; - case SYSVIEW_DEVICE_EVDEV: - idev_session_add_evdev(s->idev, sysview_device_get_ud(device)); - break; - } -} - -void session_remove_device(Session *s, sysview_device *device) { - unsigned int type; - - assert(s); - assert(device); - - type = sysview_device_get_type(device); - switch (type) { - case SYSVIEW_DEVICE_DRM: - grdev_session_remove_drm(s->grdev, sysview_device_get_ud(device)); - break; - case SYSVIEW_DEVICE_EVDEV: - idev_session_remove_evdev(s->idev, sysview_device_get_ud(device)); - break; - } -} - -void session_refresh_device(Session *s, sysview_device *device, struct udev_device *ud) { - unsigned int type; - - assert(s); - assert(device); - - type = sysview_device_get_type(device); - switch (type) { - case SYSVIEW_DEVICE_DRM: - grdev_session_hotplug_drm(s->grdev, sysview_device_get_ud(device)); - break; - } -} diff --git a/src/console/consoled-terminal.c b/src/console/consoled-terminal.c deleted file mode 100644 index 03447d1b92..0000000000 --- a/src/console/consoled-terminal.c +++ /dev/null @@ -1,358 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 David Herrmann <dh.herrmann@gmail.com> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <errno.h> -#include <stdlib.h> -#include "consoled.h" -#include "list.h" -#include "macro.h" -#include "util.h" - -static int terminal_write_fn(term_screen *screen, void *userdata, const void *buf, size_t size) { - Terminal *t = userdata; - int r; - - if (t->pty) { - r = pty_write(t->pty, buf, size); - if (r < 0) - return log_oom(); - } - - return 0; -} - -static int terminal_pty_fn(Pty *pty, void *userdata, unsigned int event, const void *ptr, size_t size) { - Terminal *t = userdata; - int r; - - switch (event) { - case PTY_CHILD: - log_debug("PTY child exited"); - t->pty = pty_unref(t->pty); - break; - case PTY_DATA: - r = term_screen_feed_text(t->screen, ptr, size); - if (r < 0) - log_error_errno(r, "Cannot update screen state: %m"); - - workspace_dirty(t->workspace); - break; - } - - return 0; -} - -int terminal_new(Terminal **out, Workspace *w) { - _cleanup_(terminal_freep) Terminal *t = NULL; - int r; - - assert(w); - - t = new0(Terminal, 1); - if (!t) - return -ENOMEM; - - t->workspace = w; - LIST_PREPEND(terminals_by_workspace, w->terminal_list, t); - - r = term_parser_new(&t->parser, true); - if (r < 0) - return r; - - r = term_screen_new(&t->screen, terminal_write_fn, t, NULL, NULL); - if (r < 0) - return r; - - r = term_screen_set_answerback(t->screen, "systemd-console"); - if (r < 0) - return r; - - if (out) - *out = t; - t = NULL; - return 0; -} - -Terminal *terminal_free(Terminal *t) { - if (!t) - return NULL; - - assert(t->workspace); - - if (t->pty) { - (void) pty_signal(t->pty, SIGHUP); - pty_close(t->pty); - pty_unref(t->pty); - } - term_screen_unref(t->screen); - term_parser_free(t->parser); - LIST_REMOVE(terminals_by_workspace, t->workspace->terminal_list, t); - free(t); - - return NULL; -} - -void terminal_resize(Terminal *t) { - uint32_t width, height, fw, fh; - int r; - - assert(t); - - width = t->workspace->width; - height = t->workspace->height; - fw = unifont_get_width(t->workspace->manager->uf); - fh = unifont_get_height(t->workspace->manager->uf); - - width = (fw > 0) ? width / fw : 0; - height = (fh > 0) ? height / fh : 0; - - if (t->pty) { - r = pty_resize(t->pty, width, height); - if (r < 0) - log_error_errno(r, "Cannot resize pty: %m"); - } - - r = term_screen_resize(t->screen, width, height); - if (r < 0) - log_error_errno(r, "Cannot resize screen: %m"); -} - -void terminal_run(Terminal *t) { - pid_t pid; - - assert(t); - - if (t->pty) - return; - - pid = pty_fork(&t->pty, - t->workspace->manager->event, - terminal_pty_fn, - t, - term_screen_get_width(t->screen), - term_screen_get_height(t->screen)); - if (pid < 0) { - log_error_errno(pid, "Cannot fork PTY: %m"); - return; - } else if (pid == 0) { - /* child */ - - char **argv = (char*[]){ - (char*)getenv("SHELL") ? : (char*)_PATH_BSHELL, - NULL - }; - - setenv("TERM", "xterm-256color", 1); - setenv("COLORTERM", "systemd-console", 1); - - execve(argv[0], argv, environ); - log_error_errno(errno, "Cannot exec %s (%d): %m", argv[0], -errno); - _exit(1); - } -} - -static void terminal_feed_keyboard(Terminal *t, idev_data *data) { - idev_data_keyboard *kdata = &data->keyboard; - int r; - - if (!data->resync && (kdata->value == 1 || kdata->value == 2)) { - assert_cc(TERM_KBDMOD_CNT == (int)IDEV_KBDMOD_CNT); - assert_cc(TERM_KBDMOD_IDX_SHIFT == (int)IDEV_KBDMOD_IDX_SHIFT && - TERM_KBDMOD_IDX_CTRL == (int)IDEV_KBDMOD_IDX_CTRL && - TERM_KBDMOD_IDX_ALT == (int)IDEV_KBDMOD_IDX_ALT && - TERM_KBDMOD_IDX_LINUX == (int)IDEV_KBDMOD_IDX_LINUX && - TERM_KBDMOD_IDX_CAPS == (int)IDEV_KBDMOD_IDX_CAPS); - - r = term_screen_feed_keyboard(t->screen, - kdata->keysyms, - kdata->n_syms, - kdata->ascii, - kdata->codepoints, - kdata->mods); - if (r < 0) - log_error_errno(r, "Cannot feed keyboard data to screen: %m"); - } -} - -void terminal_feed(Terminal *t, idev_data *data) { - switch (data->type) { - case IDEV_DATA_KEYBOARD: - terminal_feed_keyboard(t, data); - break; - } -} - -static void terminal_fill(uint8_t *dst, - uint32_t width, - uint32_t height, - uint32_t stride, - uint32_t value) { - uint32_t i, j, *px; - - for (j = 0; j < height; ++j) { - px = (uint32_t*)dst; - - for (i = 0; i < width; ++i) - *px++ = value; - - dst += stride; - } -} - -static void terminal_blend(uint8_t *dst, - uint32_t width, - uint32_t height, - uint32_t dst_stride, - const uint8_t *src, - uint32_t src_stride, - uint32_t fg, - uint32_t bg) { - uint32_t i, j, *px; - - for (j = 0; j < height; ++j) { - px = (uint32_t*)dst; - - for (i = 0; i < width; ++i) { - if (!src || src[i / 8] & (1 << (7 - i % 8))) - *px = fg; - else - *px = bg; - - ++px; - } - - src += src_stride; - dst += dst_stride; - } -} - -typedef struct { - const grdev_display_target *target; - unifont *uf; - uint32_t cell_width; - uint32_t cell_height; - bool dirty; -} TerminalDrawContext; - -static int terminal_draw_cell(term_screen *screen, - void *userdata, - unsigned int x, - unsigned int y, - const term_attr *attr, - const uint32_t *ch, - size_t n_ch, - unsigned int ch_width) { - TerminalDrawContext *ctx = userdata; - const grdev_display_target *target = ctx->target; - grdev_fb *fb = target->back; - uint32_t xpos, ypos, width, height; - uint32_t fg, bg; - unifont_glyph g; - uint8_t *dst; - int r; - - if (n_ch > 0) { - r = unifont_lookup(ctx->uf, &g, *ch); - if (r < 0) - r = unifont_lookup(ctx->uf, &g, 0xfffd); - if (r < 0) - unifont_fallback(&g); - } - - xpos = x * ctx->cell_width; - ypos = y * ctx->cell_height; - - if (xpos >= fb->width || ypos >= fb->height) - return 0; - - width = MIN(fb->width - xpos, ctx->cell_width * ch_width); - height = MIN(fb->height - ypos, ctx->cell_height); - - term_attr_to_argb32(attr, &fg, &bg, NULL); - - ctx->dirty = true; - - dst = fb->maps[0]; - dst += fb->strides[0] * ypos + sizeof(uint32_t) * xpos; - - if (n_ch < 1) { - terminal_fill(dst, - width, - height, - fb->strides[0], - bg); - } else { - if (width > g.width) - terminal_fill(dst + sizeof(uint32_t) * g.width, - width - g.width, - height, - fb->strides[0], - bg); - if (height > g.height) - terminal_fill(dst + fb->strides[0] * g.height, - width, - height - g.height, - fb->strides[0], - bg); - - terminal_blend(dst, - width, - height, - fb->strides[0], - g.data, - g.stride, - fg, - bg); - } - - return 0; -} - -bool terminal_draw(Terminal *t, const grdev_display_target *target) { - TerminalDrawContext ctx = { }; - uint64_t age; - - assert(t); - assert(target); - - /* start up terminal on first frame */ - terminal_run(t); - - ctx.target = target; - ctx.uf = t->workspace->manager->uf; - ctx.cell_width = unifont_get_width(ctx.uf); - ctx.cell_height = unifont_get_height(ctx.uf); - ctx.dirty = false; - - if (target->front) { - /* if the frontbuffer is new enough, no reason to redraw */ - age = term_screen_get_age(t->screen); - if (age != 0 && age <= target->front->data.u64) - return false; - } else { - /* force flip if no frontbuffer is set, yet */ - ctx.dirty = true; - } - - term_screen_draw(t->screen, terminal_draw_cell, &ctx, &target->back->data.u64); - - return ctx.dirty; -} diff --git a/src/console/consoled-workspace.c b/src/console/consoled-workspace.c deleted file mode 100644 index 5e9e5c7c49..0000000000 --- a/src/console/consoled-workspace.c +++ /dev/null @@ -1,167 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 David Herrmann <dh.herrmann@gmail.com> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <errno.h> -#include <stdlib.h> -#include "consoled.h" -#include "grdev.h" -#include "idev.h" -#include "list.h" -#include "macro.h" -#include "util.h" - -int workspace_new(Workspace **out, Manager *m) { - _cleanup_(workspace_unrefp) Workspace *w = NULL; - int r; - - assert(out); - - w = new0(Workspace, 1); - if (!w) - return -ENOMEM; - - w->ref = 1; - w->manager = m; - LIST_PREPEND(workspaces_by_manager, m->workspace_list, w); - - r = terminal_new(&w->current, w); - if (r < 0) - return r; - - *out = w; - w = NULL; - return 0; -} - -static void workspace_cleanup(Workspace *w) { - Terminal *t; - - assert(w); - assert(w->ref == 0); - assert(w->manager); - assert(!w->session_list); - - w->current = NULL; - while ((t = w->terminal_list)) - terminal_free(t); - - LIST_REMOVE(workspaces_by_manager, w->manager->workspace_list, w); - free(w); -} - -Workspace *workspace_ref(Workspace *w) { - assert(w); - - ++w->ref; - return w; -} - -Workspace *workspace_unref(Workspace *w) { - if (!w) - return NULL; - - assert(w->ref > 0); - - if (--w->ref == 0) - workspace_cleanup(w); - - return NULL; -} - -Workspace *workspace_attach(Workspace *w, Session *s) { - assert(w); - assert(s); - - LIST_PREPEND(sessions_by_workspace, w->session_list, s); - workspace_refresh(w); - return workspace_ref(w); -} - -Workspace *workspace_detach(Workspace *w, Session *s) { - assert(w); - assert(s); - assert(s->active_ws == w); - - LIST_REMOVE(sessions_by_workspace, w->session_list, s); - workspace_refresh(w); - return workspace_unref(w); -} - -void workspace_refresh(Workspace *w) { - uint32_t width, height; - Terminal *t; - Session *s; - Display *d; - - assert(w); - - width = 0; - height = 0; - - /* find out minimum dimension of all attached displays */ - LIST_FOREACH(sessions_by_workspace, s, w->session_list) { - LIST_FOREACH(displays_by_session, d, s->display_list) { - assert(d->width > 0 && d->height > 0); - - if (width == 0 || d->width < width) - width = d->width; - if (height == 0 || d->height < height) - height = d->height; - } - } - - /* either both are zero, or none is zero */ - assert(!(!width ^ !height)); - - /* update terminal-sizes if dimensions changed */ - if (w->width != width || w->height != height) { - w->width = width; - w->height = height; - - LIST_FOREACH(terminals_by_workspace, t, w->terminal_list) - terminal_resize(t); - - workspace_dirty(w); - } -} - -void workspace_dirty(Workspace *w) { - Session *s; - - assert(w); - - LIST_FOREACH(sessions_by_workspace, s, w->session_list) - session_dirty(s); -} - -void workspace_feed(Workspace *w, idev_data *data) { - assert(w); - assert(data); - - terminal_feed(w->current, data); -} - -bool workspace_draw(Workspace *w, const grdev_display_target *target) { - assert(w); - assert(target); - - return terminal_draw(w->current, target); -} diff --git a/src/console/consoled.c b/src/console/consoled.c deleted file mode 100644 index 9f69e8983f..0000000000 --- a/src/console/consoled.c +++ /dev/null @@ -1,66 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -/*** - This file is part of systemd. - - Copyright 2014 David Herrmann <dh.herrmann@gmail.com> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include <errno.h> -#include <stdlib.h> -#include "sd-daemon.h" -#include "log.h" -#include "signal-util.h" -#include "consoled.h" - -int main(int argc, char *argv[]) { - _cleanup_(manager_freep) Manager *m = NULL; - int r; - - log_set_target(LOG_TARGET_AUTO); - log_parse_environment(); - log_open(); - - umask(0022); - - if (argc != 1) { - log_error("This program takes no arguments."); - r = -EINVAL; - goto out; - } - - r = manager_new(&m); - if (r < 0) { - log_error_errno(r, "Could not create manager: %m"); - goto out; - } - - sd_notify(false, - "READY=1\n" - "STATUS=Processing requests..."); - - r = manager_run(m); - if (r < 0) { - log_error_errno(r, "Cannot run manager: %m"); - goto out; - } - -out: - sd_notify(false, - "STATUS=Shutting down..."); - - return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; -} diff --git a/src/console/consoled.h b/src/console/consoled.h deleted file mode 100644 index f85c1a0791..0000000000 --- a/src/console/consoled.h +++ /dev/null @@ -1,164 +0,0 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -#pragma once - -/*** - This file is part of systemd. - - Copyright 2014 David Herrmann <dh.herrmann@gmail.com> - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ - -#include "grdev.h" -#include "idev.h" -#include "list.h" -#include "macro.h" -#include "pty.h" -#include "sd-bus.h" -#include "sd-event.h" -#include "sysview.h" -#include "term.h" -#include "unifont.h" - -typedef struct Manager Manager; -typedef struct Session Session; -typedef struct Display Display; -typedef struct Workspace Workspace; -typedef struct Terminal Terminal; - -/* - * Terminals - */ - -struct Terminal { - Workspace *workspace; - LIST_FIELDS(Terminal, terminals_by_workspace); - - term_utf8 utf8; - term_parser *parser; - term_screen *screen; - Pty *pty; -}; - -int terminal_new(Terminal **out, Workspace *w); -Terminal *terminal_free(Terminal *t); - -DEFINE_TRIVIAL_CLEANUP_FUNC(Terminal*, terminal_free); - -void terminal_resize(Terminal *t); -void terminal_run(Terminal *t); -void terminal_feed(Terminal *t, idev_data *data); -bool terminal_draw(Terminal *t, const grdev_display_target *target); - -/* - * Workspaces - */ - -struct Workspace { - unsigned long ref; - Manager *manager; - LIST_FIELDS(Workspace, workspaces_by_manager); - - LIST_HEAD(Terminal, terminal_list); - Terminal *current; - - LIST_HEAD(Session, session_list); - uint32_t width; - uint32_t height; -}; - -int workspace_new(Workspace **out, Manager *m); -Workspace *workspace_ref(Workspace *w); -Workspace *workspace_unref(Workspace *w); - -DEFINE_TRIVIAL_CLEANUP_FUNC(Workspace*, workspace_unref); - -Workspace *workspace_attach(Workspace *w, Session *s); -Workspace *workspace_detach(Workspace *w, Session *s); -void workspace_refresh(Workspace *w); - -void workspace_dirty(Workspace *w); -void workspace_feed(Workspace *w, idev_data *data); -bool workspace_draw(Workspace *w, const grdev_display_target *target); - -/* - * Displays - */ - -struct Display { - Session *session; - LIST_FIELDS(Display, displays_by_session); - grdev_display *grdev; - uint32_t width; - uint32_t height; -}; - -int display_new(Display **out, Session *s, grdev_display *grdev); -Display *display_free(Display *d); - -DEFINE_TRIVIAL_CLEANUP_FUNC(Display*, display_free); - -void display_refresh(Display *d); -void display_render(Display *d, Workspace *w); - -/* - * Sessions - */ - -struct Session { - Manager *manager; - sysview_session *sysview; - grdev_session *grdev; - idev_session *idev; - - LIST_FIELDS(Session, sessions_by_workspace); - Workspace *my_ws; - Workspace *active_ws; - - LIST_HEAD(Display, display_list); - sd_event_source *redraw_src; -}; - -int session_new(Session **out, Manager *m, sysview_session *session); -Session *session_free(Session *s); - -DEFINE_TRIVIAL_CLEANUP_FUNC(Session*, session_free); - -void session_dirty(Session *s); - -void session_add_device(Session *s, sysview_device *device); -void session_remove_device(Session *s, sysview_device *device); -void session_refresh_device(Session *s, sysview_device *device, struct udev_device *ud); - -/* - * Managers - */ - -struct Manager { - sd_event *event; - sd_bus *sysbus; - unifont *uf; - sysview_context *sysview; - grdev_context *grdev; - idev_context *idev; - LIST_HEAD(Workspace, workspace_list); -}; - -int manager_new(Manager **out); -Manager *manager_free(Manager *m); - -DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free); - -int manager_run(Manager *m); |