Beispiel #1
0
void
ply_terminal_stop_watching_for_active_vt_change (ply_terminal_t                          *terminal,
        ply_terminal_active_vt_changed_handler_t active_vt_changed_handler,
        void                                    *user_data)
{
    ply_list_node_t *node;

    if (!ply_terminal_is_vt (terminal))
        return;

    node = ply_list_get_first_node (terminal->vt_change_closures);
    while (node != NULL) {
        ply_terminal_active_vt_changed_closure_t *closure;
        ply_list_node_t *next_node;

        closure = ply_list_node_get_data (node);
        next_node = ply_list_get_next_node (terminal->vt_change_closures, node);

        if (closure->handler == active_vt_changed_handler &&
                closure->user_data == user_data) {
            free (closure);
            ply_list_remove_node (terminal->vt_change_closures, node);
        }

        node = next_node;
    }
}
Beispiel #2
0
void
ply_terminal_set_mode (ply_terminal_t     *terminal,
                       ply_terminal_mode_t mode)
{
    assert (terminal != NULL);
    assert (mode == PLY_TERMINAL_MODE_TEXT || mode == PLY_TERMINAL_MODE_GRAPHICS);

    if (!ply_terminal_is_vt (terminal))
        return;

    if (terminal->should_ignore_mode_changes)
        return;

    switch (mode) {
    case PLY_TERMINAL_MODE_TEXT:
        if (ioctl (terminal->fd, KDSETMODE, KD_TEXT) < 0)
            return;
        break;

    case PLY_TERMINAL_MODE_GRAPHICS:
        if (ioctl (terminal->fd, KDSETMODE, KD_GRAPHICS) < 0)
            return;
        break;
    }
}
Beispiel #3
0
void
ply_terminal_watch_for_vt_changes (ply_terminal_t *terminal)
{
    assert (terminal != NULL);

    struct vt_mode mode = { 0 };

    if (terminal->fd < 0)
        return;

    if (!ply_terminal_is_vt (terminal))
        return;

    if (terminal->is_watching_for_vt_changes)
        return;

    mode.mode = VT_PROCESS;
    mode.relsig = SIGUSR1;
    mode.acqsig = SIGUSR2;

    if (ioctl (terminal->fd, VT_SETMODE, &mode) < 0)
        return;

    ply_event_loop_watch_signal (terminal->loop,
                                 SIGUSR1,
                                 (ply_event_handler_t)
                                 on_leave_vt, terminal);

    ply_event_loop_watch_signal (terminal->loop,
                                 SIGUSR2,
                                 (ply_event_handler_t)
                                 on_enter_vt, terminal);

    terminal->is_watching_for_vt_changes = true;
}
Beispiel #4
0
static bool
open_device (ply_renderer_backend_t *backend)
{
  assert (backend != NULL);
  assert (backend->device_name != NULL);

  if (!load_driver (backend))
    return false;

  if (!ply_terminal_open (backend->terminal))
    {
      ply_trace ("could not open terminal: %m");
      return false;
    }

  if (!ply_terminal_is_vt (backend->terminal))
    {
      ply_trace ("terminal is not a VT");
      ply_terminal_close (backend->terminal);
      return false;
    }

  ply_terminal_watch_for_active_vt_change (backend->terminal,
                                           (ply_terminal_active_vt_changed_handler_t)
                                           on_active_vt_changed,
                                           backend);

  return true;
}
Beispiel #5
0
void
ply_terminal_ignore_mode_changes (ply_terminal_t *terminal,
                                  bool            should_ignore)
{
    if (!ply_terminal_is_vt (terminal))
        return;

    terminal->should_ignore_mode_changes = should_ignore;
}
Beispiel #6
0
bool
ply_terminal_deactivate_vt (ply_terminal_t *terminal)
{
    int old_vt_number;

    assert (terminal != NULL);

    if (!ply_terminal_is_vt (terminal)) {
        ply_trace ("terminal is not for a VT");
        return false;
    }

    if (terminal->initial_vt_number < 0) {
        ply_trace ("Don't know where to jump to");
        return false;
    }

    if (terminal->initial_vt_number == terminal->vt_number) {
        ply_trace ("can't deactivate initial VT");
        return false;
    }

    /* Otherwise we'd close and free the terminal before handling the
     * "leaving the VT" signal.
     */
    ply_terminal_stop_watching_for_vt_changes (terminal);

    old_vt_number = terminal->vt_number;

    if (ply_terminal_is_active (terminal)) {
        ply_trace ("Attempting to set active vt back to %d from %d",
                   terminal->initial_vt_number, old_vt_number);
        if (!set_active_vt (terminal, terminal->initial_vt_number)) {
            ply_trace ("Couldn't move console to initial vt: %m");
            return false;
        }

        if (!wait_for_vt_to_become_active (terminal, terminal->initial_vt_number)) {
            ply_trace ("Error while waiting for vt %d to become active: %m",
                       terminal->initial_vt_number);
            return false;
        }
    } else {
        ply_trace ("terminal for vt %d is inactive", terminal->vt_number);
    }

    if (!deallocate_vt (terminal, old_vt_number)) {
        ply_trace ("couldn't deallocate vt %d: %m", old_vt_number);
        return false;
    }

    return true;
}
Beispiel #7
0
void
ply_terminal_watch_for_active_vt_change (ply_terminal_t                          *terminal,
        ply_terminal_active_vt_changed_handler_t active_vt_changed_handler,
        void                                    *user_data)
{
    ply_terminal_active_vt_changed_closure_t *closure;

    if (!ply_terminal_is_vt (terminal))
        return;

    closure = calloc (1, sizeof(*closure));
    closure->handler = active_vt_changed_handler;
    closure->user_data = user_data;

    ply_list_append_data (terminal->vt_change_closures, closure);
}
Beispiel #8
0
bool
ply_terminal_open (ply_terminal_t *terminal)
{
    ply_terminal_open_result_t open_result;

    assert (terminal != NULL);

    if (terminal->is_open) {
        ply_trace ("terminal %s is already open", terminal->name);
        return true;
    }

    ply_trace ("trying to open terminal '%s'", terminal->name);

    open_result = ply_terminal_open_device (terminal);
    if (open_result != PLY_TERMINAL_OPEN_RESULT_SUCCESS) {
        ply_trace ("could not open %s : %m", terminal->name);
        return false;
    }

    ply_terminal_refresh_geometry (terminal);

    ply_terminal_look_up_color_palette (terminal);
    ply_terminal_save_color_palette (terminal);

    ply_event_loop_watch_signal (terminal->loop,
                                 SIGWINCH,
                                 (ply_event_handler_t)
                                 ply_terminal_refresh_geometry,
                                 terminal);

    if (ply_terminal_is_vt (terminal)) {
        ply_terminal_watch_for_vt_changes (terminal);

        if (get_active_vt (terminal) == terminal->vt_number)
            terminal->is_active = true;
        else
            terminal->is_active = false;
    }

    terminal->is_open = true;

    return true;
}
Beispiel #9
0
bool
ply_terminal_activate_vt (ply_terminal_t *terminal)
{
    assert (terminal != NULL);

    if (!ply_terminal_is_vt (terminal))
        return false;

    if (terminal->is_active)
        return true;

    if (!set_active_vt (terminal, terminal->vt_number)) {
        ply_trace ("unable to set active vt to %d: %m",
                   terminal->vt_number);
        return false;
    }

    return true;
}
Beispiel #10
0
void
ply_terminal_stop_watching_for_vt_changes (ply_terminal_t *terminal)
{
    struct vt_mode mode = { 0 };

    if (!ply_terminal_is_vt (terminal))
        return;

    if (!terminal->is_watching_for_vt_changes)
        return;

    terminal->is_watching_for_vt_changes = false;

    ply_event_loop_stop_watching_signal (terminal->loop, SIGUSR1);
    ply_event_loop_stop_watching_signal (terminal->loop, SIGUSR2);

    mode.mode = VT_AUTO;
    ioctl (terminal->fd, VT_SETMODE, &mode);
}