map remaining fn keys to something
[sdl_omap.git] / src / video / omapdss / linux / oshide.c
1 /*
2  * (C) GraÅžvydas "notaz" Ignotas, 2009-2010
3  *
4  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
5  * See the COPYING file in the top-level directory.
6  */
7
8 #include <stdio.h>
9 #include <string.h>
10 #include <pthread.h>
11
12 #include <dlfcn.h>
13 #include <X11/Xlib.h>
14 #include <X11/Xutil.h>
15
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <fcntl.h>
19 #include <unistd.h>
20 #include <sys/ioctl.h>
21 #include <termios.h>
22 #include <linux/kd.h>
23
24 #define PFX "oshide: "
25
26 #define FPTR(f) typeof(f) * p##f
27 #define FPTR_LINK(xf, dl, f) { \
28         xf.p##f = dlsym(dl, #f); \
29         if (xf.p##f == NULL) { \
30                 fprintf(stderr, "missing symbol: %s\n", #f); \
31                 goto fail; \
32         } \
33 }
34
35 struct xfuncs {
36 FPTR(XCreateBitmapFromData);
37 FPTR(XCreatePixmapCursor);
38 FPTR(XFreePixmap);
39 FPTR(XOpenDisplay);
40 FPTR(XDisplayName);
41 FPTR(XCloseDisplay);
42 FPTR(XCreateSimpleWindow);
43 FPTR(XChangeWindowAttributes);
44 FPTR(XSelectInput);
45 FPTR(XMapWindow);
46 FPTR(XNextEvent);
47 FPTR(XCheckTypedEvent);
48 FPTR(XUnmapWindow);
49 FPTR(XGrabKeyboard);
50 };
51
52
53 static Cursor transparent_cursor(struct xfuncs *xf, Display *display, Window win)
54 {
55         Cursor cursor;
56         Pixmap pix;
57         XColor dummy;
58         char d = 0;
59
60         memset(&dummy, 0, sizeof(dummy));
61         pix = xf->pXCreateBitmapFromData(display, win, &d, 1, 1);
62         cursor = xf->pXCreatePixmapCursor(display, pix, pix,
63                         &dummy, &dummy, 0, 0);
64         xf->pXFreePixmap(display, pix);
65         return cursor;
66 }
67
68 static void *x11h_handler(void *arg)
69 {
70         struct xfuncs xf;
71         unsigned int display_width, display_height;
72         XSetWindowAttributes attributes;
73         Window win;
74         XEvent report;
75         Display *display;
76         Visual *visual;
77         void *x11lib;
78         int screen;
79
80         memset(&xf, 0, sizeof(xf));
81         x11lib = dlopen("libX11.so.6", RTLD_LAZY);
82         if (x11lib == NULL) {
83                 fprintf(stderr, "libX11.so load failed:\n%s\n", dlerror());
84                 goto fail;
85         }
86         FPTR_LINK(xf, x11lib, XCreateBitmapFromData);
87         FPTR_LINK(xf, x11lib, XCreatePixmapCursor);
88         FPTR_LINK(xf, x11lib, XFreePixmap);
89         FPTR_LINK(xf, x11lib, XOpenDisplay);
90         FPTR_LINK(xf, x11lib, XDisplayName);
91         FPTR_LINK(xf, x11lib, XCloseDisplay);
92         FPTR_LINK(xf, x11lib, XCreateSimpleWindow);
93         FPTR_LINK(xf, x11lib, XChangeWindowAttributes);
94         FPTR_LINK(xf, x11lib, XSelectInput);
95         FPTR_LINK(xf, x11lib, XMapWindow);
96         FPTR_LINK(xf, x11lib, XNextEvent);
97         FPTR_LINK(xf, x11lib, XCheckTypedEvent);
98         FPTR_LINK(xf, x11lib, XUnmapWindow);
99         FPTR_LINK(xf, x11lib, XGrabKeyboard);
100
101         //XInitThreads();
102
103         display = xf.pXOpenDisplay(NULL);
104         if (display == NULL)
105         {
106                 fprintf(stderr, "cannot connect to X server %s, X handling disabled.\n",
107                                 xf.pXDisplayName(NULL));
108                 goto fail2;
109         }
110
111         visual = DefaultVisual(display, 0);
112         if (visual->class != TrueColor)
113                 fprintf(stderr, PFX "warning: non true color visual\n");
114
115         printf(PFX "X vendor: %s, rel: %d, display: %s, protocol ver: %d.%d\n", ServerVendor(display),
116                 VendorRelease(display), DisplayString(display), ProtocolVersion(display),
117                 ProtocolRevision(display));
118
119         screen = DefaultScreen(display);
120
121         display_width = DisplayWidth(display, screen);
122         display_height = DisplayHeight(display, screen);
123         printf(PFX "display is %dx%d\n", display_width, display_height);
124
125         win = xf.pXCreateSimpleWindow(display,
126                         RootWindow(display, screen),
127                         0, 0, display_width, display_height, 0,
128                         BlackPixel(display, screen),
129                         BlackPixel(display, screen));
130
131         attributes.override_redirect = True;
132         attributes.cursor = transparent_cursor(&xf, display, win);
133         xf.pXChangeWindowAttributes(display, win, CWOverrideRedirect | CWCursor, &attributes);
134
135         xf.pXSelectInput(display, win, ExposureMask | FocusChangeMask | KeyPressMask | KeyReleaseMask);
136         xf.pXMapWindow(display, win);
137         xf.pXGrabKeyboard(display, win, False, GrabModeAsync, GrabModeAsync, CurrentTime);
138         // XSetIOErrorHandler
139
140         while (1)
141         {
142                 xf.pXNextEvent(display, &report);
143                 switch (report.type)
144                 {
145                         case Expose:
146                                 while (xf.pXCheckTypedEvent(display, Expose, &report))
147                                         ;
148                                 break;
149
150                         case FocusOut:
151                                 // XFocusChangeEvent
152                                 // printf("focus out\n");
153                                 // xf.pXUnmapWindow(display, win);
154                                 break;
155
156                         case KeyPress:
157                                 // printf("press %d\n", report.xkey.keycode);
158                                 break;
159
160                         default:
161                                 break;
162                 }
163         }
164
165 fail2:
166         dlclose(x11lib);
167 fail:
168         fprintf(stderr, "x11 handling disabled.\n");
169         return NULL;
170 }
171
172 static struct termios g_kbd_termios_saved;
173 static int g_kbdfd;
174
175 static void hidecon_start(void)
176 {
177         struct termios kbd_termios;
178         int mode;
179
180         g_kbdfd = open("/dev/tty", O_RDWR);
181         if (g_kbdfd == -1) {
182                 perror(PFX "open /dev/tty");
183                 return;
184         }
185
186         if (ioctl(g_kbdfd, KDGETMODE, &mode) == -1) {
187                 perror(PFX "(not hiding FB): KDGETMODE");
188                 goto fail;
189         }
190
191         if (tcgetattr(g_kbdfd, &kbd_termios) == -1) {
192                 perror(PFX "tcgetattr");
193                 goto fail;
194         }
195
196         g_kbd_termios_saved = kbd_termios;
197         kbd_termios.c_lflag &= ~(ICANON | ECHO); // | ISIG);
198         kbd_termios.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON);
199         kbd_termios.c_cc[VMIN] = 0;
200         kbd_termios.c_cc[VTIME] = 0;
201
202         if (tcsetattr(g_kbdfd, TCSAFLUSH, &kbd_termios) == -1) {
203                 perror(PFX "tcsetattr");
204                 goto fail;
205         }
206
207         if (ioctl(g_kbdfd, KDSETMODE, KD_GRAPHICS) == -1) {
208                 perror(PFX "KDSETMODE KD_GRAPHICS");
209                 tcsetattr(g_kbdfd, TCSAFLUSH, &g_kbd_termios_saved);
210                 goto fail;
211         }
212
213         return;
214
215 fail:
216         close(g_kbdfd);
217         g_kbdfd = -1;
218 }
219
220 static void hidecon_end(void)
221 {
222         if (g_kbdfd < 0)
223                 return;
224
225         if (ioctl(g_kbdfd, KDSETMODE, KD_TEXT) == -1)
226                 perror(PFX "KDSETMODE KD_TEXT");
227
228         if (tcsetattr(g_kbdfd, TCSAFLUSH, &g_kbd_termios_saved) == -1)
229                 perror(PFX "tcsetattr");
230
231         close(g_kbdfd);
232         g_kbdfd = -1;
233 }
234
235 int oshide_init(void)
236 {
237         pthread_t tid;
238         int ret;
239
240         ret = pthread_create(&tid, NULL, x11h_handler, NULL);
241         if (ret != 0) {
242                 fprintf(stderr, PFX "failed to create thread: %d\n", ret);
243                 return ret;
244         }
245         pthread_detach(tid);
246
247         hidecon_start();
248
249         return 0;
250 }
251
252 void oshide_finish(void)
253 {
254         /* XXX: the X thread.. */
255
256         hidecon_end();
257 }
258
259 #if 0
260 int main()
261 {
262         x11h_init();
263         sleep(5);
264 }
265 #endif