sh2 overclock and logging stuff, menu refactoring
[libpicofe.git] / linux / x11h.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <pthread.h>
4 #include <dlfcn.h>
5 #include <X11/Xlib.h>
6 #include <X11/Xutil.h>
7
8 #define FPTR(f) typeof(f) * p##f
9 #define FPTR_LINK(xf, dl, f) { \
10         xf.p##f = dlsym(dl, #f); \
11         if (xf.p##f == NULL) { \
12                 fprintf(stderr, "missing symbol: %s\n", #f); \
13                 goto fail; \
14         } \
15 }
16
17 struct xfuncs {
18 FPTR(XCreateBitmapFromData);
19 FPTR(XCreatePixmapCursor);
20 FPTR(XFreePixmap);
21 FPTR(XOpenDisplay);
22 FPTR(XDisplayName);
23 FPTR(XCloseDisplay);
24 FPTR(XCreateSimpleWindow);
25 FPTR(XChangeWindowAttributes);
26 FPTR(XSelectInput);
27 FPTR(XMapWindow);
28 FPTR(XNextEvent);
29 FPTR(XCheckTypedEvent);
30 FPTR(XUnmapWindow);
31 FPTR(XGrabKeyboard);
32 };
33
34
35 static Cursor transparent_cursor(struct xfuncs *xf, Display *display, Window win)
36 {
37         Cursor cursor;
38         Pixmap pix;
39         XColor dummy;
40         char d = 0;
41
42         memset(&dummy, 0, sizeof(dummy));
43         pix = xf->pXCreateBitmapFromData(display, win, &d, 1, 1);
44         cursor = xf->pXCreatePixmapCursor(display, pix, pix,
45                         &dummy, &dummy, 0, 0);
46         xf->pXFreePixmap(display, pix);
47         return cursor;
48 }
49
50 static void *x11h_handler(void *arg)
51 {
52         struct xfuncs xf;
53         unsigned int display_width, display_height;
54         XSetWindowAttributes attributes;
55         Window win;
56         XEvent report;
57         Display *display;
58         Visual *visual;
59         void *x11lib;
60         int screen;
61
62         memset(&xf, 0, sizeof(xf));
63         x11lib = dlopen("libX11.so.6", RTLD_LAZY);
64         if (x11lib == NULL) {
65                 fprintf(stderr, "libX11.so load failed:\n%s\n", dlerror());
66                 goto fail;
67         }
68         FPTR_LINK(xf, x11lib, XCreateBitmapFromData);
69         FPTR_LINK(xf, x11lib, XCreatePixmapCursor);
70         FPTR_LINK(xf, x11lib, XFreePixmap);
71         FPTR_LINK(xf, x11lib, XOpenDisplay);
72         FPTR_LINK(xf, x11lib, XDisplayName);
73         FPTR_LINK(xf, x11lib, XCloseDisplay);
74         FPTR_LINK(xf, x11lib, XCreateSimpleWindow);
75         FPTR_LINK(xf, x11lib, XChangeWindowAttributes);
76         FPTR_LINK(xf, x11lib, XSelectInput);
77         FPTR_LINK(xf, x11lib, XMapWindow);
78         FPTR_LINK(xf, x11lib, XNextEvent);
79         FPTR_LINK(xf, x11lib, XCheckTypedEvent);
80         FPTR_LINK(xf, x11lib, XUnmapWindow);
81         FPTR_LINK(xf, x11lib, XGrabKeyboard);
82
83         //XInitThreads();
84
85         display = xf.pXOpenDisplay(NULL);
86         if (display == NULL)
87         {
88                 fprintf(stderr, "cannot connect to X server %s, X handling disabled.\n",
89                                 xf.pXDisplayName(NULL));
90                 goto fail2;
91         }
92
93         visual = DefaultVisual(display, 0);
94         if (visual->class != TrueColor)
95         {
96                 fprintf(stderr, "cannot handle non true color visual\n");
97                 xf.pXCloseDisplay(display);
98                 goto fail2;
99         }
100
101         printf("x11h: X vendor: %s, rel: %d, display: %s, protocol ver: %d.%d\n", ServerVendor(display),
102                 VendorRelease(display), DisplayString(display), ProtocolVersion(display),
103                 ProtocolRevision(display));
104
105         screen = DefaultScreen(display);
106
107         display_width = DisplayWidth(display, screen);
108         display_height = DisplayHeight(display, screen);
109         printf("x11h: display is %dx%d\n", display_width, display_height);
110
111         win = xf.pXCreateSimpleWindow(display,
112                         RootWindow(display, screen),
113                         0, 0, display_width, display_height, 0,
114                         BlackPixel(display, screen),
115                         BlackPixel(display, screen));
116
117         attributes.override_redirect = True;
118         attributes.cursor = transparent_cursor(&xf, display, win);
119         xf.pXChangeWindowAttributes(display, win, CWOverrideRedirect | CWCursor, &attributes);
120
121         xf.pXSelectInput(display, win, ExposureMask | FocusChangeMask | KeyPressMask | KeyReleaseMask);
122         xf.pXMapWindow(display, win);
123         xf.pXGrabKeyboard(display, win, False, GrabModeAsync, GrabModeAsync, CurrentTime);
124         // XSetIOErrorHandler
125
126         while (1)
127         {
128                 xf.pXNextEvent(display, &report);
129                 switch (report.type)
130                 {
131                         case Expose:
132                                 while (xf.pXCheckTypedEvent(display, Expose, &report))
133                                         ;
134                                 break;
135
136                         case FocusOut:
137                                 // XFocusChangeEvent
138                                 // printf("focus out\n");
139                                 // xf.pXUnmapWindow(display, win);
140                                 break;
141
142                         case KeyPress:
143                                 // printf("press %d\n", report.xkey.keycode);
144                                 break;
145
146                         default:
147                                 break;
148                 }
149         }
150
151 fail2:
152         dlclose(x11lib);
153 fail:
154         fprintf(stderr, "x11 handling disabled.\n");
155         return NULL;
156 }
157
158 int x11h_init(void)
159 {
160         pthread_t tid;
161         int ret;
162
163         ret = pthread_create(&tid, NULL, x11h_handler, NULL);
164         if (ret != 0) {
165                 fprintf(stderr, "x11h: failed to create thread: %d\n", ret);
166                 return ret;
167         }
168         pthread_detach(tid);
169
170         return 0;
171 }
172
173 #if 0
174 int main()
175 {
176         x11h_init();
177         sleep(5);
178 }
179 #endif