summaryrefslogtreecommitdiff
path: root/src/lib/ecore_fb/ecore_fb_vt.c
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2012-12-02 22:35:45 +0000
committerVincent Torri <vincent.torri@gmail.com>2012-12-02 22:35:45 +0000
commit7d6010b12c47a20e492da808e3192c3f87dab619 (patch)
tree26c6fd189e046a76560c0bc740b85f4d767ae399 /src/lib/ecore_fb/ecore_fb_vt.c
parent53fc441d5475155965d92da89502fe4634a561b2 (diff)
merge: add escape ecore, fix several bugs
SVN revision: 79995
Diffstat (limited to 'src/lib/ecore_fb/ecore_fb_vt.c')
-rw-r--r--src/lib/ecore_fb/ecore_fb_vt.c322
1 files changed, 322 insertions, 0 deletions
diff --git a/src/lib/ecore_fb/ecore_fb_vt.c b/src/lib/ecore_fb/ecore_fb_vt.c
new file mode 100644
index 0000000000..c92c087336
--- /dev/null
+++ b/src/lib/ecore_fb/ecore_fb_vt.c
@@ -0,0 +1,322 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "Ecore_Fb.h"
6#include "ecore_fb_private.h"
7
8static int _ecore_fb_vt_do_switch = 0;
9
10static int _ecore_fb_vt_tty0_fd = -1;
11static int _ecore_fb_vt_tty_fd = -1;
12static int _ecore_fb_vt_current_vt = 0;
13static int _ecore_fb_vt_prev_vt = 0;
14
15static struct termios _ecore_fb_tty_prev_tio_mode;
16static struct vt_mode _ecore_fb_vt_prev_mode;
17
18static Eina_Bool _ecore_fb_signal_usr_handler(void *data, int type, void *ev);
19static Ecore_Event_Handler *_ecore_fb_user_handler = NULL;
20static int _ecore_fb_tty_prev_mode = 0;
21static int _ecore_fb_tty_prev_kd_mode = 0;
22
23/* callbacks for an attach/release of a vt */
24static void (*_ecore_fb_func_fb_lost) (void *data) = NULL;
25static void *_ecore_fb_func_fb_lost_data = NULL;
26static void (*_ecore_fb_func_fb_gain) (void *data) = NULL;
27static void *_ecore_fb_func_fb_gain_data = NULL;
28
29/* FIXME what is the filter for? */
30static Ecore_Event_Filter *_ecore_fb_filter_handler = NULL;
31
32/* prototypes */
33/* XXX: unused
34static void _ecore_fb_vt_switch(int vt);
35static void *_ecore_fb_event_filter_start(void *data);
36static Eina_Bool _ecore_fb_event_filter_filter(void *data, void *loop_data, int type, void *event);
37static void _ecore_fb_event_filter_end(void *data, void *loop_data);
38*/
39
40static Eina_Bool
41_ecore_fb_signal_usr_handler(void *data EINA_UNUSED, int type EINA_UNUSED, void *ev)
42{
43 Ecore_Event_Signal_User *e;
44
45 e = (Ecore_Event_Signal_User *)ev;
46 if (e->number == 1)
47 {
48 /* release vt */
49 if (_ecore_fb_func_fb_lost) _ecore_fb_func_fb_lost(_ecore_fb_func_fb_lost_data);
50 /* TODO stop listening from the devices? let the callback do it? */
51 ioctl(_ecore_fb_vt_tty_fd, VT_RELDISP, 1);
52 }
53 else if (e->number == 2)
54 {
55 /* attach vt */
56 if (_ecore_fb_func_fb_gain) _ecore_fb_func_fb_gain(_ecore_fb_func_fb_gain_data);
57 /* TODO reattach all devices */
58 }
59 return 1;
60}
61
62/* XXX: unused
63static void
64_ecore_fb_vt_switch(int vt)
65{
66 vt++;
67 if (_ecore_fb_vt_tty_fd != 0)
68 {
69 if (vt != _ecore_fb_vt_current_vt)
70 {
71 tcsetattr(_ecore_fb_vt_tty_fd, TCSAFLUSH, &_ecore_fb_tty_prev_tio_mode);
72 ioctl(_ecore_fb_vt_tty_fd, KDSETMODE, _ecore_fb_tty_prev_kd_mode);
73 ioctl(_ecore_fb_vt_tty_fd, KDSKBMODE, _ecore_fb_tty_prev_mode);
74 }
75 }
76 ioctl(_ecore_fb_vt_tty_fd, VT_ACTIVATE, vt);
77}
78*/
79
80static int
81_ecore_fb_vt_setup(void)
82{
83 char buf[64];
84// XXX: unused
85// struct termios tio;
86 struct vt_mode new_vtmode;
87
88 if (_ecore_fb_vt_current_vt != _ecore_fb_vt_prev_vt)
89 {
90 snprintf(buf, sizeof(buf), "/dev/tty%i", _ecore_fb_vt_current_vt);
91 if ((_ecore_fb_vt_tty_fd = open(buf, O_RDWR)) < 0)
92 {
93 printf("[ecore_fb:vt_setup] can't open tty %d\n", _ecore_fb_vt_current_vt);
94 return 0;
95 }
96 close(_ecore_fb_vt_tty0_fd);
97 _ecore_fb_vt_tty0_fd = -1;
98 /* FIXME detach the process from current tty ? */
99 }
100 else
101 _ecore_fb_vt_tty_fd = _ecore_fb_vt_tty0_fd;
102 /* for backup */
103 tcgetattr(_ecore_fb_vt_tty_fd, &_ecore_fb_tty_prev_tio_mode);
104 ioctl(_ecore_fb_vt_tty_fd, KDGETMODE, &_ecore_fb_tty_prev_kd_mode);
105 ioctl(_ecore_fb_vt_tty_fd, VT_GETMODE, &_ecore_fb_vt_prev_mode);
106
107 if (ioctl(_ecore_fb_vt_tty_fd, KDSETMODE, KD_GRAPHICS) < 0)
108 {
109 perror("[ecore_fb:vt_setup] can't set the mode to KD_GRAPHICS");
110 close(_ecore_fb_vt_tty_fd);
111 _ecore_fb_vt_tty_fd = -1;
112 return 0;
113 }
114 ioctl(_ecore_fb_vt_tty_fd, KDGKBMODE, &_ecore_fb_tty_prev_mode);
115
116 /* support of switching */
117 new_vtmode.mode = VT_PROCESS;
118 new_vtmode.waitv = 0;
119 new_vtmode.relsig = SIGUSR1;
120 new_vtmode.acqsig = SIGUSR2;
121 if (ioctl(_ecore_fb_vt_tty_fd, VT_SETMODE, &new_vtmode) < 0)
122 {
123 perror("[ecore_fb:vt_setup] can't set the tty mode");
124 close(_ecore_fb_vt_tty_fd);
125 _ecore_fb_vt_tty_fd = -1;
126 return 0;
127 }
128 /* register signal handlers when alloc/detach of vt */
129 _ecore_fb_user_handler = ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER,
130 _ecore_fb_signal_usr_handler,
131 NULL);
132 /* What does this do? */
133 /*
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);
135 */
136
137 usleep(40000);
138 if (ioctl(_ecore_fb_vt_tty_fd, VT_ACTIVATE, _ecore_fb_vt_current_vt) < 0)
139 {
140 perror("[ecore_fb:vt_setup] error on VT_ACTIVATE");
141 close(_ecore_fb_vt_tty_fd);
142 _ecore_fb_vt_tty_fd = -1;
143 return 0;
144 }
145 if(ioctl(_ecore_fb_vt_tty_fd, VT_WAITACTIVE, _ecore_fb_vt_current_vt) < 0)
146 {
147 perror("[ecore_fb:vt_setup] error on VT_WAITACTIVE");
148 close(_ecore_fb_vt_tty_fd);
149 _ecore_fb_vt_tty_fd = -1;
150 return 0;
151 }
152 /* FIXME assign the fb to the tty in case isn't setup */
153 return 1;
154}
155
156int
157ecore_fb_vt_init(void)
158{
159 struct vt_stat vtstat;
160
161 /* as root you can allocate another tty */
162 if (!geteuid())
163 _ecore_fb_vt_do_switch = 1;
164 if ((_ecore_fb_vt_tty0_fd = open("/dev/tty0", O_RDONLY)) < 0)
165 {
166 printf("[ecore_fb:init] can't open /dev/tty0\n");
167 return 0;
168 }
169 /* query current vt state */
170 if ((ioctl(_ecore_fb_vt_tty0_fd, VT_GETSTATE, &vtstat)) < 0)
171 {
172 printf("[ecore_fb:init] can't get current tty state\n");
173 return 0;
174 }
175 _ecore_fb_vt_prev_vt = vtstat.v_active;
176 /* switch to another tty */
177 if (_ecore_fb_vt_do_switch)
178 {
179 int vtno;
180
181 if ((ioctl(_ecore_fb_vt_tty0_fd, VT_OPENQRY, &vtno) < 0))
182 {
183 printf("[ecore_fb:init] can't query for a vt\n");
184 return 0;
185 }
186 _ecore_fb_vt_current_vt = vtno;
187 }
188 /* use current tty */
189 else
190 _ecore_fb_vt_current_vt = _ecore_fb_vt_prev_vt;
191 if (!_ecore_fb_vt_setup())
192 {
193 printf("[ecore_fb:init] can't setup the vt, restoring previous mode...\n");
194 /* TODO finish this */
195 if (_ecore_fb_vt_do_switch)
196 {
197 printf("[ecore_fb:init] switching back to vt %d\n", _ecore_fb_vt_prev_vt);
198 }
199 return 0;
200 }
201 return 1;
202}
203
204void
205ecore_fb_vt_shutdown(void)
206{
207 /* restore the previous mode */
208 if (_ecore_fb_vt_tty_fd != -1)
209 {
210 tcsetattr(_ecore_fb_vt_tty_fd, TCSAFLUSH, &_ecore_fb_tty_prev_tio_mode);
211 ioctl(_ecore_fb_vt_tty_fd, KDSETMODE, _ecore_fb_tty_prev_kd_mode);
212 ioctl(_ecore_fb_vt_tty_fd, KDSKBMODE, _ecore_fb_tty_prev_mode);
213 ioctl(_ecore_fb_vt_tty_fd, VT_SETMODE, &_ecore_fb_vt_prev_mode);
214 /* go back to previous vt */
215 close(_ecore_fb_vt_tty_fd);
216 _ecore_fb_vt_tty_fd = -1;
217 }
218
219 if (_ecore_fb_user_handler) ecore_event_handler_del(_ecore_fb_user_handler);
220 _ecore_fb_user_handler = NULL;
221
222 if (_ecore_fb_filter_handler) ecore_event_filter_del(_ecore_fb_filter_handler);
223 _ecore_fb_filter_handler = NULL;
224}
225
226/**
227 * @addtogroup Ecore_FB_Group Ecore_FB - Frame buffer convenience functions.
228 *
229 * @{
230 */
231
232/**
233 * @brief Set a callback called when a virtual terminal is gained.
234 *
235 * @param func The callback called when vt is gained.
236 * @param data The data to pass to the callback.
237 *
238 * This function sets the callback @p func which will be called when a
239 * virtual terminal is gained (for example you press Ctrl-Alt-F1 to go
240 * to vt1 and your app was using vt1). @p data will be pass to @p func if
241 * the callback is called.
242 */
243EAPI void
244ecore_fb_callback_gain_set(void (*func) (void *data), void *data)
245{
246 _ecore_fb_func_fb_gain = func;
247 _ecore_fb_func_fb_gain_data = data;
248}
249
250/**
251 * @brief Set a callback called when a virtual terminal is lost.
252 *
253 * @param func The callback called when vt is lost.
254 * @param data The data to pass to the callback.
255 *
256 * This function sets the callback @p func which will be called when a
257 * virtual terminal is lost (someone wants the tv from you and you
258 * want to give up that vt). @p data will be pass to @p func if the
259 * callback is called.
260 */
261EAPI void
262ecore_fb_callback_lose_set(void (*func) (void *data), void *data)
263{
264 _ecore_fb_func_fb_lost = func;
265 _ecore_fb_func_fb_lost_data = data;
266
267}
268
269/**
270 * @}
271 */
272
273/*
274 * This filter should take into account that the MOUSE_MOVE event can be
275 * triggered by a mouse, not just a touchscreen device, so you can't discard
276 * them (only those generated by a device that sends events with absolute
277 * coordinates).
278
279typedef struct _Ecore_Fb_Filter_Data Ecore_Fb_Filter_Data;
280
281struct _Ecore_Fb_Filter_Data
282{
283 int last_event_type;
284};
285
286static void *
287_ecore_fb_event_filter_start(void *data EINA_UNUSED)
288{
289 Ecore_Fb_Filter_Data *filter_data;
290
291 filter_data = calloc(1, sizeof(Ecore_Fb_Filter_Data));
292 return filter_data;
293}
294
295static Eina_Bool
296_ecore_fb_event_filter_filter(void *data EINA_UNUSED, void *loop_data,int type, void *event EINA_UNUSED)
297{
298 Ecore_Fb_Filter_Data *filter_data;
299
300 filter_data = loop_data;
301 if (!filter_data) return EINA_TRUE;
302 if (type == ECORE_EVENT_MOUSE_MOVE)
303 {
304 if ((filter_data->last_event_type) == ECORE_EVENT_MOUSE_MOVE)
305 {
306 filter_data->last_event_type = type;
307 return EINA_FALSE;
308 }
309 }
310 filter_data->last_event_type = type;
311 return EINA_TRUE;
312}
313
314static void
315_ecore_fb_event_filter_end(void *data EINA_UNUSED, void *loop_data)
316{
317 Ecore_Fb_Filter_Data *filter_data;
318
319 filter_data = loop_data;
320 if (filter_data) free(filter_data);
321}
322*/