6 #include "ecore_fb_private.h"
8 static int _ecore_fb_vt_do_switch = 0;
10 static int _ecore_fb_vt_tty0_fd = -1;
11 static int _ecore_fb_vt_tty_fd = -1;
12 static int _ecore_fb_vt_current_vt = 0;
13 static int _ecore_fb_vt_prev_vt = 0;
15 static struct termios _ecore_fb_tty_prev_tio_mode;
16 static struct vt_mode _ecore_fb_vt_prev_mode;
18 static Eina_Bool _ecore_fb_signal_usr_handler(void *data, int type, void *ev);
19 static Ecore_Event_Handler *_ecore_fb_user_handler = NULL;
20 static int _ecore_fb_tty_prev_mode = 0;
21 static int _ecore_fb_tty_prev_kd_mode = 0;
23 /* callbacks for an attach/release of a vt */
24 static void (*_ecore_fb_func_fb_lost) (void *data) = NULL;
25 static void *_ecore_fb_func_fb_lost_data = NULL;
26 static void (*_ecore_fb_func_fb_gain) (void *data) = NULL;
27 static void *_ecore_fb_func_fb_gain_data = NULL;
29 /* FIXME what is the filter for? */
30 static Ecore_Event_Filter *_ecore_fb_filter_handler = NULL;
32 static void *_ecore_fb_event_filter_start(void *data);
33 static Eina_Bool _ecore_fb_event_filter_filter(void *data, void *loop_data, int type, void *event);
34 static void _ecore_fb_event_filter_end(void *data, void *loop_data);
38 static void _ecore_fb_vt_switch(int vt);
42 _ecore_fb_signal_usr_handler(void *data __UNUSED__, int type __UNUSED__, void *ev)
44 Ecore_Event_Signal_User *e;
46 e = (Ecore_Event_Signal_User *)ev;
50 if (_ecore_fb_func_fb_lost) _ecore_fb_func_fb_lost(_ecore_fb_func_fb_lost_data);
51 /* TODO stop listening from the devices? let the callback do it? */
52 ioctl(_ecore_fb_vt_tty_fd, VT_RELDISP, 1);
54 else if (e->number == 2)
57 if (_ecore_fb_func_fb_gain) _ecore_fb_func_fb_gain(_ecore_fb_func_fb_gain_data);
58 /* TODO reattach all devices */
65 _ecore_fb_vt_switch(int vt)
68 if (_ecore_fb_vt_tty_fd != 0)
70 if (vt != _ecore_fb_vt_current_vt)
72 tcsetattr(_ecore_fb_vt_tty_fd, TCSAFLUSH, &_ecore_fb_tty_prev_tio_mode);
73 ioctl(_ecore_fb_vt_tty_fd, KDSETMODE, _ecore_fb_tty_prev_kd_mode);
74 ioctl(_ecore_fb_vt_tty_fd, KDSKBMODE, _ecore_fb_tty_prev_mode);
77 ioctl(_ecore_fb_vt_tty_fd, VT_ACTIVATE, vt);
82 _ecore_fb_vt_setup(void)
86 // struct termios tio;
87 struct vt_mode new_vtmode;
89 if (_ecore_fb_vt_current_vt != _ecore_fb_vt_prev_vt)
91 snprintf(buf, sizeof(buf), "/dev/tty%i", _ecore_fb_vt_current_vt);
92 if ((_ecore_fb_vt_tty_fd = open(buf, O_RDWR)) < 0)
94 printf("[ecore_fb:vt_setup] can't open tty %d\n", _ecore_fb_vt_current_vt);
97 close(_ecore_fb_vt_tty0_fd);
98 _ecore_fb_vt_tty0_fd = -1;
99 /* FIXME detach the process from current tty ? */
102 _ecore_fb_vt_tty_fd = _ecore_fb_vt_tty0_fd;
104 tcgetattr(_ecore_fb_vt_tty_fd, &_ecore_fb_tty_prev_tio_mode);
105 ioctl(_ecore_fb_vt_tty_fd, KDGETMODE, &_ecore_fb_tty_prev_kd_mode);
106 ioctl(_ecore_fb_vt_tty_fd, VT_GETMODE, &_ecore_fb_vt_prev_mode);
108 if (ioctl(_ecore_fb_vt_tty_fd, KDSETMODE, KD_GRAPHICS) < 0)
110 perror("[ecore_fb:vt_setup] can't set the mode to KD_GRAPHICS");
111 close(_ecore_fb_vt_tty_fd);
112 _ecore_fb_vt_tty_fd = -1;
115 ioctl(_ecore_fb_vt_tty_fd, KDGKBMODE, &_ecore_fb_tty_prev_mode);
117 /* support of switching */
118 new_vtmode.mode = VT_PROCESS;
119 new_vtmode.waitv = 0;
120 new_vtmode.relsig = SIGUSR1;
121 new_vtmode.acqsig = SIGUSR2;
122 if (ioctl(_ecore_fb_vt_tty_fd, VT_SETMODE, &new_vtmode) < 0)
124 perror("[ecore_fb:vt_setup] can't set the tty mode");
125 close(_ecore_fb_vt_tty_fd);
126 _ecore_fb_vt_tty_fd = -1;
129 /* register signal handlers when alloc/detach of vt */
130 _ecore_fb_user_handler = ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER,
131 _ecore_fb_signal_usr_handler,
133 /* What does this do? */
134 _ecore_fb_filter_handler = ecore_event_filter_add(_ecore_fb_event_filter_start, _ecore_fb_event_filter_filter, _ecore_fb_event_filter_end, NULL);
137 if (ioctl(_ecore_fb_vt_tty_fd, VT_ACTIVATE, _ecore_fb_vt_current_vt) < 0)
139 perror("[ecore_fb:vt_setup] error on VT_ACTIVATE");
140 close(_ecore_fb_vt_tty_fd);
141 _ecore_fb_vt_tty_fd = -1;
144 if(ioctl(_ecore_fb_vt_tty_fd, VT_WAITACTIVE, _ecore_fb_vt_current_vt) < 0)
146 perror("[ecore_fb:vt_setup] error on VT_WAITACTIVE");
147 close(_ecore_fb_vt_tty_fd);
148 _ecore_fb_vt_tty_fd = -1;
151 /* FIXME assign the fb to the tty in case isn't setup */
156 ecore_fb_vt_init(void)
158 struct vt_stat vtstat;
160 /* as root you can allocate another tty */
162 _ecore_fb_vt_do_switch = 1;
163 if ((_ecore_fb_vt_tty0_fd = open("/dev/tty0", O_RDONLY)) < 0)
165 printf("[ecore_fb:init] can't open /dev/tty0\n");
168 /* query current vt state */
169 if ((ioctl(_ecore_fb_vt_tty0_fd, VT_GETSTATE, &vtstat)) < 0)
171 printf("[ecore_fb:init] can't get current tty state\n");
174 _ecore_fb_vt_prev_vt = vtstat.v_active;
175 /* switch to another tty */
176 if (_ecore_fb_vt_do_switch)
180 if ((ioctl(_ecore_fb_vt_tty0_fd, VT_OPENQRY, &vtno) < 0))
182 printf("[ecore_fb:init] can't query for a vt\n");
185 _ecore_fb_vt_current_vt = vtno;
187 /* use current tty */
189 _ecore_fb_vt_current_vt = _ecore_fb_vt_prev_vt;
190 if (!_ecore_fb_vt_setup())
192 printf("[ecore_fb:init] can't setup the vt, restoring previous mode...\n");
193 /* TODO finish this */
194 if (_ecore_fb_vt_do_switch)
196 printf("[ecore_fb:init] switching back to vt %d\n", _ecore_fb_vt_prev_vt);
204 ecore_fb_vt_shutdown(void)
206 /* restore the previous mode */
207 if (_ecore_fb_vt_tty_fd != -1)
209 tcsetattr(_ecore_fb_vt_tty_fd, TCSAFLUSH, &_ecore_fb_tty_prev_tio_mode);
210 ioctl(_ecore_fb_vt_tty_fd, KDSETMODE, _ecore_fb_tty_prev_kd_mode);
211 ioctl(_ecore_fb_vt_tty_fd, KDSKBMODE, _ecore_fb_tty_prev_mode);
212 ioctl(_ecore_fb_vt_tty_fd, VT_SETMODE, &_ecore_fb_vt_prev_mode);
213 /* go back to previous vt */
214 close(_ecore_fb_vt_tty_fd);
215 _ecore_fb_vt_tty_fd = -1;
218 if (_ecore_fb_user_handler) ecore_event_handler_del(_ecore_fb_user_handler);
219 _ecore_fb_user_handler = NULL;
221 if (_ecore_fb_filter_handler) ecore_event_filter_del(_ecore_fb_filter_handler);
222 _ecore_fb_filter_handler = NULL;
226 * @addtogroup Ecore_FB_Group Ecore_FB - Frame buffer convenience functions.
232 * @brief Set a callback called when a virtual terminal is gained.
234 * @param func The callback called when vt is gained.
235 * @param data The data to pass to the callback.
237 * This function sets the callback @p func which will be called when a
238 * virtual terminal is gained (for example you press Ctrl-Alt-F1 to go
239 * to vt1 and your app was using vt1). @p data will be pass to @p func if
240 * the callback is called.
243 ecore_fb_callback_gain_set(void (*func) (void *data), void *data)
245 _ecore_fb_func_fb_gain = func;
246 _ecore_fb_func_fb_gain_data = data;
250 * @brief Set a callback called when a virtual terminal is lost.
252 * @param func The callback called when vt is lost.
253 * @param data The data to pass to the callback.
255 * This function sets the callback @p func which will be called when a
256 * virtual terminal is lost (someone wants the tv from you and you
257 * want to give up that vt). @p data will be pass to @p func if the
258 * callback is called.
261 ecore_fb_callback_lose_set(void (*func) (void *data), void *data)
263 _ecore_fb_func_fb_lost = func;
264 _ecore_fb_func_fb_lost_data = data;
272 typedef struct _Ecore_Fb_Filter_Data Ecore_Fb_Filter_Data;
274 struct _Ecore_Fb_Filter_Data
280 _ecore_fb_event_filter_start(void *data __UNUSED__)
282 Ecore_Fb_Filter_Data *filter_data;
284 filter_data = calloc(1, sizeof(Ecore_Fb_Filter_Data));
289 _ecore_fb_event_filter_filter(void *data __UNUSED__, void *loop_data,int type, void *event __UNUSED__)
291 Ecore_Fb_Filter_Data *filter_data;
293 filter_data = loop_data;
294 if (!filter_data) return EINA_TRUE;
295 if (type == ECORE_FB_EVENT_MOUSE_MOVE)
297 if ((filter_data->last_event_type) == ECORE_FB_EVENT_MOUSE_MOVE)
299 filter_data->last_event_type = type;
303 filter_data->last_event_type = type;
308 _ecore_fb_event_filter_end(void *data __UNUSED__, void *loop_data)
310 Ecore_Fb_Filter_Data *filter_data;
312 filter_data = loop_data;
313 if (filter_data) free(filter_data);