2 /* -------------------------------------------------------------------------- */
14 /* -------------------------------------------------------------------------- */
16 static fd_set rd_fd_set;
17 static fd_set wr_fd_set;
18 static fd_set ex_fd_set;
20 /* -------------------------------------------------------------------------- */
22 static void signal_terminate(int);
23 static void signal_alarm(int);
24 static void signal_other(int);
25 static void set_timeval_ms(struct timeval* t, int ms);
27 /* -------------------------------------------------------------------------- */
29 static Window x11Window = 0;
30 static Display* x11Display = 0;
31 static long x11Screen = 0;
32 static XVisualInfo* x11Visual = 0;
33 static Colormap x11Colormap = 0;
35 static EGLNativeDisplayType eglX11Display = 0;
36 static EGLNativeWindowType eglX11Window = 0;
37 static EGLDisplay eglDisplay = 0;
38 static EGLConfig eglConfig = 0;
39 static EGLSurface eglSurface = 0;
40 static EGLContext eglContext = 0;
42 /* -------------------------------------------------------------------------- */
44 static int create_gl_window();
45 static int getX11Display(int windowwidth, int windowheight);
46 static int setUpEGL();
47 static void checkX11Events();
49 /* -------------------------------------------------------------------------- */
51 void init_thread(void)
53 signal(SIGTERM, signal_terminate);
54 signal(SIGINT, signal_terminate);
55 signal(SIGQUIT, signal_terminate);
56 signal(SIGALRM, signal_alarm);
57 signal(SIGPIPE, signal_other);
58 signal(SIGCHLD, SIG_IGN);
59 signal(SIGHUP, SIG_IGN);
60 signal(SIGUSR1, SIG_IGN);
61 signal(SIGUSR2, SIG_IGN);
76 /* -------------------------------------------------------------------------- */
78 OTHER_THREAD void signal_terminate(int signum)
83 OTHER_THREAD void signal_alarm(int signum)
88 OTHER_THREAD void signal_other(int signum)
93 /* -------------------------------------------------------------------------- */
95 void set_callback(k_channel* chan, int rdwr)
97 if(rdwr & SETCB_RD) FD_SET(chan->priv->SOCK, &rd_fd_set);
98 if(rdwr & SETCB_WR) FD_SET(chan->priv->SOCK, &wr_fd_set);
101 void un_set_callback(k_channel* chan, int rdwr)
103 if(rdwr & SETCB_RD) FD_CLR(chan->priv->SOCK, &rd_fd_set);
104 if(rdwr & SETCB_WR) FD_CLR(chan->priv->SOCK, &wr_fd_set);
107 void poller(int no_block)
116 for(chan=k_channels; chan; chan=chan->next){
117 if(chan->priv->state==CHAN_CLOSE) continue;
118 if(highest < chan->priv->SOCK) highest=chan->priv->SOCK;
122 struct timeval* tp=&t;
123 set_timeval_ms(tp, no_block? 0: LOOP_TICK);
126 select(0, 0, 0, 0, tp);
128 if(!no_block) do_regular_things();
132 int len=select(highest+1, &rd, &wr, &ex, tp);
143 if(ERRNO==INTERRUPTED) return;
144 log_net_err("select", ERRNO);
150 for(chan=k_channels; chan; chan=chan->next){
151 if(FD_ISSET(chan->priv->SOCK, &ex)){
152 exception_socket(chan);
155 if(FD_ISSET(chan->priv->SOCK, &wr)){
156 int err; socklen_t len=sizeof(int);
157 if(getsockopt(chan->priv->SOCK,
159 SO_ERROR, &err, &len) || err){
160 exception_socket(chan);
164 writeable_socket(chan);
167 if(FD_ISSET(chan->priv->SOCK, &rd)){
168 readable_socket(chan);
173 void set_timeval_ms(struct timeval* t, int ms)
176 t->tv_usec=(ms-(t->tv_sec)*1000)*1000;
179 char* str_error(int e)
184 /* -------------------------------------------------------------------------- */
186 void stat_only(char* fullname, k_stat* kstat)
190 if(stat(fullname, &s)) return;
191 kstat->type=s.st_mode & 0170000;
192 kstat->size=s.st_size;
193 kstat->time=s.st_mtime;
194 kstat->perm=s.st_mode & 0007777;
197 FILE_T stat_open(char* fullname, k_stat* kstat)
199 stat_only(fullname, kstat);
200 if(!kstat->type) return 0;
201 FILE_T filehandle=open(fullname, O_RDONLY);
202 if(filehandle<0) return 0;
206 FILE_T open_only(char* fullname, int wr)
208 int rw=wr? O_RDWR|O_CREAT|O_TRUNC: O_RDONLY;
209 FILE_T filehandle=open(fullname, rw, 0644);
210 if(filehandle<0) return 0;
214 void* mmap_malloc(void* s, size_t size, int prot, int f, char* fullname, int o)
216 FILE_T fh=open(fullname, O_RDONLY, 0644);
217 if(fh<0) return MAP_FAILED;
219 char* data=k_malloc(size);
223 len=read(fh, data+charsread, size-charsread);
224 if(len< 0 && FERRNO(len)==EINTR) continue;
227 } while(charsread<size);
230 if(len<0 || charsread!=size){ k_free(data); return MAP_FAILED; }
234 void* mmap_name(void* s, size_t size, int prot, int f, char* fullname, int o)
236 if(!size) return MAP_FAILED;
237 int w=(prot & PROT_WRITE);
238 FILE_T fh=open(fullname, (w? O_RDWR|O_CREAT: O_RDONLY), 0644);
239 if(fh<0) return MAP_FAILED;
240 return mmap(s, size, prot, f, fh, o);
243 /* -------------------------------------------------------------------------- */
245 EXPORT void k_random_bytes(char* buf, size_t size)
247 *(short*)buf=getpid();
248 if(size!=2) k_log_err("Linux randomness not implemented yet!");
251 /* -------------------------------------------------------------------------- */
253 EXPORT void* k_malloc(size_t size)
255 void* p=malloc(size);
262 EXPORT void* k_realloc(void* o, size_t size)
264 void* p=realloc(o, size);
271 EXPORT void k_free(void* o)
276 EXPORT char* k_strdup(char* s)
286 EXPORT void* k_memdup(void* s, size_t size)
288 void* p=malloc(size);
296 /* ------------------------------------------------------------- */
298 #define WINDOW_WIDTH 640
299 #define WINDOW_HEIGHT 480
301 int create_gl_window()
303 if(!getX11Display(WINDOW_WIDTH, WINDOW_HEIGHT)) return 0;
304 if(!setUpEGL()) return 0;
308 /* ------------------------------------------------------------- */
310 int getX11Display(int windowwidth, int windowheight)
312 x11Display = XOpenDisplay(0);
315 printf("Error: Unable to open X display\n");
319 x11Screen = XDefaultScreen(x11Display);
320 Window rootWindow = RootWindow(x11Display, x11Screen);
321 int depth = DefaultDepth(x11Display, x11Screen);
322 x11Visual = malloc(sizeof(XVisualInfo));
323 XMatchVisualInfo(x11Display, x11Screen, depth, TrueColor, x11Visual);
326 printf("Error: Unable to acquire visual\n");
330 x11Colormap = XCreateColormap(x11Display, rootWindow, x11Visual->visual, AllocNone);
331 XSetWindowAttributes XSWA;
332 XSWA.colormap = x11Colormap;
333 XSWA.event_mask = StructureNotifyMask | ExposureMask |
334 ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask;
335 unsigned int cwmask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;
337 x11Window = XCreateWindow(x11Display, RootWindow(x11Display, x11Screen), 0, 0, windowwidth, windowheight,
338 0, CopyFromParent, InputOutput, CopyFromParent, cwmask, &XSWA);
339 XMapWindow(x11Display, x11Window);
342 eglX11Display = (EGLNativeDisplayType)x11Display;
343 eglX11Window = (EGLNativeWindowType) x11Window;
350 if(x11Window) XDestroyWindow(x11Display, x11Window);
351 if(x11Colormap) XFreeColormap( x11Display, x11Colormap);
352 if(x11Display) XCloseDisplay( x11Display);
355 void checkX11Events()
357 int nm = XPending(x11Display);
359 for(m=0; m< nm; m++) {
361 XNextEvent(x11Display, &event);
366 c_key((unsigned char)event.xkey.keycode, 1);
374 /* -------------------------------------------------------------------------- */
376 int isEGLError(char* where)
378 EGLint err = eglGetError();
379 if(err != EGL_SUCCESS) {
380 printf("EGL failed at %s (%d).\n", where, err);
388 eglDisplay = eglGetDisplay(eglX11Display);
390 EGLint iMajorVersion, iMinorVersion;
391 if(!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion)) {
392 printf("Error: eglInitialize() failed.\n");
396 EGLint pi32ConfigAttribs[5];
397 pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
398 pi32ConfigAttribs[1] = EGL_WINDOW_BIT;
399 pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE;
400 pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT;
401 pi32ConfigAttribs[4] = EGL_NONE;
403 EGLint pi32ContextAttribs[3];
404 pi32ContextAttribs[0] = EGL_CONTEXT_CLIENT_VERSION;
405 pi32ContextAttribs[1] = 2;
406 pi32ContextAttribs[2] = EGL_NONE;
409 if(!eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs) || (iConfigs != 1)) {
410 printf("Error: eglChooseConfig() failed.\n");
414 eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, eglX11Window, NULL);
415 if(isEGLError("eglCreateWindowSurface")) return 0;
417 eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, pi32ContextAttribs);
418 if(isEGLError("eglCreateContext")) return 0;
420 eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
421 if(isEGLError("eglMakeCurrent")) return 0;
426 /* -------------------------------------------------------------------------- */
428 EXPORT void k_gl_swap_buffers(void)
430 eglSwapBuffers(eglDisplay, eglSurface);
433 EXPORT void k_gl_end(void)
435 eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
436 eglTerminate(eglDisplay);
439 /* -------------------------------------------------------------------------- */