From 5ea3ab5302b95500424d61eab0dda97e98cc53d8 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Mon, 26 Oct 2020 13:19:09 +0200 Subject: [PATCH] foo --- Makefile | 13 +++- src/ggfx_vk.c | 21 +++++- test.c | 11 --- test_win.c | 166 +++++++++++++++++++++++++++++++++++++++++++ test_x11.c | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 418 insertions(+), 13 deletions(-) delete mode 100644 test.c create mode 100644 test_win.c create mode 100644 test_x11.c diff --git a/Makefile b/Makefile index 6060218..cf2a010 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -src = $(wildcard src/*.c) test.c +src = $(wildcard src/*.c) obj = $(src:.c=.o) dep = $(obj:.o=.d) bin = test @@ -6,6 +6,17 @@ bin = test CFLAGS = -pedantic -Wall -g -MMD -Isrc LDFLAGS = -lvulkan -lm +sys ?= $(shell uname -s | sed 's/MINGW.*/mingw/') + +ifeq ($(sys), mingw) + src += test_win.c + CFLAGS += -DBUILD_WIN32 +else + src += test_x11.c + CFLAGS += -DBUILD_X11 + LDFLAGS += -lX11 +endif + $(bin): $(obj) $(CC) -o $@ $(obj) $(LDFLAGS) diff --git a/src/ggfx_vk.c b/src/ggfx_vk.c index dd8b832..ba42b86 100644 --- a/src/ggfx_vk.c +++ b/src/ggfx_vk.c @@ -19,8 +19,10 @@ int ggfx_init(const char *appname, unsigned int flags) VkApplicationInfo appinf = {0}; VkLayerProperties *lprop = 0; VkExtensionProperties *iext; - uint32_t i, j, num_inst_layers, num_inst_ext, lprop_count, iext_count; + uint32_t i, j, num_inst_layers, num_inst_ext, lprop_count, iext_count, pdev_count; char **inst_layers = 0, **inst_ext = 0; + VkPhysicalDevice *pdev; + VkPhysicalDeviceProperties pdevp; static const char *debug_layers[] = { "VK_LAYER_LUNARG_device_limits", @@ -36,6 +38,7 @@ int ggfx_init(const char *appname, unsigned int flags) static const char *extensions[] = { "VK_KHR_surface", "VK_KHR_xlib_surface", + "VK_KHR_win32_surface", 0 }; @@ -119,6 +122,22 @@ int ggfx_init(const char *appname, unsigned int flags) return -1; } + if(vkEnumeratePhysicalDevices(vk, &pdev_count, 0) != 0 || !pdev_count) { + fprintf(stderr, "ggfx_init: failed to enumerate physical devices\n"); + return -1; + } + if(!(pdev = malloc(pdev_count * sizeof *pdev))) { + perror("ggfx_init: failed to allocate memory for physical devices"); + return -1; + } + vkEnumeratePhysicalDevices(vk, &pdev_count, pdev); + + printf("Found %d physical devices\n", pdev_count); + for(i=0; i +#include +#include "gphgfx.h" + +static void redraw(void); +static void reshape(int x, int y); +static void keydown(int key, int x, int y); +static void keyup(int key, int x, int y); +static void button(int bn, int st, int x, int y); +static void motion(int x, int y); + +static int create_window(const char *title, int width, int height); +static HRESULT CALLBACK handle_message(HWND win, unsigned int msg, WPARAM wparam, LPARAM lparam); +static int translate_vkey(int vkey); +static void handle_mbutton(int bn, int st, WPARAM wparam, LPARAM lparam); + +static HWND win; +static HINSTANCE hinst; +static HDC dc; +static int win_width, win_height; + + +int WINAPI WinMain(HINSTANCE hinst_, HINSTANCE hprev, char *cmdline, int showcmd) +{ + WNDCLASSEX wc = {0}; + MSG msg; + + hinst = hinst_; + + wc.cbSize = sizeof wc; + wc.hbrBackground = GetStockObject(BLACK_BRUSH); + wc.hCursor = LoadCursor(0, IDC_ARROW); + wc.hIcon = wc.hIconSm = LoadIcon(0, IDI_APPLICATION); + wc.hInstance = hinst; + wc.lpfnWndProc = handle_message; + wc.lpszClassName = "gphgfxtest"; + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + if(!RegisterClassEx(&wc)) { + fprintf(stderr, "failed to register window class\n"); + return 1; + } + + if(create_window("gph-gfx test", 800, 600) == -1) { + UnregisterClass("gphgfxtest", hinst); + return 1; + } + + for(;;) { + while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + if(quit) goto end; + } + redraw(); + } +end: + + ggfx_shutdown(); + ReleaseDC(dc); + DestroyWindow(win); + UnregisterClass("gphgfxtest", hinst); + return 0; +} + +static int create_window(const char *title, int width, int height) +{ + if(!(win = CreateWindow("gphgfxtest", title, WS_OVERLAPPEDWINDOW, 0, 0, width, + height, 0, 0, hinst, 0))) { + fprintf(stderr, "failed to create window\n"); + return -1; + } + dc = GetDC(win); + + ShowWindow(win, 1); + return 0; +} + +static HRESULT CALLBACK handle_message(HWND win, unsigned int msg, WPARAM wparam, LPARAM lparam) +{ + static int mouse_x, mouse_y; + int x, y, key; + + switch(msg) { + case WM_CLOSE: + quit = 1; + PostQuitMessage(0); + break; + + case WM_PAINT: + /*upd_pending = 1;*/ + ValidateRect(win, 0); + break; + + case WM_SIZE: + x = lparam & 0xffff; + y = lparam >> 16; + if(x != win_width && y != win_height) { + win_width = x; + win_height = y; + reshape(win_width, win_height); + } + break; + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + key = translate_vkey(wparam); + keydown(key, mouse_x, mouse_y); + break; + + case WM_KEYUP: + case WM_SYSKEYUP: + key = translate_vkey(wparam); + keyup(key, mouse_x, mouse_y); + break; + + case WM_LBUTTONDOWN: + handle_mbutton(0, 1, wparam, lparam); + break; + case WM_MBUTTONDOWN: + handle_mbutton(1, 1, wparam, lparam); + break; + case WM_RBUTTONDOWN: + handle_mbutton(2, 1, wparam, lparam); + break; + case WM_LBUTTONUP: + handle_mbutton(0, 0, wparam, lparam); + break; + case WM_MBUTTONUP: + handle_mbutton(1, 0, wparam, lparam); + break; + case WM_RBUTTONUP: + handle_mbutton(2, 0, wparam, lparam); + break; + + case WM_MOUSEMOVE: + motion(lparam & 0xffff, lparam >> 16); + break; + + case WM_SYSCOMMAND: + wparam &= 0xfff0; + if(wparam == SC_KEYMENU || wparam == SC_SCREENSAVE || wparam == SC_MONITORPOWER) { + return 0; + } + default: + return DefWindowProc(win, msg, wparam, lparam); + } + + return 0; +} + + +static int translate_vkey(int vkey) +{ + if(vkey >= 'A' && vkey <= 'Z') { + vkey += 32; + } + + return vkey; +} + +static void handle_mbutton(int bn, int st, WPARAM wparam, LPARAM lparam) +{ + int x = lparam & 0xffff; + int y = lparam >> 16; + mouse(bn, st, x, y); +} diff --git a/test_x11.c b/test_x11.c new file mode 100644 index 0000000..1c9e143 --- /dev/null +++ b/test_x11.c @@ -0,0 +1,220 @@ +#include +#include +#include +#include +#include +#include "gphgfx.h" + +static void redraw(void); +static void reshape(int x, int y); +static void keydown(int key, int x, int y); +static void keyup(int key, int x, int y); +static void button(int bn, int st, int x, int y); +static void motion(int x, int y); + +static int create_window(const char *title, int width, int height); +static void handle_event(XEvent *ev); +static KeySym translate_keysym(KeySym sym); +static void set_window_title(const char *title); + +static Display *dpy; +static int scr; +static Window win, root; +static Atom xa_wm_proto, xa_wm_del_win; +static int quit, mapped, win_width, win_height, modstate; +static GC gc; + +int main(int argc, char **argv) +{ + if(!(dpy = XOpenDisplay(0))) { + fprintf(stderr, "failed to connect to the X server\n"); + return 1; + } + xa_wm_proto = XInternAtom(dpy, "WM_PROTOCOLS", False); + xa_wm_del_win = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + + scr = DefaultScreen(dpy); + root = RootWindow(dpy, scr); + + if(create_window("gph-gfx test", 800, 600) == -1) { + return 1; + } + + if(ggfx_init("test", GGFX_INIT_DEBUG) == -1) { + return 1; + } + + for(;;) { + while(XPending(dpy)) { + XEvent ev; + XNextEvent(dpy, &ev); + handle_event(&ev); + if(quit) goto end; + } + redraw(); + } +end: + + ggfx_shutdown(); + XFreeGC(dpy, gc); + XCloseDisplay(dpy); + return 0; +} + + +static void redraw(void) +{ + XSetForeground(dpy, gc, 0xff00); + XClearWindow(dpy, win); + usleep(10000); +} + +static void reshape(int x, int y) +{ + printf("reshape %dx%d\n", x, y); +} + +static void keydown(int key, int x, int y) +{ + switch(key) { + case 27: + quit = 1; + break; + } +} + +static void keyup(int key, int x, int y) +{ +} + +static void button(int bn, int st, int x, int y) +{ +} + +static void motion(int x, int y) +{ +} + +static int create_window(const char *title, int width, int height) +{ + XSetWindowAttributes xattr = {0}; + XVisualInfo vinf; + unsigned int xattr_mask; + + if(!XMatchVisualInfo(dpy, scr, 24, TrueColor, &vinf)) { + fprintf(stderr, "failed to find appropriate visual\n"); + return -1; + } + + xattr.background_pixel = BlackPixel(dpy, scr); + xattr.colormap = XCreateColormap(dpy, root, vinf.visual, AllocNone); + xattr_mask = CWBackPixel | CWColormap | CWBackPixmap | CWBorderPixel; + if(!(win = XCreateWindow(dpy, root, 0, 0, width, height, 0, vinf.depth, + InputOutput, vinf.visual, xattr_mask, &xattr))) { + fprintf(stderr, "Failed to create window\n"); + return -1; + } + + XSelectInput(dpy, win, ExposureMask | StructureNotifyMask | KeyPressMask | + KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask); + + set_window_title(title); + XSetWMProtocols(dpy, win, &xa_wm_del_win, 1); + XMapWindow(dpy, win); + + gc = XCreateGC(dpy, win, 0, 0); + return 0; +} + + +static KeySym translate_keysym(KeySym sym) +{ + switch(sym) { + case XK_Escape: + return 27; + case XK_BackSpace: + return '\b'; + case XK_Linefeed: + return '\r'; + case XK_Return: + return '\n'; + case XK_Delete: + return 127; + case XK_Tab: + return '\t'; + default: + break; + } + return sym; +} + +static void handle_event(XEvent *ev) +{ + KeySym sym; + + switch(ev->type) { + case MapNotify: + mapped = 1; + break; + case UnmapNotify: + 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(ev->xconfigure.width, ev->xconfigure.height); + } + break; + + case ClientMessage: + if(ev->xclient.message_type == xa_wm_proto) { + if(ev->xclient.data.l[0] == xa_wm_del_win) { + quit = 1; + } + } + break; + + case Expose: + /*upd_pending = 1;*/ + break; + + case KeyPress: + case KeyRelease: + modstate = ev->xkey.state & (ShiftMask | ControlMask | Mod1Mask); + if(!(sym = XLookupKeysym(&ev->xkey, 0))) { + break; + } + sym = translate_keysym(sym); + if(ev->type == KeyPress) { + keydown(sym, ev->xkey.x, ev->xkey.y); + } else { + keyup(sym, ev->xkey.x, ev->xkey.y); + } + break; + + case ButtonPress: + case ButtonRelease: + modstate = ev->xbutton.state & (ShiftMask | ControlMask | Mod1Mask); + button(ev->xbutton.button - Button1, ev->type == ButtonPress, + ev->xbutton.x, ev->xbutton.y); + break; + + case MotionNotify: + motion(ev->xmotion.x, ev->xmotion.y); + break; + + default: + break; + } +} + +static void set_window_title(const char *title) +{ + XTextProperty tprop; + if(!XStringListToTextProperty((char**)&title, 1, &tprop)) { + return; + } + XSetWMName(dpy, win, &tprop); + XFree(tprop.value); +} -- 1.7.10.4