efl/legacy/ecore/src/lib/ecore_fb/ecore_fb_vt.c

291 lines
7.6 KiB
C
Raw Normal View History

/*
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "Ecore_Fb.h"
#include "ecore_fb_private.h"
static int _ecore_fb_vt_do_switch = 0;
static int _ecore_fb_vt_tty0_fd = 0;
static int _ecore_fb_vt_tty_fd = 0;
static int _ecore_fb_vt_current_vt = 0;
static int _ecore_fb_vt_prev_vt = 0;
static struct termios _ecore_fb_tty_prev_tio_mode;
static struct vt_mode _ecore_fb_vt_prev_mode;
Fix callback signatures The change from returning int to Eina_Bool left several call sites with warnings because they were not updated. Here they are fixed by using Coccinelle, a tool that allows us to automate tasks like that. This commit was generated from the following semantic patch: virtual org @r1@ identifier fn!=NULL, fn2; expression E1, E2, E3; @@ ( ecore_event_handler_add(E1, fn, ...) | ecore_event_filter_add(E1, fn, ...) | ecore_idler_add(fn, ...) | ecore_idle_enterer_add(E1, fn, ...) | ecore_idle_enterer_before_add(E1, fn, ...) | ecore_idle_exiter_add(E1, fn, ...) | ecore_main_fd_handler_add(E1, E2, fn, E3, fn2, ...) | ecore_main_win32_handler_add(E1, fn, ...) | ecore_timer_add(E1, fn, ...) | ecore_timer_loop_add(E1, fn, ...) | ecore_animator_add(fn, ...) | ecore_poller_add(E1, E2, fn, ...) ) @r2@ identifier r1.fn; identifier ret; typedef Eina_Bool; position p; @@ - int + Eina_Bool fn@p(...) { <... ( - return 1; + return EINA_TRUE; | - return 0; + return EINA_FALSE; | - int + Eina_Bool ret; ... return <+...ret...+>; | return ...; ) ...> } @r3@ identifier r1.fn2; identifier ret; position p; @@ - int + Eina_Bool fn2@p(...) { ... ( - return 1; + return EINA_TRUE; | - return 0; + return EINA_FALSE; | - int + Eina_Bool ret; ... return <+...ret...+>; | return ...; ) ... } @r4@ identifier r1.fn; @@ - int + Eina_Bool fn(...); @r5@ identifier r1.fn2; @@ - int + Eina_Bool fn2(...); @script:python depends on org@ p << r2.p; f << r1.fn; @@ import sys msg="WARNING: wrong callback %s! ( %s:%s )" % (f, p[0].file,p[0].line) print >> sys.stderr, msg @script:python depends on org@ p << r3.p; f << r1.fn2; @@ import sys msg="WARNING: wrong callback %s! ( %s:%s )" % (f, p[0].file,p[0].line) print >> sys.stderr, msg SVN revision: 49985
2010-07-01 18:38:05 -07:00
static Eina_Bool _ecore_fb_signal_usr_handler(void *data, int type, void *ev);
static Ecore_Event_Handler *_ecore_fb_user_handler = NULL;
static int _ecore_fb_tty_prev_mode = 0;
static int _ecore_fb_tty_prev_kd_mode = 0;
/* callbacks for an attach/release of a vt */
static void (*_ecore_fb_func_fb_lost) (void *data) = NULL;
static void *_ecore_fb_func_fb_lost_data = NULL;
static void (*_ecore_fb_func_fb_gain) (void *data) = NULL;
static void *_ecore_fb_func_fb_gain_data = NULL;
/* FIXME what is the filter for? */
static Ecore_Event_Filter *_ecore_fb_filter_handler = NULL;
static void *_ecore_fb_event_filter_start(void *data);
Fix callback signatures The change from returning int to Eina_Bool left several call sites with warnings because they were not updated. Here they are fixed by using Coccinelle, a tool that allows us to automate tasks like that. This commit was generated from the following semantic patch: virtual org @r1@ identifier fn!=NULL, fn2; expression E1, E2, E3; @@ ( ecore_event_handler_add(E1, fn, ...) | ecore_event_filter_add(E1, fn, ...) | ecore_idler_add(fn, ...) | ecore_idle_enterer_add(E1, fn, ...) | ecore_idle_enterer_before_add(E1, fn, ...) | ecore_idle_exiter_add(E1, fn, ...) | ecore_main_fd_handler_add(E1, E2, fn, E3, fn2, ...) | ecore_main_win32_handler_add(E1, fn, ...) | ecore_timer_add(E1, fn, ...) | ecore_timer_loop_add(E1, fn, ...) | ecore_animator_add(fn, ...) | ecore_poller_add(E1, E2, fn, ...) ) @r2@ identifier r1.fn; identifier ret; typedef Eina_Bool; position p; @@ - int + Eina_Bool fn@p(...) { <... ( - return 1; + return EINA_TRUE; | - return 0; + return EINA_FALSE; | - int + Eina_Bool ret; ... return <+...ret...+>; | return ...; ) ...> } @r3@ identifier r1.fn2; identifier ret; position p; @@ - int + Eina_Bool fn2@p(...) { ... ( - return 1; + return EINA_TRUE; | - return 0; + return EINA_FALSE; | - int + Eina_Bool ret; ... return <+...ret...+>; | return ...; ) ... } @r4@ identifier r1.fn; @@ - int + Eina_Bool fn(...); @r5@ identifier r1.fn2; @@ - int + Eina_Bool fn2(...); @script:python depends on org@ p << r2.p; f << r1.fn; @@ import sys msg="WARNING: wrong callback %s! ( %s:%s )" % (f, p[0].file,p[0].line) print >> sys.stderr, msg @script:python depends on org@ p << r3.p; f << r1.fn2; @@ import sys msg="WARNING: wrong callback %s! ( %s:%s )" % (f, p[0].file,p[0].line) print >> sys.stderr, msg SVN revision: 49985
2010-07-01 18:38:05 -07:00
static Eina_Bool _ecore_fb_event_filter_filter(void *data, void *loop_data, int type, void *event);
static void _ecore_fb_event_filter_end(void *data, void *loop_data);
/* prototypes */
static void _ecore_fb_vt_switch(int vt);
static int
_ecore_fb_signal_usr_handler(void *data __UNUSED__, int type __UNUSED__, void *ev)
{
Ecore_Event_Signal_User *e;
e = (Ecore_Event_Signal_User *)ev;
if (e->number == 1)
{
/* release vt */
if (_ecore_fb_func_fb_lost) _ecore_fb_func_fb_lost(_ecore_fb_func_fb_lost_data);
/* TODO stop listening from the devices? let the callback do it? */
ioctl(_ecore_fb_vt_tty_fd, VT_RELDISP, 1);
}
else if (e->number == 2)
{
/* attach vt */
if (_ecore_fb_func_fb_gain) _ecore_fb_func_fb_gain(_ecore_fb_func_fb_gain_data);
/* TODO reattach all devices */
}
return 1;
}
static void
_ecore_fb_vt_switch(int vt)
{
vt++;
if (_ecore_fb_vt_tty_fd != 0)
{
if (vt != _ecore_fb_vt_current_vt)
{
tcsetattr(_ecore_fb_vt_tty_fd, TCSAFLUSH, &_ecore_fb_tty_prev_tio_mode);
ioctl(_ecore_fb_vt_tty_fd, KDSETMODE, _ecore_fb_tty_prev_kd_mode);
ioctl(_ecore_fb_vt_tty_fd, KDSKBMODE, _ecore_fb_tty_prev_mode);
}
}
ioctl(_ecore_fb_vt_tty_fd, VT_ACTIVATE, vt);
}
static int
_ecore_fb_vt_setup(void)
{
char buf[64];
struct termios tio;
struct vt_mode new_vtmode;
if(_ecore_fb_vt_current_vt != _ecore_fb_vt_prev_vt)
{
snprintf(buf, sizeof(buf), "/dev/tty%i", _ecore_fb_vt_current_vt);
if((_ecore_fb_vt_tty_fd = open(buf, O_RDWR)) < 0)
{
printf("[ecore_fb:vt_setup] cant open tty %d\n", _ecore_fb_vt_current_vt);
return 0;
}
close(_ecore_fb_vt_tty0_fd);
_ecore_fb_vt_tty0_fd = 0;
/* FIXME detach the process from current tty ? */
}
else
_ecore_fb_vt_tty_fd = _ecore_fb_vt_tty0_fd;
/* for backup */
tcgetattr(_ecore_fb_vt_tty_fd, &_ecore_fb_tty_prev_tio_mode);
ioctl(_ecore_fb_vt_tty_fd, KDGETMODE, &_ecore_fb_tty_prev_kd_mode);
ioctl(_ecore_fb_vt_tty_fd, VT_GETMODE, &_ecore_fb_vt_prev_mode);
if(ioctl(_ecore_fb_vt_tty_fd, KDSETMODE, KD_GRAPHICS) < 0)
{
perror("[ecore_fb:vt_setup] cant set the mode to KD_GRAPHICS");
close(_ecore_fb_vt_tty_fd);
return 0;
}
ioctl(_ecore_fb_vt_tty_fd, KDGKBMODE, &_ecore_fb_tty_prev_mode);
/* support of switching */
new_vtmode.mode = VT_PROCESS;
new_vtmode.waitv = 0;
new_vtmode.relsig = SIGUSR1;
new_vtmode.acqsig = SIGUSR2;
if(ioctl(_ecore_fb_vt_tty_fd, VT_SETMODE, &new_vtmode) < 0)
{
perror("[ecore_fb:vt_setup] cant set the tty mode");
close(_ecore_fb_vt_tty_fd);
return 0;
}
/* register signal handlers when alloc/detach of vt */
_ecore_fb_user_handler = ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER,
_ecore_fb_signal_usr_handler,
NULL);
/* What does this does? */
_ecore_fb_filter_handler = ecore_event_filter_add(_ecore_fb_event_filter_start, _ecore_fb_event_filter_filter, _ecore_fb_event_filter_end, NULL);
usleep(40000);
if(ioctl(_ecore_fb_vt_tty_fd, VT_ACTIVATE, _ecore_fb_vt_current_vt) < 0)
{
perror("[ecore_fb:vt_setup] error on VT_ACTIVATE");
close(_ecore_fb_vt_tty_fd);
return 0;
}
if(ioctl(_ecore_fb_vt_tty_fd, VT_WAITACTIVE, _ecore_fb_vt_current_vt) < 0)
{
perror("[ecore_fb:vt_setup] error on VT_WAITACTIVE");
close(_ecore_fb_vt_tty_fd);
return 0;
}
/* FIXME assign the fb to the tty in case isnt setup */
return 1;
}
int
ecore_fb_vt_init(void)
{
struct vt_stat vtstat;
/* as root you can allocate another tty */
if(!geteuid())
_ecore_fb_vt_do_switch = 1;
if((_ecore_fb_vt_tty0_fd = open("/dev/tty0", O_RDONLY)) < 0)
{
printf("[ecore_fb:init] cant open /dev/tty0\n");
return 0;
}
/* query current vt state */
if((ioctl(_ecore_fb_vt_tty0_fd, VT_GETSTATE, &vtstat)) < 0)
{
printf("[ecore_fb:init] cant get current tty state\n");
return 0;
}
_ecore_fb_vt_prev_vt = vtstat.v_active;
/* switch to another tty */
if(_ecore_fb_vt_do_switch)
{
int vtno;
if ((ioctl(_ecore_fb_vt_tty0_fd, VT_OPENQRY, &vtno) < 0))
{
printf("[ecore_fb:init] cant query for a vt\n");
return 0;
}
_ecore_fb_vt_current_vt = vtno;
}
/* use current tty */
else
_ecore_fb_vt_current_vt = _ecore_fb_vt_prev_vt;
if(!_ecore_fb_vt_setup())
{
printf("[ecore_fb:init] cant setup the vt, restoring previous mode...\n");
/* TODO finish this */
if(_ecore_fb_vt_do_switch)
{
printf("[ecore_fb:init] switching back to vt %d\n", _ecore_fb_vt_prev_vt);
}
return 0;
}
return 1;
}
void
ecore_fb_vt_shutdown(void)
{
/* restore the previous mode */
if(_ecore_fb_vt_tty_fd != 0)
{
tcsetattr(_ecore_fb_vt_tty_fd, TCSAFLUSH, &_ecore_fb_tty_prev_tio_mode);
ioctl(_ecore_fb_vt_tty_fd, KDSETMODE, _ecore_fb_tty_prev_kd_mode);
ioctl(_ecore_fb_vt_tty_fd, KDSKBMODE, _ecore_fb_tty_prev_mode);
ioctl(_ecore_fb_vt_tty_fd, VT_SETMODE, &_ecore_fb_vt_prev_mode);
/* go back to previous vt */
close(_ecore_fb_vt_tty_fd);
_ecore_fb_vt_tty_fd = 0;
}
if(_ecore_fb_user_handler)
ecore_event_handler_del(_ecore_fb_user_handler);
_ecore_fb_user_handler = NULL;
if(_ecore_fb_filter_handler)
ecore_event_filter_del(_ecore_fb_filter_handler);
_ecore_fb_filter_handler = NULL;
}
/**
* To be documented.
*
* FIXME: To be fixed.
* @todo Documentation: Find out what this does.
*/
EAPI void
ecore_fb_callback_gain_set(void (*func) (void *data), void *data)
{
_ecore_fb_func_fb_gain = func;
_ecore_fb_func_fb_gain_data = data;
}
/**
* To be documented.
*
* FIXME: To be fixed.
* @todo Documentation: Find out what this does.
*/
EAPI void
ecore_fb_callback_lose_set(void (*func) (void *data), void *data)
{
_ecore_fb_func_fb_lost = func;
_ecore_fb_func_fb_lost_data = data;
}
typedef struct _Ecore_Fb_Filter_Data Ecore_Fb_Filter_Data;
struct _Ecore_Fb_Filter_Data
{
int last_event_type;
};
static void *
_ecore_fb_event_filter_start(void *data __UNUSED__)
{
Ecore_Fb_Filter_Data *filter_data;
filter_data = calloc(1, sizeof(Ecore_Fb_Filter_Data));
return filter_data;
}
Fix callback signatures The change from returning int to Eina_Bool left several call sites with warnings because they were not updated. Here they are fixed by using Coccinelle, a tool that allows us to automate tasks like that. This commit was generated from the following semantic patch: virtual org @r1@ identifier fn!=NULL, fn2; expression E1, E2, E3; @@ ( ecore_event_handler_add(E1, fn, ...) | ecore_event_filter_add(E1, fn, ...) | ecore_idler_add(fn, ...) | ecore_idle_enterer_add(E1, fn, ...) | ecore_idle_enterer_before_add(E1, fn, ...) | ecore_idle_exiter_add(E1, fn, ...) | ecore_main_fd_handler_add(E1, E2, fn, E3, fn2, ...) | ecore_main_win32_handler_add(E1, fn, ...) | ecore_timer_add(E1, fn, ...) | ecore_timer_loop_add(E1, fn, ...) | ecore_animator_add(fn, ...) | ecore_poller_add(E1, E2, fn, ...) ) @r2@ identifier r1.fn; identifier ret; typedef Eina_Bool; position p; @@ - int + Eina_Bool fn@p(...) { <... ( - return 1; + return EINA_TRUE; | - return 0; + return EINA_FALSE; | - int + Eina_Bool ret; ... return <+...ret...+>; | return ...; ) ...> } @r3@ identifier r1.fn2; identifier ret; position p; @@ - int + Eina_Bool fn2@p(...) { ... ( - return 1; + return EINA_TRUE; | - return 0; + return EINA_FALSE; | - int + Eina_Bool ret; ... return <+...ret...+>; | return ...; ) ... } @r4@ identifier r1.fn; @@ - int + Eina_Bool fn(...); @r5@ identifier r1.fn2; @@ - int + Eina_Bool fn2(...); @script:python depends on org@ p << r2.p; f << r1.fn; @@ import sys msg="WARNING: wrong callback %s! ( %s:%s )" % (f, p[0].file,p[0].line) print >> sys.stderr, msg @script:python depends on org@ p << r3.p; f << r1.fn2; @@ import sys msg="WARNING: wrong callback %s! ( %s:%s )" % (f, p[0].file,p[0].line) print >> sys.stderr, msg SVN revision: 49985
2010-07-01 18:38:05 -07:00
static Eina_Bool
_ecore_fb_event_filter_filter(void *data __UNUSED__, void *loop_data,int type, void *event __UNUSED__)
{
Ecore_Fb_Filter_Data *filter_data;
filter_data = loop_data;
Fix callback signatures The change from returning int to Eina_Bool left several call sites with warnings because they were not updated. Here they are fixed by using Coccinelle, a tool that allows us to automate tasks like that. This commit was generated from the following semantic patch: virtual org @r1@ identifier fn!=NULL, fn2; expression E1, E2, E3; @@ ( ecore_event_handler_add(E1, fn, ...) | ecore_event_filter_add(E1, fn, ...) | ecore_idler_add(fn, ...) | ecore_idle_enterer_add(E1, fn, ...) | ecore_idle_enterer_before_add(E1, fn, ...) | ecore_idle_exiter_add(E1, fn, ...) | ecore_main_fd_handler_add(E1, E2, fn, E3, fn2, ...) | ecore_main_win32_handler_add(E1, fn, ...) | ecore_timer_add(E1, fn, ...) | ecore_timer_loop_add(E1, fn, ...) | ecore_animator_add(fn, ...) | ecore_poller_add(E1, E2, fn, ...) ) @r2@ identifier r1.fn; identifier ret; typedef Eina_Bool; position p; @@ - int + Eina_Bool fn@p(...) { <... ( - return 1; + return EINA_TRUE; | - return 0; + return EINA_FALSE; | - int + Eina_Bool ret; ... return <+...ret...+>; | return ...; ) ...> } @r3@ identifier r1.fn2; identifier ret; position p; @@ - int + Eina_Bool fn2@p(...) { ... ( - return 1; + return EINA_TRUE; | - return 0; + return EINA_FALSE; | - int + Eina_Bool ret; ... return <+...ret...+>; | return ...; ) ... } @r4@ identifier r1.fn; @@ - int + Eina_Bool fn(...); @r5@ identifier r1.fn2; @@ - int + Eina_Bool fn2(...); @script:python depends on org@ p << r2.p; f << r1.fn; @@ import sys msg="WARNING: wrong callback %s! ( %s:%s )" % (f, p[0].file,p[0].line) print >> sys.stderr, msg @script:python depends on org@ p << r3.p; f << r1.fn2; @@ import sys msg="WARNING: wrong callback %s! ( %s:%s )" % (f, p[0].file,p[0].line) print >> sys.stderr, msg SVN revision: 49985
2010-07-01 18:38:05 -07:00
if (!filter_data) return EINA_TRUE;
if (type == ECORE_FB_EVENT_MOUSE_MOVE)
{
if ((filter_data->last_event_type) == ECORE_FB_EVENT_MOUSE_MOVE)
{
filter_data->last_event_type = type;
Fix callback signatures The change from returning int to Eina_Bool left several call sites with warnings because they were not updated. Here they are fixed by using Coccinelle, a tool that allows us to automate tasks like that. This commit was generated from the following semantic patch: virtual org @r1@ identifier fn!=NULL, fn2; expression E1, E2, E3; @@ ( ecore_event_handler_add(E1, fn, ...) | ecore_event_filter_add(E1, fn, ...) | ecore_idler_add(fn, ...) | ecore_idle_enterer_add(E1, fn, ...) | ecore_idle_enterer_before_add(E1, fn, ...) | ecore_idle_exiter_add(E1, fn, ...) | ecore_main_fd_handler_add(E1, E2, fn, E3, fn2, ...) | ecore_main_win32_handler_add(E1, fn, ...) | ecore_timer_add(E1, fn, ...) | ecore_timer_loop_add(E1, fn, ...) | ecore_animator_add(fn, ...) | ecore_poller_add(E1, E2, fn, ...) ) @r2@ identifier r1.fn; identifier ret; typedef Eina_Bool; position p; @@ - int + Eina_Bool fn@p(...) { <... ( - return 1; + return EINA_TRUE; | - return 0; + return EINA_FALSE; | - int + Eina_Bool ret; ... return <+...ret...+>; | return ...; ) ...> } @r3@ identifier r1.fn2; identifier ret; position p; @@ - int + Eina_Bool fn2@p(...) { ... ( - return 1; + return EINA_TRUE; | - return 0; + return EINA_FALSE; | - int + Eina_Bool ret; ... return <+...ret...+>; | return ...; ) ... } @r4@ identifier r1.fn; @@ - int + Eina_Bool fn(...); @r5@ identifier r1.fn2; @@ - int + Eina_Bool fn2(...); @script:python depends on org@ p << r2.p; f << r1.fn; @@ import sys msg="WARNING: wrong callback %s! ( %s:%s )" % (f, p[0].file,p[0].line) print >> sys.stderr, msg @script:python depends on org@ p << r3.p; f << r1.fn2; @@ import sys msg="WARNING: wrong callback %s! ( %s:%s )" % (f, p[0].file,p[0].line) print >> sys.stderr, msg SVN revision: 49985
2010-07-01 18:38:05 -07:00
return EINA_FALSE;
}
}
filter_data->last_event_type = type;
Fix callback signatures The change from returning int to Eina_Bool left several call sites with warnings because they were not updated. Here they are fixed by using Coccinelle, a tool that allows us to automate tasks like that. This commit was generated from the following semantic patch: virtual org @r1@ identifier fn!=NULL, fn2; expression E1, E2, E3; @@ ( ecore_event_handler_add(E1, fn, ...) | ecore_event_filter_add(E1, fn, ...) | ecore_idler_add(fn, ...) | ecore_idle_enterer_add(E1, fn, ...) | ecore_idle_enterer_before_add(E1, fn, ...) | ecore_idle_exiter_add(E1, fn, ...) | ecore_main_fd_handler_add(E1, E2, fn, E3, fn2, ...) | ecore_main_win32_handler_add(E1, fn, ...) | ecore_timer_add(E1, fn, ...) | ecore_timer_loop_add(E1, fn, ...) | ecore_animator_add(fn, ...) | ecore_poller_add(E1, E2, fn, ...) ) @r2@ identifier r1.fn; identifier ret; typedef Eina_Bool; position p; @@ - int + Eina_Bool fn@p(...) { <... ( - return 1; + return EINA_TRUE; | - return 0; + return EINA_FALSE; | - int + Eina_Bool ret; ... return <+...ret...+>; | return ...; ) ...> } @r3@ identifier r1.fn2; identifier ret; position p; @@ - int + Eina_Bool fn2@p(...) { ... ( - return 1; + return EINA_TRUE; | - return 0; + return EINA_FALSE; | - int + Eina_Bool ret; ... return <+...ret...+>; | return ...; ) ... } @r4@ identifier r1.fn; @@ - int + Eina_Bool fn(...); @r5@ identifier r1.fn2; @@ - int + Eina_Bool fn2(...); @script:python depends on org@ p << r2.p; f << r1.fn; @@ import sys msg="WARNING: wrong callback %s! ( %s:%s )" % (f, p[0].file,p[0].line) print >> sys.stderr, msg @script:python depends on org@ p << r3.p; f << r1.fn2; @@ import sys msg="WARNING: wrong callback %s! ( %s:%s )" % (f, p[0].file,p[0].line) print >> sys.stderr, msg SVN revision: 49985
2010-07-01 18:38:05 -07:00
return EINA_TRUE;
}
static void
_ecore_fb_event_filter_end(void *data __UNUSED__, void *loop_data)
{
Ecore_Fb_Filter_Data *filter_data;
filter_data = loop_data;
if (filter_data) free(filter_data);
}