seat: allow session-switching with keyboard

This adds two new grabs to switch sessions within kmscon. They are set to
ctrl+alt+Left/Right by default.

To improve debugging, we also add some log-messages to session management.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
David Herrmann 2012-10-15 18:02:12 +02:00
parent 22e63dbdba
commit 488f7abac0
3 changed files with 129 additions and 25 deletions

View File

@ -103,14 +103,18 @@ static void print_help()
"\t --xkb-repeat-rate <msecs> [50]\n"
"\t Delay between two key-repeats in ms\n"
"\n"
"\t --grab-scroll-up <grab> [<Shift>Up]\n"
"\t Shortcut to scroll up\n"
"\t --grab-scroll-down <grab> [<Shift>Down]\n"
"\t Shortcut to scroll down\n"
"\t --grab-page-up <grab> [<Shift>Prior]\n"
"\t Shortcut to scroll page up\n"
"\t --grab-page-down <grab> [<Shift>Next]\n"
"\t Shortcut to scroll page down\n"
"\t --grab-scroll-up <grab> [<Shift>Up]\n"
"\t Shortcut to scroll up\n"
"\t --grab-scroll-down <grab> [<Shift>Down]\n"
"\t Shortcut to scroll down\n"
"\t --grab-page-up <grab> [<Shift>Prior]\n"
"\t Shortcut to scroll page up\n"
"\t --grab-page-down <grab> [<Shift>Next]\n"
"\t Shortcut to scroll page down\n"
"\t --grab-session-next <grab> [<Ctrl><Alt>Right]\n"
"\t Switch to next session\n"
"\t --grab-session-prev <grab> [<Ctrl><Alt>Left]\n"
"\t Switch to previous session\n"
"\n"
"Font Options:\n"
"\t --font-engine <engine> [pango]\n"
@ -245,6 +249,12 @@ static struct conf_grab def_grab_page_up =
static struct conf_grab def_grab_page_down =
CONF_SINGLE_GRAB(SHL_SHIFT_MASK, XKB_KEY_Next);
static struct conf_grab def_grab_session_next =
CONF_SINGLE_GRAB(SHL_CONTROL_MASK | SHL_ALT_MASK, XKB_KEY_Right);
static struct conf_grab def_grab_session_prev =
CONF_SINGLE_GRAB(SHL_CONTROL_MASK | SHL_ALT_MASK, XKB_KEY_Left);
struct conf_option options[] = {
CONF_OPTION_BOOL('h', "help", aftercheck_help, &kmscon_conf.help, false),
CONF_OPTION_BOOL('v', "verbose", NULL, &kmscon_conf.verbose, false),
@ -265,6 +275,8 @@ struct conf_option options[] = {
CONF_OPTION_GRAB(0, "grab-scroll-down", NULL, &kmscon_conf.grab_scroll_down, &def_grab_scroll_down),
CONF_OPTION_GRAB(0, "grab-page-up", NULL, &kmscon_conf.grab_page_up, &def_grab_page_up),
CONF_OPTION_GRAB(0, "grab-page-down", NULL, &kmscon_conf.grab_page_down, &def_grab_page_down),
CONF_OPTION_GRAB(0, "grab-session-next", NULL, &kmscon_conf.grab_session_next, &def_grab_session_next),
CONF_OPTION_GRAB(0, "grab-session-prev", NULL, &kmscon_conf.grab_session_prev, &def_grab_session_prev),
CONF_OPTION_STRING(0, "xkb-layout", NULL, &kmscon_conf.xkb_layout, "us"),
CONF_OPTION_STRING(0, "xkb-variant", NULL, &kmscon_conf.xkb_variant, ""),
CONF_OPTION_STRING(0, "xkb-options", NULL, &kmscon_conf.xkb_options, ""),

View File

@ -72,6 +72,7 @@ struct kmscon_conf_t {
char **argv;
/* terminal scroll-back buffer size */
unsigned int sb_size;
/* scroll-up grab */
struct conf_grab *grab_scroll_up;
/* scroll-down grab */
@ -80,6 +81,10 @@ struct kmscon_conf_t {
struct conf_grab *grab_page_up;
/* page-down grab */
struct conf_grab *grab_page_down;
/* session-next grab */
struct conf_grab *grab_session_next;
/* session-prev grab */
struct conf_grab *grab_session_prev;
/* seats */
char **seats;

View File

@ -32,6 +32,7 @@
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "conf.h"
#include "eloop.h"
#include "kmscon_conf.h"
#include "kmscon_seat.h"
@ -88,11 +89,13 @@ static void session_call(struct kmscon_session *sess, unsigned int event,
static void session_call_activate(struct kmscon_session *sess)
{
log_debug("activate session %p", sess);
session_call(sess, KMSCON_SESSION_ACTIVATE, NULL);
}
static void session_call_deactivate(struct kmscon_session *sess)
{
log_debug("deactivate session %p", sess);
session_call(sess, KMSCON_SESSION_DEACTIVATE, NULL);
}
@ -108,12 +111,14 @@ static void session_call_display_gone(struct kmscon_session *sess,
session_call(sess, KMSCON_SESSION_DISPLAY_GONE, disp);
}
static void session_activate(struct kmscon_session *sess)
static int session_activate(struct kmscon_session *sess)
{
struct kmscon_seat *seat = sess->seat;
if (seat->cur_sess == sess || !sess->enabled)
return;
if (seat->cur_sess == sess)
return 0;
if (!sess->enabled)
return -EINVAL;
if (seat->cur_sess) {
if (seat->awake)
@ -124,12 +129,15 @@ static void session_activate(struct kmscon_session *sess)
seat->cur_sess = sess;
if (seat->awake)
session_call_activate(sess);
return 0;
}
static void session_deactivate(struct kmscon_session *sess)
{
struct kmscon_seat *seat = sess->seat;
struct shl_dlist *iter;
struct kmscon_session *s;
if (seat->cur_sess != sess)
return;
@ -138,18 +146,50 @@ static void session_deactivate(struct kmscon_session *sess)
session_call_deactivate(sess);
seat->cur_sess = NULL;
shl_dlist_for_each(iter, &seat->sessions) {
sess = shl_dlist_entry(iter, struct kmscon_session, list);
if (!sess->enabled)
shl_dlist_for_each_but_one(iter, &sess->list, &seat->sessions) {
s = shl_dlist_entry(iter, struct kmscon_session, list);
if (!s->enabled)
continue;
seat->cur_sess = sess;
seat->cur_sess = s;
if (seat->awake)
session_call_activate(seat->cur_sess);
break;
}
}
static void seat_activate_next(struct kmscon_seat *seat)
{
struct shl_dlist *iter;
struct kmscon_session *sess;
if (!seat->cur_sess)
return;
shl_dlist_for_each_but_one(iter, &seat->cur_sess->list,
&seat->sessions) {
sess = shl_dlist_entry(iter, struct kmscon_session, list);
if (!session_activate(sess))
break;
}
}
static void seat_activate_prev(struct kmscon_seat *seat)
{
struct shl_dlist *iter;
struct kmscon_session *sess;
if (!seat->cur_sess)
return;
shl_dlist_for_each_reverse_but_one(iter, &seat->cur_sess->list,
&seat->sessions) {
sess = shl_dlist_entry(iter, struct kmscon_session, list);
if (!session_activate(sess))
break;
}
}
static void activate_display(struct kmscon_display *d)
{
int ret;
@ -257,6 +297,29 @@ static int seat_vt_event(struct uterm_vt *vt, unsigned int event, void *data)
return 0;
}
static void seat_input_event(struct uterm_input *input,
struct uterm_input_event *ev,
void *data)
{
struct kmscon_seat *seat = data;
if (ev->handled)
return;
if (conf_grab_matches(kmscon_conf.grab_session_next,
ev->mods, ev->num_syms, ev->keysyms)) {
ev->handled = true;
seat_activate_next(seat);
return;
}
if (conf_grab_matches(kmscon_conf.grab_session_prev,
ev->mods, ev->num_syms, ev->keysyms)) {
ev->handled = true;
seat_activate_prev(seat);
return;
}
}
int kmscon_seat_new(struct kmscon_seat **out,
struct ev_eloop *eloop,
struct uterm_vt_master *vtm,
@ -298,24 +361,38 @@ int kmscon_seat_new(struct kmscon_seat **out,
if (ret)
goto err_name;
ret = uterm_input_register_cb(seat->input, seat_input_event, seat);
if (ret)
goto err_input;
ret = uterm_vt_allocate(seat->vtm, &seat->vt, seat->name,
seat->input, kmscon_conf.vt, seat_vt_event,
seat);
if (ret)
goto err_input;
ret = kmscon_terminal_register(&s, seat);
if (ret)
goto err_vt;
kmscon_session_enable(s);
goto err_input_cb;
ev_eloop_ref(seat->eloop);
uterm_vt_master_ref(seat->vtm);
*out = seat;
/* register built-in sessions */
ret = kmscon_terminal_register(&s, seat);
if (ret == -EOPNOTSUPP)
log_notice("terminal support not compiled in");
else if (ret)
goto err_sessions;
else
kmscon_session_enable(s);
return 0;
err_vt:
uterm_vt_deallocate(seat->vt);
err_sessions:
kmscon_seat_free(seat);
return ret;
err_input_cb:
uterm_input_unregister_cb(seat->input, seat_input_event, seat);
err_input:
uterm_input_unref(seat->input);
err_name:
@ -348,6 +425,7 @@ void kmscon_seat_free(struct kmscon_seat *seat)
}
uterm_vt_deallocate(seat->vt);
uterm_input_unregister_cb(seat->input, seat_input_event, seat);
uterm_input_unref(seat->input);
free(seat->name);
uterm_vt_master_unref(seat->vtm);
@ -437,13 +515,16 @@ int kmscon_seat_register_session(struct kmscon_seat *seat,
seat->name);
return -ENOMEM;
}
log_debug("register session %p", sess);
memset(sess, 0, sizeof(*sess));
sess->ref = 1;
sess->seat = seat;
sess->cb = cb;
sess->data = data;
shl_dlist_link(&seat->sessions, &sess->list);
shl_dlist_link_tail(&seat->sessions, &sess->list);
*out = sess;
return 0;
@ -471,8 +552,10 @@ void kmscon_session_unregister(struct kmscon_session *sess)
if (!sess || !sess->seat)
return;
shl_dlist_unlink(&sess->list);
log_debug("unregister session %p", sess);
session_deactivate(sess);
shl_dlist_unlink(&sess->list);
sess->seat = NULL;
session_call(sess, KMSCON_SESSION_UNREGISTER, NULL);
}
@ -508,6 +591,8 @@ void kmscon_session_enable(struct kmscon_session *sess)
if (!sess)
return;
log_debug("enable session %p", sess);
sess->enabled = true;
if (sess->seat && !sess->seat->cur_sess)
session_activate(sess);
@ -518,6 +603,8 @@ void kmscon_session_disable(struct kmscon_session *sess)
if (!sess)
return;
log_debug("disable session %p", sess);
if (sess->seat)
session_deactivate(sess);
sess->enabled = false;