demos/triangle: Destroy the window when escape is pressed.

This commit is contained in:
Henri Verbeet 2016-11-02 14:44:24 +01:00
parent f9805396d9
commit 169810d20d
5 changed files with 61 additions and 9 deletions

View File

@ -58,7 +58,7 @@ AC_CHECK_LIB([pthread], [pthread_create],
AC_CHECK_LIB([vulkan], [vkGetInstanceProcAddr], [], [AC_MSG_ERROR([libvulkan not found.])]) AC_CHECK_LIB([vulkan], [vkGetInstanceProcAddr], [], [AC_MSG_ERROR([libvulkan not found.])])
PKG_CHECK_MODULES([XCB], [xcb], [], [AC_MSG_ERROR[libxcb not found.]]) PKG_CHECK_MODULES([XCB], [xcb xcb-keysyms], [], [AC_MSG_ERROR[libxcb and/or libxcb-keysyms not found.]])
dnl Check for functions dnl Check for functions
VKD3D_CHECK_SYNC_ADD_AND_FETCH_FUNC VKD3D_CHECK_SYNC_ADD_AND_FETCH_FUNC

View File

@ -41,9 +41,13 @@
#define WIDL_C_INLINE_WRAPPERS #define WIDL_C_INLINE_WRAPPERS
#define COBJMACROS #define COBJMACROS
#include <d3d12.h> #include <d3d12.h>
#include <inttypes.h>
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x)) #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x))
#define DEMO_KEY_UNKNOWN 0x0000
#define DEMO_KEY_ESCAPE 0xff1b
struct demo_vec3 struct demo_vec3
{ {
float x, y, z; float x, y, z;
@ -62,6 +66,8 @@ struct demo_swapchain_desc
DXGI_FORMAT format; DXGI_FORMAT format;
}; };
typedef uint32_t demo_key;
static inline void demo_rasterizer_desc_init_default(D3D12_RASTERIZER_DESC *desc) static inline void demo_rasterizer_desc_init_default(D3D12_RASTERIZER_DESC *desc)
{ {
desc->FillMode = D3D12_FILL_MODE_SOLID; desc->FillMode = D3D12_FILL_MODE_SOLID;

View File

@ -44,6 +44,7 @@ struct demo_window
struct demo *demo; struct demo *demo;
void *user_data; void *user_data;
void (*draw_func)(void *user_data); void (*draw_func)(void *user_data);
void (*key_press_func)(struct demo_window *window, demo_key key, void *user_data);
}; };
struct demo_swapchain struct demo_swapchain
@ -74,6 +75,7 @@ static inline struct demo_window *demo_window_create(struct demo *demo, const ch
window->instance = GetModuleHandle(NULL); window->instance = GetModuleHandle(NULL);
window->draw_func = draw_func; window->draw_func = draw_func;
window->user_data = user_data; window->user_data = user_data;
window->key_press_func = NULL;
style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE; style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE;
AdjustWindowRect(&rect, style, FALSE); AdjustWindowRect(&rect, style, FALSE);
@ -101,6 +103,13 @@ static inline void demo_window_destroy(struct demo_window *window)
free(window); free(window);
} }
static inline demo_key demo_key_from_vkey(DWORD vkey)
{
if (vkey == VK_ESCAPE)
return DEMO_KEY_ESCAPE;
return DEMO_KEY_UNKNOWN;
}
static inline LRESULT CALLBACK demo_window_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) static inline LRESULT CALLBACK demo_window_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{ {
struct demo_window *window = (void *)GetWindowLongPtrW(hwnd, GWLP_USERDATA); struct demo_window *window = (void *)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
@ -112,6 +121,12 @@ static inline LRESULT CALLBACK demo_window_proc(HWND hwnd, UINT message, WPARAM
window->draw_func(window->user_data); window->draw_func(window->user_data);
return 0; return 0;
case WM_KEYDOWN:
if (!window->key_press_func)
break;
window->key_press_func(window, demo_key_from_vkey(wparam), window->user_data);
return 0;
case WM_DESTROY: case WM_DESTROY:
window->hwnd = NULL; window->hwnd = NULL;
demo_window_destroy(window); demo_window_destroy(window);
@ -121,6 +136,12 @@ static inline LRESULT CALLBACK demo_window_proc(HWND hwnd, UINT message, WPARAM
return DefWindowProcW(hwnd, message, wparam, lparam); return DefWindowProcW(hwnd, message, wparam, lparam);
} }
static inline void demo_window_set_key_press_func(struct demo_window *window,
void (*key_press_func)(struct demo_window *window, demo_key key, void *user_data))
{
window->key_press_func = key_press_func;
}
static inline void demo_process_events(struct demo *demo) static inline void demo_process_events(struct demo *demo)
{ {
MSG msg = {0}; MSG msg = {0};

View File

@ -25,6 +25,7 @@
#include <vkd3d.h> #include <vkd3d.h>
#include <xcb/xcb_event.h> #include <xcb/xcb_event.h>
#include <xcb/xcb_icccm.h> #include <xcb/xcb_icccm.h>
#include <xcb/xcb_keysyms.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <limits.h> #include <limits.h>
#include <unistd.h> #include <unistd.h>
@ -35,6 +36,7 @@ struct demo
xcb_connection_t *connection; xcb_connection_t *connection;
xcb_atom_t wm_protocols_atom; xcb_atom_t wm_protocols_atom;
xcb_atom_t wm_delete_window_atom; xcb_atom_t wm_delete_window_atom;
xcb_key_symbols_t *xcb_keysyms;
struct demo_window **windows; struct demo_window **windows;
size_t windows_size; size_t windows_size;
@ -48,6 +50,7 @@ struct demo_window
void *user_data; void *user_data;
void (*draw_func)(void *user_data); void (*draw_func)(void *user_data);
void (*key_press_func)(struct demo_window *window, demo_key key, void *user_data);
}; };
struct demo_swapchain struct demo_swapchain
@ -131,7 +134,7 @@ static inline struct demo_window *demo_find_window(struct demo *demo, xcb_window
static inline struct demo_window *demo_window_create(struct demo *demo, const char *title, static inline struct demo_window *demo_window_create(struct demo *demo, const char *title,
unsigned int width, unsigned int height, void (*draw_func)(void *user_data), void *user_data) unsigned int width, unsigned int height, void (*draw_func)(void *user_data), void *user_data)
{ {
static const uint32_t window_events = XCB_EVENT_MASK_EXPOSURE; static const uint32_t window_events = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS;
struct demo_window *window; struct demo_window *window;
xcb_size_hints_t hints; xcb_size_hints_t hints;
@ -150,6 +153,7 @@ static inline struct demo_window *demo_window_create(struct demo *demo, const ch
window->demo = demo; window->demo = demo;
window->draw_func = draw_func; window->draw_func = draw_func;
window->user_data = user_data; window->user_data = user_data;
window->key_press_func = NULL;
screen = xcb_setup_roots_iterator(xcb_get_setup(demo->connection)).data; screen = xcb_setup_roots_iterator(xcb_get_setup(demo->connection)).data;
xcb_create_window(demo->connection, XCB_COPY_FROM_PARENT, window->window, screen->root, 0, 0, xcb_create_window(demo->connection, XCB_COPY_FROM_PARENT, window->window, screen->root, 0, 0,
width, height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, width, height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual,
@ -181,16 +185,23 @@ static inline void demo_window_destroy(struct demo_window *window)
free(window); free(window);
} }
static inline void demo_window_set_key_press_func(struct demo_window *window,
void (*key_press_func)(struct demo_window *window, demo_key key, void *user_data))
{
window->key_press_func = key_press_func;
}
static inline void demo_process_events(struct demo *demo) static inline void demo_process_events(struct demo *demo)
{ {
const xcb_client_message_event_t *client_message; const struct xcb_client_message_event_t *client_message;
struct xcb_key_press_event_t *key_press;
xcb_generic_event_t *event; xcb_generic_event_t *event;
struct demo_window *window; struct demo_window *window;
bool done = false; xcb_keysym_t sym;
xcb_flush(demo->connection); xcb_flush(demo->connection);
while (!done && (event = xcb_wait_for_event(demo->connection))) while (demo->window_count && (event = xcb_wait_for_event(demo->connection)))
{ {
switch (XCB_EVENT_RESPONSE_TYPE(event)) switch (XCB_EVENT_RESPONSE_TYPE(event))
{ {
@ -199,16 +210,20 @@ static inline void demo_process_events(struct demo *demo)
window->draw_func(window->user_data); window->draw_func(window->user_data);
break; break;
case XCB_KEY_PRESS:
key_press = (struct xcb_key_press_event_t *)event;
if (!(window = demo_find_window(demo, key_press->event)) || !window->key_press_func)
break;
sym = xcb_key_press_lookup_keysym(demo->xcb_keysyms, key_press, 0);
window->key_press_func(window, sym, window->user_data);
break;
case XCB_CLIENT_MESSAGE: case XCB_CLIENT_MESSAGE:
client_message = (xcb_client_message_event_t *)event; client_message = (xcb_client_message_event_t *)event;
if (client_message->type == demo->wm_protocols_atom if (client_message->type == demo->wm_protocols_atom
&& client_message->data.data32[0] == demo->wm_delete_window_atom && client_message->data.data32[0] == demo->wm_delete_window_atom
&& (window = demo_find_window(demo, client_message->window))) && (window = demo_find_window(demo, client_message->window)))
{
demo_window_destroy(window); demo_window_destroy(window);
if (!demo->window_count)
done = true;
}
break; break;
} }
@ -226,6 +241,8 @@ static inline bool demo_init(struct demo *demo)
goto fail; goto fail;
if ((demo->wm_protocols_atom = demo_get_atom(demo->connection, "WM_PROTOCOLS")) == XCB_NONE) if ((demo->wm_protocols_atom = demo_get_atom(demo->connection, "WM_PROTOCOLS")) == XCB_NONE)
goto fail; goto fail;
if (!(demo->xcb_keysyms = xcb_key_symbols_alloc(demo->connection)))
goto fail;
demo->windows = NULL; demo->windows = NULL;
demo->windows_size = 0; demo->windows_size = 0;
@ -241,6 +258,7 @@ fail:
static inline void demo_cleanup(struct demo *demo) static inline void demo_cleanup(struct demo *demo)
{ {
free(demo->windows); free(demo->windows);
xcb_key_symbols_free(demo->xcb_keysyms);
xcb_disconnect(demo->connection); xcb_disconnect(demo->connection);
} }

View File

@ -358,6 +358,12 @@ static void cxt_load_assets(struct cx_triangle *cxt)
cxt_wait_for_previous_frame(cxt); cxt_wait_for_previous_frame(cxt);
} }
static void cxt_key_press(struct demo_window *window, demo_key key, void *user_data)
{
if (key == DEMO_KEY_ESCAPE)
demo_window_destroy(window);
}
static int cxt_main(void) static int cxt_main(void)
{ {
unsigned int width = 640, height = 480; unsigned int width = 640, height = 480;
@ -370,6 +376,7 @@ static int cxt_main(void)
cxt.window = demo_window_create(&cxt.demo, "Vkd3d Triangle", cxt.window = demo_window_create(&cxt.demo, "Vkd3d Triangle",
width, height, cxt_render_frame, &cxt); width, height, cxt_render_frame, &cxt);
demo_window_set_key_press_func(cxt.window, cxt_key_press);
cxt.width = width; cxt.width = width;
cxt.height = height; cxt.height = height;