ecore-drm: added vt switch key event handler

Summary:
Because vt mode of tty is set to VT_PROCESS,
ecore-drm is responsible for managing switch-to or switch-from other vt.
For that, ecore-drm has to handshake with kernel(tty driver).

 On switch-from side(A):
  1. Listen key event to satisfy vt switch key binding.
  2. ioctl(fd, VT_ACTIVE, switch-to-vt) for activating switch-to vt.
  3. Receive SIGUSR1(relsig) from kernel.
  4. Prepare releasing vt, and ioctl(fd, VT_RELDISP, 1).

 On switch-to side(B):
  0. Kernel receive VT_RELDISP with value 1(ok) from switch-from vt.
  1. Receive SIGUSR2(acqsig) from kernel.
  2. ioctl(fd, VT_RELDISP, VT_ACKACQ), and start to setup vt.

 This revision added A-1 step on above.

Test Plan:
 On booted PC with systemd.
 1. launch enlightenment_start with drm and wayland
 ex) ECORE_DRM_TTY=/dev/tty1 \
     E_WL_FORCE=drm \
     ELM_ENGINE=wayland_shm enlightenment_start
 2. try to switch vt by pressing "Ctrl + Alt + (F1 ~ F8)"

Reviewers: gwanglim, stefan_schmidt, devilhorns

Subscribers: cedric

Differential Revision: https://phab.enlightenment.org/D1280
This commit is contained in:
MinJeong Kim 2014-09-15 12:03:52 -04:00 committed by Chris Michael
parent 11237fd858
commit 96a83aecfa
2 changed files with 50 additions and 1 deletions

View File

@ -98,6 +98,7 @@ struct _Ecore_Drm_Device
int fd;
const char *name;
Ecore_Event_Handler *event_hdlr;
Ecore_Event_Handler *switch_hdlr;
} tty;
unsigned int format;

View File

@ -12,6 +12,33 @@
# define KDSKBMUTE 0x4B51
#endif
static Eina_Bool
_ecore_drm_tty_cb_vt_switch(void *data, int type EINA_UNUSED, void *event)
{
Ecore_Drm_Device *dev;
Ecore_Event_Key *ev;
int keycode;
int vt;
dev = data;
ev = event;
keycode = ev->keycode - 8;
if ((ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) &&
(ev->modifiers & ECORE_EVENT_MODIFIER_ALT) &&
(keycode >= KEY_F1) && (keycode <= KEY_F8))
{
vt = (keycode - KEY_F1 + 1);
/* make a vt #vt active */
ioctl(dev->tty.fd, VT_ACTIVATE, vt);
return ECORE_CALLBACK_DONE;
}
return ECORE_CALLBACK_PASS_ON;
}
static Eina_Bool
_ecore_drm_tty_cb_signal(void *data, int type EINA_UNUSED, void *event)
{
@ -22,8 +49,11 @@ _ecore_drm_tty_cb_signal(void *data, int type EINA_UNUSED, void *event)
dev = data;
ev = event;
/* FIXME: this sigdata doesn't have pid or uid info
* si_code is single value to get from sigdata
*/
sigdata = ev->data;
if (sigdata.si_pid != getpid()) return ECORE_CALLBACK_RENEW;
if (sigdata.si_code != SI_KERNEL) return ECORE_CALLBACK_RENEW;
if (ev->number == 1)
{
@ -54,6 +84,13 @@ _ecore_drm_tty_cb_signal(void *data, int type EINA_UNUSED, void *event)
/* issue ioctl to release vt */
if (!ecore_drm_tty_release(dev))
ERR("Could not release VT: %m");
/* remove switch handler */
if (dev->tty.switch_hdlr)
{
ecore_event_handler_del(dev->tty.switch_hdlr);
dev->tty.switch_hdlr = NULL;
}
}
else
ERR("Could not drop drm master: %m");
@ -80,6 +117,12 @@ _ecore_drm_tty_cb_signal(void *data, int type EINA_UNUSED, void *event)
/* enable inputs */
EINA_LIST_FOREACH(dev->inputs, l, input)
ecore_drm_inputs_enable(input);
/* listen key event for vt switch */
if (!dev->tty.switch_hdlr)
ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
_ecore_drm_tty_cb_vt_switch, dev);
}
else
ERR("Could not acquire VT: %m");
@ -212,6 +255,11 @@ ecore_drm_tty_open(Ecore_Drm_Device *dev, const char *name)
ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER,
_ecore_drm_tty_cb_signal, dev);
/* setup handler for key event of vt switch */
dev->tty.switch_hdlr =
ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
_ecore_drm_tty_cb_vt_switch, dev);
/* set current tty into env */
setenv("ECORE_DRM_TTY", tty, 1);