--- /dev/null
+#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);
+}