From fed26b0af76ec211f6e029c4b74288f24739bd4a Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Sat, 18 Dec 2021 14:02:46 +0200 Subject: [PATCH] initial commit --- .gitignore | 4 ++ Makefile | 25 +++++++++ src/app.c | 38 +++++++++++++ src/app.h | 22 ++++++++ src/main_x11.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 255 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 src/app.c create mode 100644 src/app.h create mode 100644 src/main_x11.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..59e7bce --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.o +*.swp +*.d +vkray diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b9931ac --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ +src = $(wildcard src/*.c) +obj = $(src:.c=.o) +dep = $(src:.c=.d) +bin = vkray + +sdr = $(wildcard sdr/*.glsl) +spirv = $(sdr:.glsl=.spv) + +CFLAGS = -pedantic -Wall -g -MMD +LDFLAGS = -lvulkan -lX11 + +$(bin): $(obj) $(spirv) + $(CC) -o $@ $(obj) $(LDFLAGS) + +%.spv: %.v.glsl + glslangValidator -o $@ -S vert -V $< + +%.spv: %.p.glsl + glslangValidator -o $@ -S frag -V $< + +-include $(dep) + +.PHONY: clean +clean: + rm -f $(src) $(obj) $(spirv) diff --git a/src/app.c b/src/app.c new file mode 100644 index 0000000..9be52ca --- /dev/null +++ b/src/app.c @@ -0,0 +1,38 @@ +#include "app.h" + +int app_init(void) +{ + return 0; +} + +void app_cleanup(void) +{ +} + + +void app_display(void) +{ +} + +void app_reshape(int x, int y) +{ +} + +void app_keyboard(int key, int press) +{ + if(!press) return; + + switch(key) { + case 27: + app_quit(); + break; + } +} + +void app_mouse(int bn, int press, int x, int y) +{ +} + +void app_motion(int x, int y) +{ +} diff --git a/src/app.h b/src/app.h new file mode 100644 index 0000000..4f891e7 --- /dev/null +++ b/src/app.h @@ -0,0 +1,22 @@ +#ifndef APP_H_ +#define APP_H_ + +enum { + KEY_DEL = 127, + KEY_HOME, KEY_END, + KEY_PGUP, KEY_PGDOWN +}; + +int app_init(void); +void app_cleanup(void); + +void app_display(void); +void app_reshape(int x, int y); +void app_keyboard(int key, int press); +void app_mouse(int bn, int press, int x, int y); +void app_motion(int x, int y); + +void app_quit(void); +void app_swap_buffers(void); + +#endif /* APP_H_ */ diff --git a/src/main_x11.c b/src/main_x11.c new file mode 100644 index 0000000..54f4df6 --- /dev/null +++ b/src/main_x11.c @@ -0,0 +1,166 @@ +#include +#include +#include +#include +#include "app.h" + +static Window create_window(const char *title, int xsz, int ysz); +static void handle_event(XEvent *ev); +static int translate_keysym(KeySym sym); + +static Display *dpy; +static Window win, root_win; +static int xscr; +static Atom xa_wm_proto, xa_wm_del_win; +static int reshape_pending, quit; +static int win_width, win_height, win_mapped; + +int main(int argc, char **argv) +{ + XEvent ev; + + if(!(dpy = XOpenDisplay(0))) { + fprintf(stderr, "failed to connect to the X server\n"); + return 1; + } + xscr = DefaultScreen(dpy); + root_win = RootWindow(dpy, xscr); + xa_wm_proto = XInternAtom(dpy, "WM_PROTOCOLS", False); + xa_wm_del_win = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + + if(!(win = create_window("vkray", 1280, 800))) { + return 1; + } + + for(;;) { + while(XPending(dpy)) { + XNextEvent(dpy, &ev); + handle_event(&ev); + if(quit) goto end; + } + + if(reshape_pending) { + app_reshape(win_width, win_height); + } + app_display(); + } + +end: + XDestroyWindow(dpy, win); + XCloseDisplay(dpy); + return 0; +} + +void app_quit(void) +{ + quit = 1; +} + +void app_swap_buffers(void) +{ +} + +static Window create_window(const char *title, int xsz, int ysz) +{ + Window win; + XVisualInfo vinf; + XTextProperty txprop; + XSetWindowAttributes xattr; + + if(!XMatchVisualInfo(dpy, xscr, 24, TrueColor, &vinf)) { + fprintf(stderr, "no suitable visual found\n"); + return 0; + } + + xattr.background_pixel = BlackPixel(dpy, xscr); + xattr.colormap = XCreateColormap(dpy, root_win, vinf.visual, AllocNone); + + if(!(win = XCreateWindow(dpy, root_win, 0, 0, xsz, ysz, 0, 24, InputOutput, + vinf.visual, CWBackPixel | CWColormap, &xattr))) { + fprintf(stderr, "failed to create window\n"); + return 0; + } + + XSelectInput(dpy, win, KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | + ButtonMotionMask | ExposureMask | StructureNotifyMask); + + XSetWMProtocols(dpy, win, &xa_wm_del_win, 1); + + if(XStringListToTextProperty((char**)&title, 1, &txprop)) { + XSetWMName(dpy, win, &txprop); + XSetWMIconName(dpy, win, &txprop); + XFree(txprop.value); + } + + XMapWindow(dpy, win); + + reshape_pending = 1; + return win; +} + +static void handle_event(XEvent *ev) +{ + KeySym sym; + int key; + + switch(ev->type) { + case MapNotify: + win_mapped = 1; + break; + case UnmapNotify: + win_mapped = 0; + break; + + case ConfigureNotify: + if(ev->xconfigure.width != win_width || ev->xconfigure.height != win_height) { + win_width = ev->xconfigure.width; + win_height = ev->xconfigure.height; + reshape_pending = 1; + } + break; + + case KeyPress: + case KeyRelease: + if((sym = XLookupKeysym(&ev->xkey, 0)) && (key = translate_keysym(sym))) { + app_keyboard(key, ev->type == KeyPress); + } + break; + + case ButtonPress: + case ButtonRelease: + app_mouse(ev->xbutton.button - Button1, ev->type == ButtonPress, ev->xbutton.x, ev->xbutton.y); + break; + + case ClientMessage: + if(ev->xclient.message_type == xa_wm_proto) { + if(ev->xclient.data.l[0] == xa_wm_del_win) { + quit = 1; + } + } + break; + + default: + break; + } +} + +static int translate_keysym(KeySym sym) +{ + if(sym < 128) return sym; + + switch(sym) { + case XK_Escape: return 27; + case XK_Tab: return '\t'; + case XK_Return: return '\n'; + case XK_BackSpace: return '\b'; + case XK_Delete: return KEY_DEL; + case XK_Home: return KEY_HOME; + case XK_End: return KEY_END; + case XK_Page_Up: return KEY_PGUP; + case XK_Page_Down: return KEY_PGDOWN; + default: + break; + } + + return 0; +} -- 1.7.10.4