foo
authorJohn Tsiombikas <nuclear@member.fsf.org>
Mon, 26 Oct 2020 11:19:09 +0000 (13:19 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Mon, 26 Oct 2020 11:19:09 +0000 (13:19 +0200)
Makefile
src/ggfx_vk.c
test.c [deleted file]
test_win.c [new file with mode: 0644]
test_x11.c [new file with mode: 0644]

index 6060218..cf2a010 100644 (file)
--- 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)
 
index dd8b832..ba42b86 100644 (file)
@@ -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<pdev_count; i++) {
+               vkGetPhysicalDeviceProperties(pdev[i], &pdevp);
+               printf(" - %s\n", pdevp.deviceName);
+       }
+
        return 0;
 }
 
diff --git a/test.c b/test.c
deleted file mode 100644 (file)
index 8e9395e..0000000
--- a/test.c
+++ /dev/null
@@ -1,11 +0,0 @@
-#include "gphgfx.h"
-
-int main(int argc, char **argv)
-{
-       if(ggfx_init("test", GGFX_INIT_DEBUG) == -1) {
-               return 1;
-       }
-
-       ggfx_shutdown();
-       return 0;
-}
diff --git a/test_win.c b/test_win.c
new file mode 100644 (file)
index 0000000..f1e75a5
--- /dev/null
@@ -0,0 +1,166 @@
+#include <stdio.h>
+#include <windows.h>
+#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 (file)
index 0000000..1c9e143
--- /dev/null
@@ -0,0 +1,220 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#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);
+}