*drive-thru whale* Please enter your password.
This commit is contained in:
parent
0d5347e057
commit
c54a59da72
1 changed files with 142 additions and 0 deletions
142
src/window.c
Normal file
142
src/window.c
Normal file
|
@ -0,0 +1,142 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xdbe.h>
|
||||
|
||||
#include <hexagram/window.h>
|
||||
|
||||
struct _hexagram_window {
|
||||
Display *display;
|
||||
|
||||
int screen;
|
||||
|
||||
unsigned int width,
|
||||
height;
|
||||
|
||||
Window root,
|
||||
win;
|
||||
|
||||
Pixmap shape,
|
||||
bg;
|
||||
|
||||
GC gc;
|
||||
|
||||
XGCValues gc_values;
|
||||
|
||||
XdbeBackBuffer buf;
|
||||
XdbeSwapInfo swapinfo;
|
||||
};
|
||||
|
||||
hexagram_window *hexagram_window_new_x11(const char *display,
|
||||
unsigned int width,
|
||||
unsigned int height) {
|
||||
hexagram_window *window;
|
||||
int major, minor;
|
||||
|
||||
if ((window = malloc(sizeof(*window))) == NULL) {
|
||||
goto error_malloc_window;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connect to the X display
|
||||
*/
|
||||
if ((window->display = XOpenDisplay(display)) == NULL) {
|
||||
goto error_x_open_display;
|
||||
}
|
||||
|
||||
window->screen = DefaultScreen(window->display);
|
||||
window->root = DefaultRootWindow(window->display);
|
||||
|
||||
/*
|
||||
* Create the X window
|
||||
*/
|
||||
if ((window->win = XCreateSimpleWindow(window->display,
|
||||
window->root,
|
||||
0, 0,
|
||||
width, height, 0, 0, 0)) == 0) {
|
||||
goto error_x_create_simple_window;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a back buffer, if the Xdbe extension is available. If not, render
|
||||
* directly to the window, at the cost of flickering.
|
||||
*/
|
||||
if (XdbeQueryExtension(window->display, &major, &minor)) {
|
||||
if ((window->buf = XdbeAllocateBackBufferName(window->display,
|
||||
window->win,
|
||||
XdbeBackground)) == 0) {
|
||||
goto error_x_dbe_allocate_back_buffer_name;
|
||||
}
|
||||
|
||||
window->swapinfo.swap_window = window->win;
|
||||
window->swapinfo.swap_action = XdbeBackground;
|
||||
} else {
|
||||
window->buf = window->win;
|
||||
}
|
||||
|
||||
if ((window->bg = XCreatePixmap(window->display,
|
||||
window->win, width, height, 24)) == 0) {
|
||||
goto error_x_create_pixmap_bg;
|
||||
}
|
||||
|
||||
window->gc_values.foreground = 0x000000;
|
||||
window->gc_values.background = 0xffffff;
|
||||
window->gc_values.graphics_exposures = 0;
|
||||
|
||||
if ((window->gc = XCreateGC(window->display,
|
||||
window->win,
|
||||
HEXAGRAM_WINDOW_GC_FLAGS,
|
||||
&window->gc_values)) == 0) {
|
||||
goto error_x_create_gc;
|
||||
}
|
||||
|
||||
return window;
|
||||
|
||||
error_x_create_gc:
|
||||
(void)XFreePixmap(window->display, window->bg);
|
||||
|
||||
error_x_create_pixmap_bg:
|
||||
if (window->buf != window->win) {
|
||||
(void)XdbeDeallocateBackBufferName(window->display, window->buf);
|
||||
}
|
||||
|
||||
error_x_dbe_allocate_back_buffer_name:
|
||||
(void)XDestroyWindow(window->display, window->win);
|
||||
|
||||
error_x_create_simple_window:
|
||||
(void)XCloseDisplay(window->display);
|
||||
|
||||
error_x_open_display:
|
||||
free(window);
|
||||
|
||||
error_malloc_window:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int hexagram_window_show(hexagram_window *window) {
|
||||
if (XSelectInput(window->display, window->win,
|
||||
ExposureMask | ButtonPressMask | KeyPressMask) == 0) {
|
||||
goto error_x;
|
||||
}
|
||||
|
||||
if (XMapWindow(window->display, window->win) == 0) {
|
||||
goto error_x;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_x:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void hexagram_window_destroy(hexagram_window *window) {
|
||||
(void)XFreeGC(window->display, window->gc);
|
||||
|
||||
(void)XFreePixmap(window->display, window->bg);
|
||||
|
||||
if (window->buf != window->win) {
|
||||
(void)XdbeDeallocateBackBufferName(window->display, window->buf);
|
||||
}
|
||||
|
||||
XUnmapWindow(window->display, window->win);
|
||||
}
|
Loading…
Add table
Reference in a new issue