From 634bb3ca825dc6659f03a3013694c5c7b64460e8 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 2 Jul 2009 18:12:25 +0000 Subject: Put windowing interface in libdimension-tests. --- tests/tests.c | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) (limited to 'tests/tests.c') diff --git a/tests/tests.c b/tests/tests.c index b938d39..0816c5d 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -20,6 +20,185 @@ #include "tests.h" +/* XIfEvent callback */ +static Bool +WaitForNotify(Display *d, XEvent *e, char *arg) +{ + return (e->type == MapNotify) && (e->xmap.window == (Window)arg); +} + +/* New non-glX X window */ +dmnsn_display * +dmnsn_new_X_display(const dmnsn_canvas *canvas) +{ + dmnsn_display *display; + int screen, depth; + Visual *visual; + XSetWindowAttributes swa; + + display = malloc(sizeof(dmnsn_display)); + if (!display) { + return NULL; + } + + /* Get an X connection */ + display->dpy = XOpenDisplay(0); + if (!display->dpy) { + free(display); + return NULL; + } + screen = DefaultScreen(display->dpy); + depth = DefaultDepth(display->dpy, screen); + + /* Get an appropriate visual */ + visual = DefaultVisual(display->dpy, screen); + + /* Set display->cx to NULL */ + display->cx = NULL; + + /* Create a color map */ + display->cmap = XCreateColormap(display->dpy, + RootWindow(display->dpy, screen), + visual, AllocNone); + if (!display->cmap) { + glXDestroyContext(display->dpy, display->cx); + XCloseDisplay(display->dpy); + free(display); + return NULL; + } + + /* Create a window */ + swa.colormap = display->cmap; + swa.border_pixel = 0; + swa.event_mask = StructureNotifyMask; + display->win = XCreateWindow(display->dpy, + RootWindow(display->dpy, screen), + 0, 0, canvas->x, canvas->y, + 0, depth, InputOutput, visual, + CWBorderPixel|CWColormap|CWEventMask, &swa); + if (!display->win) { + XFreeColormap(display->dpy, display->cmap); + glXDestroyContext(display->dpy, display->cx); + XCloseDisplay(display->dpy); + free(display); + return NULL; + } + + XStoreName(display->dpy, display->win, "X"); + + XMapWindow(display->dpy, display->win); + XIfEvent(display->dpy, &display->event, WaitForNotify, (char*)display->win); + + return display; +} + +dmnsn_display * +dmnsn_new_glX_display(const dmnsn_canvas *canvas) +{ + int attributeList[] = { + GLX_RGBA, + GLX_DOUBLEBUFFER, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + None + }; + dmnsn_display *display; + XVisualInfo *vi; + XSetWindowAttributes swa; + + display = malloc(sizeof(dmnsn_display)); + if (!display) { + return NULL; + } + + /* Get an X connection */ + display->dpy = XOpenDisplay(0); + if (!display->dpy) { + free(display); + return NULL; + } + + /* Get an appropriate visual */ + vi = glXChooseVisual(display->dpy, DefaultScreen(display->dpy), + attributeList); + if (!vi) { + XCloseDisplay(display->dpy); + free(display); + return NULL; + } + + /* Create a GLX context */ + display->cx = glXCreateContext(display->dpy, vi, 0, GL_TRUE); + if (!display->cx) { + XCloseDisplay(display->dpy); + free(display); + return NULL; + } + + /* Create a color map */ + display->cmap = XCreateColormap(display->dpy, + RootWindow(display->dpy, vi->screen), + vi->visual, AllocNone); + if (!display->cmap) { + glXDestroyContext(display->dpy, display->cx); + XCloseDisplay(display->dpy); + free(display); + return NULL; + } + + /* Create a window */ + swa.colormap = display->cmap; + swa.border_pixel = 0; + swa.event_mask = StructureNotifyMask; + display->win = XCreateWindow(display->dpy, + RootWindow(display->dpy, vi->screen), + 0, 0, canvas->x, canvas->y, + 0, vi->depth, InputOutput, vi->visual, + CWBorderPixel|CWColormap|CWEventMask, &swa); + if (!display->win) { + XFreeColormap(display->dpy, display->cmap); + glXDestroyContext(display->dpy, display->cx); + XCloseDisplay(display->dpy); + free(display); + return NULL; + } + + XStoreName(display->dpy, display->win, "glX"); + + XMapWindow(display->dpy, display->win); + XIfEvent(display->dpy, &display->event, WaitForNotify, (char*)display->win); + + /* Connect the context to the window */ + glXMakeCurrent(display->dpy, display->win, display->cx); + + return display; +} + +void +dmnsn_delete_display(dmnsn_display *display) +{ + if (display) { + XDestroyWindow(display->dpy, display->win); + XFreeColormap(display->dpy, display->cmap); + if (display->cx) { + glXDestroyContext(display->dpy, display->cx); + } + XCloseDisplay(display->dpy); + free(display); + } +} + +void +dmnsn_display_frame(dmnsn_display *display) +{ + if (display->cx) { + glFlush(); + glXSwapBuffers(display->dpy, display->win); + } + XSync(display->dpy, True); +} + /* Print a progress bar of the progress of `progress' */ void progressbar(const char *str, const dmnsn_progress *progress) -- cgit v1.2.3