111 lines
2.6 KiB
C
111 lines
2.6 KiB
C
#include "based_gui.h"
|
|
#include <X11/Xlib.h>
|
|
#include <X11/extensions/Xdbe.h>
|
|
#include <X11/xpm.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
|
|
struct BasedWindow {
|
|
int a;
|
|
};
|
|
|
|
struct BasedApp {
|
|
Display* display;
|
|
Window window;
|
|
XdbeBackBuffer back_buffer;
|
|
bool has_back_buffer;
|
|
XdbeSwapInfo swap_info;
|
|
Atom wm_delete_window;
|
|
};
|
|
|
|
BasedApp* based_app_new(void)
|
|
{
|
|
BasedApp* app = malloc(sizeof(app));
|
|
|
|
XInitThreads();
|
|
|
|
app->display = XOpenDisplay(NULL);
|
|
|
|
unsigned long white = WhitePixel(app->display, DefaultScreen(app->display));
|
|
unsigned long black = BlackPixel(app->display, DefaultScreen(app->display));
|
|
|
|
app->window = XCreateSimpleWindow(
|
|
app->display,
|
|
DefaultRootWindow(app->display),
|
|
0,
|
|
0,
|
|
500,
|
|
500,
|
|
0,
|
|
white,
|
|
white
|
|
);
|
|
|
|
app->has_back_buffer = false;
|
|
|
|
// Create back buffer for double buffering
|
|
int xdbe_major_version, xdbe_minor_version;
|
|
if (XdbeQueryExtension(
|
|
app->display, &xdbe_major_version, &xdbe_minor_version
|
|
)) {
|
|
app->has_back_buffer = true;
|
|
|
|
app->back_buffer
|
|
= XdbeAllocateBackBufferName(app->display, app->window, 0);
|
|
|
|
app->swap_info
|
|
= (XdbeSwapInfo) { .swap_window = app->window, .swap_action = 0 };
|
|
}
|
|
|
|
XSelectInput(
|
|
app->display, app->window, ExposureMask | KeyPressMask | KeyReleaseMask
|
|
);
|
|
|
|
app->wm_delete_window
|
|
= XInternAtom(app->display, "WM_DELETE_WINDOW", false);
|
|
XSetWMProtocols(app->display, app->window, &app->wm_delete_window, 1);
|
|
|
|
XVisualInfo vinfo;
|
|
XMatchVisualInfo(
|
|
app->display, DefaultScreen(app->display), 32, TrueColor, &vinfo
|
|
);
|
|
|
|
XMapWindow(app->display, app->window);
|
|
|
|
return app;
|
|
}
|
|
|
|
BasedWindow* based_app_make_window(BasedApp* app)
|
|
{
|
|
(void)app;
|
|
return NULL;
|
|
}
|
|
|
|
void based_app_run(BasedApp* app)
|
|
{
|
|
|
|
XEvent event;
|
|
for (;;) {
|
|
XNextEvent(app->display, &event);
|
|
switch (event.type) {
|
|
case Expose:
|
|
if (!event.xexpose.x && !event.xexpose.y && !event.xexpose.width
|
|
&& !event.xexpose.height) {
|
|
break;
|
|
}
|
|
break;
|
|
case ClientMessage:
|
|
if ((uint64_t)event.xclient.data.l[0] == app->wm_delete_window)
|
|
return;
|
|
}
|
|
|
|
if (app->has_back_buffer)
|
|
XdbeSwapBuffers(app->display, &app->swap_info, 1);
|
|
}
|
|
}
|
|
|
|
void based_window_delete(BasedWindow* window) { free(window); }
|
|
|
|
void based_app_delete(BasedApp* app) { free(app); }
|