summaryrefslogtreecommitdiff
path: root/src/lib/ecore_drm/ecore_drm_tty.c
diff options
context:
space:
mode:
authorChris Michael <cp.michael@samsung.com>2014-03-06 09:43:48 +0000
committerChris Michael <cp.michael@samsung.com>2014-03-06 10:57:26 +0000
commit3762e85c3967a7a7574c83bf6d550d58e58d90fc (patch)
tree48e695cf560924cf0b800f682371dfe1eb74de7e /src/lib/ecore_drm/ecore_drm_tty.c
parent0f1883df9a978d686971bba9f1450b7eb7a3fd84 (diff)
ecore-drm: Add Ecore_Drm code
@feature: Add Ecore_Drm library code for setting up drm card, outputs, virtual terminals, framebuffers, and input for use with ecore_evas drm code. Signed-off-by: Chris Michael <cp.michael@samsung.com>
Diffstat (limited to 'src/lib/ecore_drm/ecore_drm_tty.c')
-rw-r--r--src/lib/ecore_drm/ecore_drm_tty.c297
1 files changed, 297 insertions, 0 deletions
diff --git a/src/lib/ecore_drm/ecore_drm_tty.c b/src/lib/ecore_drm/ecore_drm_tty.c
new file mode 100644
index 0000000000..41a0561fb7
--- /dev/null
+++ b/src/lib/ecore_drm/ecore_drm_tty.c
@@ -0,0 +1,297 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include "ecore_drm_private.h"
6#include <sys/stat.h>
7#include <sys/ioctl.h>
8#include <linux/vt.h>
9#include <linux/kd.h>
10
11#ifndef KDSKBMUTE
12# define KDSKBMUTE 0x4B51
13#endif
14
15static Eina_Bool
16_ecore_drm_tty_cb_signal(void *data, int type EINA_UNUSED, void *event)
17{
18 Ecore_Drm_Device *dev;
19 Ecore_Event_Signal_User *ev;
20
21 dev = data;
22 ev = event;
23
24 DBG("Caught user signal: %d", ev->number);
25
26 if (ev->number == 1)
27 {
28 Ecore_Drm_Input *input;
29 Ecore_Drm_Output *output;
30 Ecore_Drm_Sprite *sprite;
31 Eina_List *l;
32
33 DBG("Release VT");
34
35 /* disable inputs (suspends) */
36 EINA_LIST_FOREACH(dev->inputs, l, input)
37 ecore_drm_inputs_disable(input);
38
39 /* disable hardware cursor */
40 EINA_LIST_FOREACH(dev->outputs, l, output)
41 ecore_drm_output_cursor_size_set(output, 0, 0, 0);
42
43 /* disable sprites */
44 EINA_LIST_FOREACH(dev->sprites, l, sprite)
45 ecore_drm_sprites_fb_set(sprite, 0, 0);
46
47 /* close input fds ?? */
48
49 /* drop drm master */
50 if (ecore_drm_device_master_drop(dev))
51 {
52 /* issue ioctl to release vt */
53 if (!ecore_drm_tty_release(dev))
54 ERR("Could not release VT: %m");
55 }
56 else
57 ERR("Could not drop drm master: %m");
58 }
59 else if (ev->number == 2)
60 {
61 Ecore_Drm_Output *output;
62 Ecore_Drm_Input *input;
63 Eina_List *l;
64
65 DBG("Acquire VT");
66
67 /* issue ioctl to acquire vt */
68 if (ecore_drm_tty_acquire(dev))
69 {
70 /* set drm master */
71 if (!ecore_drm_device_master_set(dev))
72 ERR("Could not set drm master: %m");
73
74 /* set output mode */
75 EINA_LIST_FOREACH(dev->outputs, l, output)
76 ecore_drm_output_enable(output);
77
78 /* enable inputs */
79 EINA_LIST_FOREACH(dev->inputs, l, input)
80 ecore_drm_inputs_enable(input);
81 }
82 else
83 ERR("Could not acquire VT: %m");
84 }
85
86 return EINA_TRUE;
87}
88
89static Eina_Bool
90_ecore_drm_tty_setup(Ecore_Drm_Device *dev)
91{
92 struct stat st;
93 int kb_mode;
94 struct vt_mode vtmode = { 0 };
95
96 if (fstat(dev->tty.fd, &st) == -1)
97 {
98 ERR("Failed to get stats for tty: %m");
99 return EINA_FALSE;
100 }
101
102 if (ioctl(dev->tty.fd, KDGKBMODE, &kb_mode))
103 {
104 ERR("Could not get tty keyboard mode: %m");
105 return EINA_FALSE;
106 }
107
108 /* NB: Don't set this. This Turns OFF keyboard on the VT */
109 /* if (ioctl(dev->tty.fd, KDSKBMUTE, 1) && */
110 /* ioctl(dev->tty.fd, KDSKBMODE, K_OFF)) */
111 /* { */
112 /* ERR("Could not set K_OFF keyboard mode: %m"); */
113 /* return EINA_FALSE; */
114 /* } */
115
116 /* if (ioctl(dev->tty.fd, KDSETMODE, KD_GRAPHICS)) */
117 /* { */
118 /* ERR("Could not set graphics mode: %m"); */
119 /* return EINA_FALSE; */
120 /* } */
121
122 vtmode.mode = VT_PROCESS;
123 vtmode.waitv = 0;
124 vtmode.relsig = SIGUSR1;
125 vtmode.acqsig = SIGUSR2;
126 if (ioctl(dev->tty.fd, VT_SETMODE, &vtmode) < 0)
127 {
128 ERR("Could not set Terminal Mode: %m");
129 return EINA_FALSE;
130 }
131
132 /* if (ioctl(dev->tty.fd, VT_ACTIVATE, minor(st.st_rdev)) < 0) */
133 /* { */
134 /* ERR("Failed to activate vt: %m"); */
135 /* return EINA_FALSE; */
136 /* } */
137
138 /* if (ioctl(dev->tty.fd, VT_WAITACTIVE, minor(st.st_rdev)) < 0) */
139 /* { */
140 /* ERR("Failed to wait active: %m"); */
141 /* return EINA_FALSE; */
142 /* } */
143
144 return EINA_TRUE;
145}
146
147/**
148 * @defgroup Ecore_Drm_Tty_Group Tty manipulation functions
149 *
150 * Functions that deal with opening, closing, and otherwise using a tty
151 */
152
153/**
154 * Open a tty for use
155 *
156 * @param dev The Ecore_Drm_Device that this tty will belong to.
157 * @param name The name of the tty to try and open.
158 * If NULL, /dev/tty0 will be used.
159 *
160 * @return EINA_TRUE on success, EINA_FALSE on failure
161 *
162 * @ingroup Ecore_Drm_Tty_Group
163 */
164EAPI Eina_Bool
165ecore_drm_tty_open(Ecore_Drm_Device *dev, const char *name)
166{
167 char tty[32] = "<stdin>";
168
169 /* check for valid device */
170 if ((!dev) || (!dev->drm.name)) return EINA_FALSE;
171
172 /* assign default tty fd of -1 */
173 dev->tty.fd = -1;
174
175 if (!name)
176 {
177 char *env;
178
179 if ((env = getenv("ECORE_DRM_TTY")))
180 snprintf(tty, sizeof(tty), "%s", env);
181 else
182 dev->tty.fd = STDIN_FILENO;
183 }
184 else // FIXME: NB: This should Really check for format of name (/dev/xyz)
185 snprintf(tty, sizeof(tty), "%s", name);
186
187 if (dev->tty.fd < 0)
188 {
189 DBG("Trying to Open Tty: %s", tty);
190
191 dev->tty.fd = open(tty, O_RDWR | O_NOCTTY);
192 if (dev->tty.fd < 0)
193 {
194 DBG("Failed to Open Tty: %m");
195 return EINA_FALSE;
196 }
197 }
198
199 if (dev->tty.fd < 0)
200 {
201 DBG("Failed to open tty %s", tty);
202 return EINA_FALSE;
203 }
204
205 DBG("Opened Tty %s : %d", tty, dev->tty.fd);
206
207 /* save tty name */
208 dev->tty.name = eina_stringshare_add(tty);
209
210 /* FIXME */
211 if (!_ecore_drm_tty_setup(dev))
212 return EINA_FALSE;
213
214 /* setup handler for signals */
215 dev->tty.event_hdlr =
216 ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER,
217 _ecore_drm_tty_cb_signal, dev);
218
219 /* set current tty into env */
220 setenv("ECORE_DRM_TTY", tty, 1);
221
222 return EINA_TRUE;
223}
224
225/**
226 * Close an already opened tty
227 *
228 * @param dev The Ecore_Drm_Device which owns this tty.
229 *
230 * @return EINA_TRUE on success, EINA_FALSE on failure
231 *
232 * @ingroup Ecore_Drm_Tty_Group
233 */
234EAPI Eina_Bool
235ecore_drm_tty_close(Ecore_Drm_Device *dev)
236{
237 /* check for valid device */
238 if ((!dev) || (!dev->drm.name)) return EINA_FALSE;
239
240 close(dev->tty.fd);
241
242 dev->tty.fd = -1;
243
244 /* destroy the event handler */
245 if (dev->tty.event_hdlr) ecore_event_handler_del(dev->tty.event_hdlr);
246 dev->tty.event_hdlr = NULL;
247
248 /* clear the tty name */
249 if (dev->tty.name) eina_stringshare_del(dev->tty.name);
250 dev->tty.name = NULL;
251
252 unsetenv("ECORE_DRM_TTY");
253
254 return EINA_TRUE;
255}
256
257/**
258 * Release a virtual terminal
259 *
260 * @param dev The Ecore_Drm_Device which owns this tty.
261 *
262 * @return EINA_TRUE on success, EINA_FALSE on failure
263 *
264 * @ingroup Ecore_Drm_Tty_Group
265 */
266EAPI Eina_Bool
267ecore_drm_tty_release(Ecore_Drm_Device *dev)
268{
269 /* check for valid device */
270 if ((!dev) || (!dev->drm.name) || (dev->tty.fd < 0)) return EINA_FALSE;
271
272 /* send ioctl for vt release */
273 if (ioctl(dev->tty.fd, VT_RELDISP, 1) < 0) return EINA_FALSE;
274
275 return EINA_TRUE;
276}
277
278/**
279 * Acquire a virtual terminal
280 *
281 * @param dev The Ecore_Drm_Device which owns this tty.
282 *
283 * @return EINA_TRUE on success, EINA_FALSE on failure
284 *
285 * @ingroup Ecore_Drm_Tty_Group
286 */
287EAPI Eina_Bool
288ecore_drm_tty_acquire(Ecore_Drm_Device *dev)
289{
290 /* check for valid device */
291 if ((!dev) || (!dev->drm.name) || (dev->tty.fd < 0)) return EINA_FALSE;
292
293 /* send ioctl for vt acquire */
294 if (ioctl(dev->tty.fd, VT_RELDISP, VT_ACKACQ) < 0) return EINA_FALSE;
295
296 return EINA_TRUE;
297}