2 /* -------------------------------------------------------------------------- */
4 static fd_set rd_fd_set;
5 static fd_set wr_fd_set;
6 static fd_set ex_fd_set;
8 /* -------------------------------------------------------------------------- */
10 static void signal_terminate(int);
11 static void signal_alarm(int);
12 static void signal_other(int);
13 static void set_timeval_ms(struct timeval* t, int ms);
15 /* -------------------------------------------------------------------------- */
17 static Window x11Window = 0;
18 static Display* x11Display = 0;
19 static long x11Screen = 0;
20 static XVisualInfo* x11Visual = 0;
21 static Colormap x11Colormap = 0;
23 static EGLNativeDisplayType eglX11Display = 0;
24 static EGLNativeWindowType eglX11Window = 0;
25 static EGLDisplay eglDisplay = 0;
26 static EGLConfig eglConfig = 0;
27 static EGLSurface eglSurface = 0;
28 static EGLContext eglContext = 0;
30 /* -------------------------------------------------------------------------- */
32 static int create_gl_window();
33 static int getX11Display(int windowwidth, int windowheight);
34 static int setUpEGL();
35 static void checkX11Events();
37 /* -------------------------------------------------------------------------- */
39 void init_thread(void)
41 signal(SIGTERM, signal_terminate);
42 signal(SIGINT, signal_terminate);
43 signal(SIGQUIT, signal_terminate);
44 signal(SIGALRM, signal_alarm);
45 signal(SIGPIPE, signal_other);
46 signal(SIGCHLD, SIG_IGN);
47 signal(SIGHUP, SIG_IGN);
48 signal(SIGUSR1, SIG_IGN);
49 signal(SIGUSR2, SIG_IGN);
64 /* -------------------------------------------------------------------------- */
66 OTHER_THREAD void signal_terminate(int signum)
71 OTHER_THREAD void signal_alarm(int signum)
76 OTHER_THREAD void signal_other(int signum)
81 /* -------------------------------------------------------------------------- */
83 void set_callback(k_channel* chan, int rdwr)
85 if(rdwr & SETCB_RD) FD_SET(chan->priv->SOCK, &rd_fd_set);
86 if(rdwr & SETCB_WR) FD_SET(chan->priv->SOCK, &wr_fd_set);
89 void un_set_callback(k_channel* chan, int rdwr)
91 if(rdwr & SETCB_RD) FD_CLR(chan->priv->SOCK, &rd_fd_set);
92 if(rdwr & SETCB_WR) FD_CLR(chan->priv->SOCK, &wr_fd_set);
95 void poller(int no_block)
104 for(chan=k_channels; chan; chan=chan->next){
105 if(chan->priv->state==CHAN_CLOSE) continue;
106 if(highest < chan->priv->SOCK) highest=chan->priv->SOCK;
110 struct timeval* tp=&t;
111 set_timeval_ms(tp, no_block? 0: LOOP_TICK);
114 select(0, 0, 0, 0, tp);
116 if(!no_block) do_regular_things();
120 int len=select(highest+1, &rd, &wr, &ex, tp);
131 if(ERRNO==INTERRUPTED) return;
132 log_net_err("select", ERRNO);
138 for(chan=k_channels; chan; chan=chan->next){
139 if(FD_ISSET(chan->priv->SOCK, &ex)){
140 exception_socket(chan);
143 if(FD_ISSET(chan->priv->SOCK, &wr)){
144 int err; socklen_t len=sizeof(int);
145 if(getsockopt(chan->priv->SOCK,
147 SO_ERROR, &err, &len) || err){
148 exception_socket(chan);
152 writeable_socket(chan);
155 if(FD_ISSET(chan->priv->SOCK, &rd)){
156 readable_socket(chan);
161 void set_timeval_ms(struct timeval* t, int ms)
164 t->tv_usec=(ms-(t->tv_sec)*1000)*1000;
167 char* str_error(int e)
172 /* -------------------------------------------------------------------------- */
174 void stat_only(char* fullname, k_stat* kstat)
178 if(stat(fullname, &s)) return;
179 kstat->type=s.st_mode & 0170000;
180 kstat->size=s.st_size;
181 kstat->time=s.st_mtime;
182 kstat->perm=s.st_mode & 0007777;
185 FILE_T stat_open(char* fullname, k_stat* kstat)
187 stat_only(fullname, kstat);
188 if(!kstat->type) return 0;
189 FILE_T filehandle=open(fullname, O_RDONLY);
190 if(filehandle<0) return 0;
194 FILE_T open_only(char* fullname, int wr)
196 int rw=wr? O_RDWR|O_CREAT|O_TRUNC: O_RDONLY;
197 FILE_T filehandle=open(fullname, rw, 0644);
198 if(filehandle<0) return 0;
202 void* mmap_malloc(void* s, size_t size, int prot, int f, char* fullname, int o)
204 FILE_T fh=open(fullname, O_RDONLY, 0644);
205 if(fh<0) return MAP_FAILED;
207 char* data=k_malloc(size);
211 len=read(fh, data+charsread, size-charsread);
212 if(len< 0 && FERRNO(len)==EINTR) continue;
215 } while(charsread<size);
218 if(len<0 || charsread!=size){ k_free(data); return MAP_FAILED; }
222 void* mmap_name(void* s, size_t size, int prot, int f, char* fullname, int o)
224 if(!size) return MAP_FAILED;
225 int w=(prot & PROT_WRITE);
226 FILE_T fh=open(fullname, (w? O_RDWR|O_CREAT: O_RDONLY), 0644);
227 if(fh<0) return MAP_FAILED;
228 return mmap(s, size, prot, f, fh, o);
231 /* -------------------------------------------------------------------------- */
233 EXPORT void k_random_bytes(char* buf, size_t size)
235 *(short*)buf=getpid();
236 if(size!=2) k_log_err("Linux randomness not implemented yet!");
239 /* -------------------------------------------------------------------------- */
241 EXPORT void* k_malloc(size_t size)
243 void* p=malloc(size);
250 EXPORT void* k_realloc(void* o, size_t size)
252 void* p=realloc(o, size);
259 EXPORT void k_free(void* o)
264 EXPORT char* k_strdup(char* s)
274 EXPORT void* k_memdup(void* s, size_t size)
276 void* p=malloc(size);
284 /* ------------------------------------------------------------- */
286 #define WINDOW_WIDTH 640
287 #define WINDOW_HEIGHT 480
289 int create_gl_window()
291 if(!getX11Display(WINDOW_WIDTH, WINDOW_HEIGHT)) return 0;
292 if(!setUpEGL()) return 0;
296 /* ------------------------------------------------------------- */
298 int getX11Display(int windowwidth, int windowheight)
300 x11Display = XOpenDisplay(0);
303 printf("Error: Unable to open X display\n");
307 x11Screen = XDefaultScreen(x11Display);
308 Window rootWindow = RootWindow(x11Display, x11Screen);
309 int depth = DefaultDepth(x11Display, x11Screen);
310 x11Visual = malloc(sizeof(XVisualInfo));
311 XMatchVisualInfo(x11Display, x11Screen, depth, TrueColor, x11Visual);
314 printf("Error: Unable to acquire visual\n");
318 x11Colormap = XCreateColormap(x11Display, rootWindow, x11Visual->visual, AllocNone);
319 XSetWindowAttributes XSWA;
320 XSWA.colormap = x11Colormap;
321 XSWA.event_mask = StructureNotifyMask | ExposureMask |
322 ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask;
323 unsigned int cwmask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;
325 x11Window = XCreateWindow(x11Display, RootWindow(x11Display, x11Screen), 0, 0, windowwidth, windowheight,
326 0, CopyFromParent, InputOutput, CopyFromParent, cwmask, &XSWA);
327 XMapWindow(x11Display, x11Window);
330 eglX11Display = (EGLNativeDisplayType)x11Display;
331 eglX11Window = (EGLNativeWindowType) x11Window;
338 if(x11Window) XDestroyWindow(x11Display, x11Window);
339 if(x11Colormap) XFreeColormap( x11Display, x11Colormap);
340 if(x11Display) XCloseDisplay( x11Display);
343 void checkX11Events()
345 int nm = XPending(x11Display);
347 for(m=0; m< nm; m++) {
349 XNextEvent(x11Display, &event);
354 c_key((unsigned char)event.xkey.keycode, 1);
362 /* -------------------------------------------------------------------------- */
364 int isEGLError(char* where)
366 EGLint err = eglGetError();
367 if(err != EGL_SUCCESS) {
368 printf("EGL failed at %s (%d).\n", where, err);
376 eglDisplay = eglGetDisplay(eglX11Display);
378 EGLint iMajorVersion, iMinorVersion;
379 if(!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion)) {
380 printf("Error: eglInitialize() failed.\n");
384 EGLint pi32ConfigAttribs[5];
385 pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
386 pi32ConfigAttribs[1] = EGL_WINDOW_BIT;
387 pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE;
388 pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT;
389 pi32ConfigAttribs[4] = EGL_NONE;
391 EGLint pi32ContextAttribs[3];
392 pi32ContextAttribs[0] = EGL_CONTEXT_CLIENT_VERSION;
393 pi32ContextAttribs[1] = 2;
394 pi32ContextAttribs[2] = EGL_NONE;
397 if(!eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs) || (iConfigs != 1)) {
398 printf("Error: eglChooseConfig() failed.\n");
402 eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, eglX11Window, NULL);
403 if(isEGLError("eglCreateWindowSurface")) return 0;
405 eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, pi32ContextAttribs);
406 if(isEGLError("eglCreateContext")) return 0;
408 eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
409 if(isEGLError("eglMakeCurrent")) return 0;
414 /* -------------------------------------------------------------------------- */
416 EXPORT void k_gl_swap_buffers(void)
418 eglSwapBuffers(eglDisplay, eglSurface);
421 EXPORT void k_gl_end(void)
423 eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
424 eglTerminate(eglDisplay);
427 /* -------------------------------------------------------------------------- */