From e4e280da4f4d189862613d480ea2af5187abd60d Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Sun, 29 Dec 2019 20:41:48 -0500 Subject: [PATCH] add some jtk window functions --- src/jes/gui/jtk.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++- src/jes/gui/jtk.d | 6 ++++ 2 files changed, 94 insertions(+), 1 deletion(-) diff --git a/src/jes/gui/jtk.c b/src/jes/gui/jtk.c index 8d0930f..7007d26 100644 --- a/src/jes/gui/jtk.c +++ b/src/jes/gui/jtk.c @@ -1,6 +1,9 @@ -#include #include #include +#include +#include +#include +#include static Display * g_display; static XVisualInfo * g_vi; @@ -52,3 +55,87 @@ bool jtk_init() return true; } + +static Bool wait_for_notify(Display * display, XEvent * event, XPointer arg) +{ + return (event->type == MapNotify) && (event->xmap.window == (Window)arg); +} + +void * jtk_window_create() +{ + XEvent event; + Window window = XCreateWindow(g_display, + RootWindow(g_display, g_vi->screen), + 0, 0, 800, 800, 0, g_vi->depth, InputOutput, g_vi->visual, + CWBorderPixel | CWColormap | CWEventMask, &g_swa); + XMapWindow(g_display, window); + XIfEvent(g_display, &event, wait_for_notify, (XPointer)window); + if (glXMakeCurrent(g_display, window, g_context) == False) + { + fprintf(stderr, "glXMakeCurrent() failure\n"); + XDestroyWindow(g_display, window); + return NULL; + } + + /* Disable the window close button. */ + Atom wm_delete_window_atom = XInternAtom(g_display, "WM_DELETE_WINDOW", False); + XSetWMProtocols(g_display, window, &wm_delete_window_atom, 1); + + return (void *)window; +} + +void jtk_window_swap_buffers(void * window) +{ + glXSwapBuffers(g_display, (Window)window); +} + +void jtk_window_close(void * window) +{ + XDestroyWindow(g_display, (Window)window); +} + +void jtk_window_set_title(void * window, const char * title) +{ + XTextProperty title_property; + if (XStringListToTextProperty((char **)&title, 1, &title_property) != 0) + { + XSetTextProperty(g_display, (Window)window, &title_property, XA_WM_NAME); + XFree(title_property.value); + } +} + +/** + * Set the window icon. + * + * @param window + * The window to operate on. + * @param data + * The format of data must be 32 bits per pixel in BGRA format (e.g. data[0] + * is blue value, data[3] is alpha value of first pixel). + * @param width + * Icon width. + * @param height + * Icon height. + */ +void jtk_window_set_icon(void * window, const uint8_t * data, + size_t width, size_t height) +{ + Atom net_wm_icon_atom = XInternAtom(g_display, "_NET_WM_ICON", False); + size_t property_size = (2u + width * height) * sizeof(long); + unsigned long * property_data = (unsigned long *)malloc(property_size); + property_data[0] = width; + property_data[1] = height; + unsigned long * dest = &property_data[2]; + const uint32_t * src = (const uint32_t *)data; + for (size_t row = 0u; row < height; row++) + { + for (size_t col = 0u; col < width; col++) + { + *dest++ = *src++; + } + } + XChangeProperty(g_display, (Window)window, net_wm_icon_atom, XA_CARDINAL, + 32, PropModeReplace, (uint8_t *)property_data, property_size); + XFlush(g_display); + free(property_data); +} diff --git a/src/jes/gui/jtk.d b/src/jes/gui/jtk.d index 81f6d51..d61040e 100644 --- a/src/jes/gui/jtk.d +++ b/src/jes/gui/jtk.d @@ -1,4 +1,10 @@ private extern(C) bool jtk_init(); +private extern(C) void * jtk_window_create(); +private extern(C) void jtk_window_swap_buffers(void * window); +private extern(C) void jtk_window_close(void * window); +private extern(C) void jtk_window_set_title(void * window, const char * title); +private extern(C) void jtk_window_set_icon(void * window, const ubyte * data, + size_t width, size_t height); struct Jtk {