vulkan_test2
diff src/wsys_x11.c @ 4:c31c4115d44a
test 2, open window, create queue, etc ...
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 22 Sep 2017 15:26:29 +0300 |
parents | |
children | cec4b0e7fce8 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/wsys_x11.c Fri Sep 22 15:26:29 2017 +0300 1.3 @@ -0,0 +1,298 @@ 1.4 +#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <X11/Xlib.h> 1.7 +#include <X11/Xutil.h> 1.8 +#include "wsys.h" 1.9 +#include "vku.h" 1.10 + 1.11 +struct callbacks { 1.12 + void (*display)(void); 1.13 + void (*reshape)(int, int); 1.14 + void (*keyboard)(int, int); 1.15 + void (*mouse)(int, int, int, int); 1.16 + void (*motion)(int, int); 1.17 + void (*passive)(int, int); 1.18 +}; 1.19 + 1.20 +enum { 1.21 + QUIT = 1, 1.22 + RESHAPE = 2, 1.23 + REDISPLAY = 4 1.24 +}; 1.25 + 1.26 +static void proc_event(XEvent *ev); 1.27 + 1.28 +static Display *dpy; 1.29 +static Window win; 1.30 +static Atom xa_wm_delete; 1.31 +static int win_width, win_height; 1.32 +static int win_mapped; 1.33 +static unsigned int evmask = StructureNotifyMask | ExposureMask; 1.34 +static unsigned int pending; 1.35 +static struct callbacks cb; 1.36 + 1.37 +int wsys_create_window(int xsz, int ysz) 1.38 +{ 1.39 + int i, scr, num_visuals; 1.40 + Window root_win; 1.41 + Visual *vis = 0; 1.42 + XSetWindowAttributes xattr; 1.43 + unsigned int xattr_mask; 1.44 + XVisualInfo *vinf, vinf_match; 1.45 + 1.46 + if(!(dpy = XOpenDisplay(0))) { 1.47 + fprintf(stderr, "failed to open connection to the X server\n"); 1.48 + return -1; 1.49 + } 1.50 + scr = DefaultScreen(dpy); 1.51 + root_win = RootWindow(dpy, scr); 1.52 + 1.53 + xa_wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False); 1.54 + 1.55 + vinf_match.screen = scr; 1.56 + vinf_match.depth = 24; 1.57 + vinf_match.class = TrueColor; 1.58 + 1.59 + if(!(vinf = XGetVisualInfo(dpy, VisualScreenMask | VisualDepthMask | VisualClassMask, &vinf_match, &num_visuals))) { 1.60 + fprintf(stderr, "failed to retrieve matching visuals\n"); 1.61 + XCloseDisplay(dpy); 1.62 + return -1; 1.63 + } 1.64 + 1.65 + for(i=0; i<num_visuals; i++) { 1.66 + if(vku_xlib_usable_visual(dpy, vinf[i].visualid)) { 1.67 + vis = vinf[i].visual; 1.68 + break; 1.69 + } 1.70 + } 1.71 + if(!vis) { 1.72 + fprintf(stderr, "failed to find approprate visual\n"); 1.73 + XFree(vinf); 1.74 + XCloseDisplay(dpy); 1.75 + return -1; 1.76 + } 1.77 + 1.78 + xattr.background_pixel = xattr.border_pixel = BlackPixel(dpy, scr); 1.79 + xattr.colormap = XCreateColormap(dpy, root_win, vis, AllocNone); 1.80 + xattr_mask = CWBackPixel | CWBorderPixel | CWColormap; 1.81 + 1.82 + if(!(win = XCreateWindow(dpy, root_win, 0, 0, xsz, ysz, 0, 24, InputOutput, vis, xattr_mask, &xattr))) { 1.83 + fprintf(stderr, "failed to create X window\n"); 1.84 + XFree(vinf); 1.85 + XCloseDisplay(dpy); 1.86 + return -1; 1.87 + } 1.88 + XFree(vinf); 1.89 + 1.90 + XSelectInput(dpy, win, evmask); 1.91 + XSetWMProtocols(dpy, win, &xa_wm_delete, 1); 1.92 + 1.93 + wsys_set_window_title("X11 window"); 1.94 + XMapWindow(dpy, win); 1.95 + 1.96 + win_width = xsz; 1.97 + win_height = ysz; 1.98 + pending = RESHAPE | REDISPLAY; 1.99 + 1.100 + return 0; 1.101 +} 1.102 + 1.103 +void wsys_destroy_window(void) 1.104 +{ 1.105 + if(dpy) { 1.106 + if(win) { 1.107 + XDestroyWindow(dpy, win); 1.108 + win = 0; 1.109 + } 1.110 + XCloseDisplay(dpy); 1.111 + dpy = 0; 1.112 + } 1.113 +} 1.114 + 1.115 +void wsys_get_window_size(int *xsz, int *ysz) 1.116 +{ 1.117 + *xsz = win_width; 1.118 + *ysz = win_height; 1.119 +} 1.120 + 1.121 +void wsys_set_window_title(const char *title) 1.122 +{ 1.123 + XTextProperty text; 1.124 + XStringListToTextProperty((char**)&title, 1, &text); 1.125 + XSetWMName(dpy, win, &text); 1.126 + XSetWMIconName(dpy, win, &text); 1.127 + XFree(text.value); 1.128 +} 1.129 + 1.130 +void wsys_display_callback(void (*func)(void)) 1.131 +{ 1.132 + cb.display = func; 1.133 +} 1.134 + 1.135 +void wsys_reshape_callback(void (*func)(int, int)) 1.136 +{ 1.137 + cb.reshape = func; 1.138 +} 1.139 + 1.140 +void wsys_keyboard_callback(void (*func)(int, int)) 1.141 +{ 1.142 + cb.keyboard = func; 1.143 + if(func) { 1.144 + evmask |= KeyPressMask | KeyReleaseMask; 1.145 + } else { 1.146 + evmask &= ~(KeyPressMask | KeyReleaseMask); 1.147 + } 1.148 + if(win) { 1.149 + XSelectInput(dpy, win, evmask); 1.150 + } 1.151 +} 1.152 + 1.153 +void wsys_mouse_callback(void (*func)(int, int, int, int)) 1.154 +{ 1.155 + cb.mouse = func; 1.156 + if(func) { 1.157 + evmask |= ButtonPressMask | ButtonReleaseMask; 1.158 + } else { 1.159 + evmask &= ~(ButtonPressMask | ButtonReleaseMask); 1.160 + } 1.161 + if(win) { 1.162 + XSelectInput(dpy, win, evmask); 1.163 + } 1.164 +} 1.165 + 1.166 +void wsys_motion_callback(void (*func)(int, int)) 1.167 +{ 1.168 + cb.motion = func; 1.169 + if(func) { 1.170 + evmask |= ButtonMotionMask; 1.171 + } else { 1.172 + evmask &= ~ButtonMotionMask; 1.173 + } 1.174 + if(win) { 1.175 + XSelectInput(dpy, win, evmask); 1.176 + } 1.177 +} 1.178 + 1.179 +void wsys_passive_motion_callback(void (*func)(int, int)) 1.180 +{ 1.181 + cb.passive = func; 1.182 + if(func) { 1.183 + evmask |= PointerMotionMask; 1.184 + } else { 1.185 + evmask &= ~PointerMotionMask; 1.186 + } 1.187 + if(win) { 1.188 + XSelectInput(dpy, win, evmask); 1.189 + } 1.190 +} 1.191 + 1.192 +void wsys_swap_buffers(void) 1.193 +{ 1.194 + /* TODO */ 1.195 +} 1.196 + 1.197 +void wsys_redisplay(void) 1.198 +{ 1.199 + pending |= REDISPLAY; 1.200 +} 1.201 + 1.202 +void wsys_quit(void) 1.203 +{ 1.204 + pending |= QUIT; 1.205 +} 1.206 + 1.207 +int wsys_process_events(int mode) 1.208 +{ 1.209 + XEvent xev; 1.210 + 1.211 + if(pending & RESHAPE) { 1.212 + if(cb.reshape) { 1.213 + cb.reshape(win_width, win_height); 1.214 + } 1.215 + pending &= ~RESHAPE; 1.216 + } 1.217 + 1.218 + if(mode == WSYS_BLOCKING) { 1.219 + XNextEvent(dpy, &xev); 1.220 + proc_event(&xev); 1.221 + if(pending & QUIT) return -1; 1.222 + } 1.223 + 1.224 + while(XPending(dpy)) { 1.225 + XNextEvent(dpy, &xev); 1.226 + proc_event(&xev); 1.227 + if(pending & QUIT) return -1; 1.228 + } 1.229 + 1.230 + if(pending & REDISPLAY && win_mapped) { 1.231 + pending &= ~REDISPLAY; 1.232 + if(cb.display) { 1.233 + cb.display(); 1.234 + } 1.235 + } 1.236 + return 0; 1.237 +} 1.238 + 1.239 +static void proc_event(XEvent *ev) 1.240 +{ 1.241 + switch(ev->type) { 1.242 + case MapNotify: 1.243 + win_mapped = 1; 1.244 + break; 1.245 + 1.246 + case UnmapNotify: 1.247 + win_mapped = 0; 1.248 + break; 1.249 + 1.250 + case ClientMessage: 1.251 + if(ev->xclient.data.l[0] == xa_wm_delete) { 1.252 + pending |= QUIT; 1.253 + } 1.254 + break; 1.255 + 1.256 + case ConfigureNotify: 1.257 + if(ev->xconfigure.width != win_width || ev->xconfigure.height != win_height) { 1.258 + win_width = ev->xconfigure.width; 1.259 + win_height = ev->xconfigure.height; 1.260 + pending |= RESHAPE; 1.261 + } 1.262 + break; 1.263 + 1.264 + case Expose: 1.265 + if(ev->xexpose.count == 0) { 1.266 + pending |= REDISPLAY; 1.267 + } 1.268 + break; 1.269 + 1.270 + case KeyPress: 1.271 + case KeyRelease: 1.272 + if(cb.keyboard) { 1.273 + KeySym sym; 1.274 + char str[16]; 1.275 + XLookupString(&ev->xkey, str, sizeof str, &sym, 0); 1.276 + cb.keyboard(sym & 0xff, ev->type == KeyPress ? 1 : 0); 1.277 + } 1.278 + break; 1.279 + 1.280 + case ButtonPress: 1.281 + case ButtonRelease: 1.282 + if(cb.mouse) { 1.283 + int bn = ev->xbutton.button - Button1; 1.284 + int pressed = ev->type == ButtonPress ? 1 : 0; 1.285 + cb.mouse(bn, pressed, ev->xbutton.x, ev->xbutton.y); 1.286 + } 1.287 + break; 1.288 + 1.289 + case MotionNotify: 1.290 + if(ev->xmotion.state & 0x1f00) { 1.291 + if(cb.motion) { 1.292 + cb.motion(ev->xmotion.x, ev->xmotion.y); 1.293 + } 1.294 + } else { 1.295 + if(cb.passive) { 1.296 + cb.passive(ev->xmotion.x, ev->xmotion.y); 1.297 + } 1.298 + } 1.299 + break; 1.300 + } 1.301 +}