nuclear@4: #include nuclear@4: #include nuclear@4: #include nuclear@4: #include nuclear@4: #include "wsys.h" nuclear@4: #include "vku.h" nuclear@4: nuclear@4: struct callbacks { nuclear@4: void (*display)(void); nuclear@4: void (*reshape)(int, int); nuclear@4: void (*keyboard)(int, int); nuclear@4: void (*mouse)(int, int, int, int); nuclear@4: void (*motion)(int, int); nuclear@4: void (*passive)(int, int); nuclear@4: }; nuclear@4: nuclear@4: enum { nuclear@4: QUIT = 1, nuclear@4: RESHAPE = 2, nuclear@4: REDISPLAY = 4 nuclear@4: }; nuclear@4: nuclear@4: static void proc_event(XEvent *ev); nuclear@4: nuclear@4: static Display *dpy; nuclear@4: static Window win; nuclear@5: static VkSurfaceKHR surf; nuclear@5: static VkSwapchainKHR swapchain; nuclear@6: static VkImage *swapchain_images; nuclear@6: static int next_swapchain_image; nuclear@4: static Atom xa_wm_delete; nuclear@4: static int win_width, win_height; nuclear@4: static int win_mapped; nuclear@4: static unsigned int evmask = StructureNotifyMask | ExposureMask; nuclear@4: static unsigned int pending; nuclear@4: static struct callbacks cb; nuclear@4: nuclear@4: int wsys_create_window(int xsz, int ysz) nuclear@4: { nuclear@4: int i, scr, num_visuals; nuclear@4: Window root_win; nuclear@4: Visual *vis = 0; nuclear@4: XSetWindowAttributes xattr; nuclear@4: unsigned int xattr_mask; nuclear@4: XVisualInfo *vinf, vinf_match; nuclear@4: nuclear@4: if(!(dpy = XOpenDisplay(0))) { nuclear@4: fprintf(stderr, "failed to open connection to the X server\n"); nuclear@4: return -1; nuclear@4: } nuclear@4: scr = DefaultScreen(dpy); nuclear@4: root_win = RootWindow(dpy, scr); nuclear@4: nuclear@4: xa_wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False); nuclear@4: nuclear@4: vinf_match.screen = scr; nuclear@4: vinf_match.depth = 24; nuclear@4: vinf_match.class = TrueColor; nuclear@4: nuclear@4: if(!(vinf = XGetVisualInfo(dpy, VisualScreenMask | VisualDepthMask | VisualClassMask, &vinf_match, &num_visuals))) { nuclear@4: fprintf(stderr, "failed to retrieve matching visuals\n"); nuclear@4: XCloseDisplay(dpy); nuclear@4: return -1; nuclear@4: } nuclear@4: nuclear@4: for(i=0; itype) { nuclear@4: case MapNotify: nuclear@4: win_mapped = 1; nuclear@4: break; nuclear@4: nuclear@4: case UnmapNotify: nuclear@4: win_mapped = 0; nuclear@4: break; nuclear@4: nuclear@4: case ClientMessage: nuclear@4: if(ev->xclient.data.l[0] == xa_wm_delete) { nuclear@4: pending |= QUIT; nuclear@4: } nuclear@4: break; nuclear@4: nuclear@4: case ConfigureNotify: nuclear@4: if(ev->xconfigure.width != win_width || ev->xconfigure.height != win_height) { nuclear@4: win_width = ev->xconfigure.width; nuclear@4: win_height = ev->xconfigure.height; nuclear@4: pending |= RESHAPE; nuclear@4: } nuclear@4: break; nuclear@4: nuclear@4: case Expose: nuclear@4: if(ev->xexpose.count == 0) { nuclear@4: pending |= REDISPLAY; nuclear@4: } nuclear@4: break; nuclear@4: nuclear@4: case KeyPress: nuclear@4: case KeyRelease: nuclear@4: if(cb.keyboard) { nuclear@4: KeySym sym; nuclear@4: char str[16]; nuclear@4: XLookupString(&ev->xkey, str, sizeof str, &sym, 0); nuclear@4: cb.keyboard(sym & 0xff, ev->type == KeyPress ? 1 : 0); nuclear@4: } nuclear@4: break; nuclear@4: nuclear@4: case ButtonPress: nuclear@4: case ButtonRelease: nuclear@4: if(cb.mouse) { nuclear@4: int bn = ev->xbutton.button - Button1; nuclear@4: int pressed = ev->type == ButtonPress ? 1 : 0; nuclear@4: cb.mouse(bn, pressed, ev->xbutton.x, ev->xbutton.y); nuclear@4: } nuclear@4: break; nuclear@4: nuclear@4: case MotionNotify: nuclear@4: if(ev->xmotion.state & 0x1f00) { nuclear@4: if(cb.motion) { nuclear@4: cb.motion(ev->xmotion.x, ev->xmotion.y); nuclear@4: } nuclear@4: } else { nuclear@4: if(cb.passive) { nuclear@4: cb.passive(ev->xmotion.x, ev->xmotion.y); nuclear@4: } nuclear@4: } nuclear@4: break; nuclear@4: } nuclear@4: }