"\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"
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),
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, ""),
#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#include "conf.h"
#include "eloop.h"
#include "kmscon_conf.h"
#include "kmscon_seat.h"
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);
}
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)
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;
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;
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,
if (ret)
goto err_name;
- ret = uterm_vt_allocate(seat->vtm, &seat->vt, seat->name,
- seat->input, kmscon_conf.vt, seat_vt_event,
- seat);
+ ret = uterm_input_register_cb(seat->input, seat_input_event, seat);
if (ret)
goto err_input;
- ret = kmscon_terminal_register(&s, seat);
+ ret = uterm_vt_allocate(seat->vtm, &seat->vt, seat->name,
+ seat->input, kmscon_conf.vt, seat_vt_event,
+ 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:
}
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);
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;
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);
}
if (!sess)
return;
+ log_debug("enable session %p", sess);
+
sess->enabled = true;
if (sess->seat && !sess->seat->cur_sess)
session_activate(sess);
if (!sess)
return;
+ log_debug("disable session %p", sess);
+
if (sess->seat)
session_deactivate(sess);
sess->enabled = false;