main3.c (3714B)
1 #include <stdint.h> 2 3 #include <X11/Xlib.h> 4 #include <X11/XKBlib.h> 5 #include <GL/glx.h> 6 #include <GL/gl.h> 7 #include <dlfcn.h> 8 #include <stdio.h> 9 #include <sys/syscall.h> 10 #include <time.h> 11 12 #define SCRW 800 13 #define SCRH 600 14 15 static __inline long __syscall2(long n, long a1, long a2) 16 { 17 unsigned long ret; 18 __asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2) 19 : "rcx", "r11", "memory"); 20 return ret; 21 } 22 23 static __inline uint64_t time_monotonic(void) 24 { 25 struct timespec now; 26 __syscall2(SYS_clock_gettime, CLOCK_MONOTONIC_RAW, (long)&now); 27 return now.tv_sec * 1000000 + now.tv_nsec / 1000; 28 } 29 30 static int visual_hints[] = { 31 GLX_RGBA, 32 GLX_DEPTH_SIZE, 24, 33 GLX_DOUBLEBUFFER, 34 None 35 }; 36 37 static const char *sym_names = 38 "libX11.so\0" 39 "XOpenDisplay\0" 40 "XCreateSimpleWindow\0" 41 "XSelectInput\0" 42 "XMapWindow\0" 43 "XPending\0" 44 "XNextEvent\0" 45 "XkbKeycodeToKeysym\0" 46 "\0" 47 "libGL.so\0" 48 "glXChooseVisual\0" 49 "glXCreateContext\0" 50 "glXMakeCurrent\0" 51 "glXSwapBuffers\0" 52 "glClear\0\0\0"; 53 54 static void *syms[12]; 55 56 #define _XOpenDisplay ((Display *(*)(const char *))syms[0]) 57 #define _XCreateSimpleWindow ((Window (*)(Display *, Window, int, int, unsigned, unsigned, unsigned, unsigned long, unsigned long))syms[1]) 58 #define _XSelectInput ((int (*)(Display *, Window, long))syms[2]) 59 #define _XMapWindow ((int (*)(Display *, Window))syms[3]) 60 #define _XPending ((int (*)(Display *))syms[4]) 61 #define _XNextEvent ((int (*)(Display *, XEvent *))syms[5]) 62 #define _XkbKeycodeToKeysym ((KeySym (*)(Display *, KeyCode, int, int))syms[6]) 63 64 #define _glXChooseVisual ((XVisualInfo *(*)(Display *, int, int *))syms[7]) 65 #define _glXCreateContext ((GLXContext (*)(Display *, XVisualInfo *, GLXContext, Bool))syms[8]) 66 #define _glXMakeCurrent ((Bool (*)(Display *, GLXDrawable, GLXContext))syms[9]) 67 #define _glXSwapBuffers ((void (*)(Display *, GLXDrawable))syms[10]) 68 69 #define _glClear ((void (*)(GLbitfield))syms[11]) 70 71 static void dl_load(void) 72 { 73 const char *name = sym_names; 74 void **sym = syms; 75 76 do 77 { 78 void *dl = dlopen(name, RTLD_LAZY | RTLD_GLOBAL); 79 for(;;) 80 { 81 while(*name++); 82 if(*name == 0) break; 83 *sym++ = dlsym(dl, name); 84 } 85 } while(*++name); 86 } 87 88 void my_main(int argc, const char **argv) 89 { 90 dl_load(); 91 92 Display *display = _XOpenDisplay(NULL); 93 int screen = DefaultScreen(display); 94 Window window = _XCreateSimpleWindow(display, RootWindow(display, screen), 0, 0, SCRW, SCRH, 0, 0, 0); 95 _XSelectInput(display, window, KeyPressMask | KeyReleaseMask); 96 XVisualInfo *visual_info = _glXChooseVisual(display, screen, visual_hints); 97 GLXContext context = _glXCreateContext(display, visual_info, NULL, True); 98 _glXMakeCurrent(display, window, context); 99 100 _XMapWindow(display, window); 101 102 uint64_t prev = time_monotonic(); 103 uint64_t t = 0; 104 for(;;) 105 { 106 XEvent event; 107 while(_XPending(display)) 108 { 109 _XNextEvent(display, &event); 110 if(event.type == KeyPress) 111 { 112 switch(_XkbKeycodeToKeysym(display, event.xkey.keycode, 0, 0)) 113 { 114 case XK_Escape: goto shutdown; 115 } 116 } 117 } 118 // draw demo 119 120 _glClear(GL_COLOR_BUFFER_BIT); 121 122 _glXSwapBuffers(display, window); 123 124 t += time_monotonic() - prev; 125 } 126 127 shutdown: 128 return; 129 } 130 131 asm ( 132 ".text\n" 133 ".global _start\n" 134 "_start:\n" 135 "xor %rbp,%rbp\n" 136 "pop %rdi\n" 137 "mov %rsp,%rsi\n" 138 "andq $-16,%rsp\n" 139 "call my_main\n" 140 "movq $60,%rax\n" 141 "xor %rdi,%rdi\n" 142 "syscall\n" 143 );