summaryrefslogtreecommitdiffstats
path: root/libdimension/tests/display.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdimension/tests/display.c')
-rw-r--r--libdimension/tests/display.c151
1 files changed, 151 insertions, 0 deletions
diff --git a/libdimension/tests/display.c b/libdimension/tests/display.c
new file mode 100644
index 0000000..d4e2a1c
--- /dev/null
+++ b/libdimension/tests/display.c
@@ -0,0 +1,151 @@
+/*************************************************************************
+ * Copyright (C) 2009-2010 Tavian Barnes <tavianator@tavianator.com> *
+ * *
+ * This file is part of The Dimension Test Suite. *
+ * *
+ * The Dimension Test Suite is free software; you can redistribute it *
+ * and/or modify it under the terms of the GNU General Public License as *
+ * published by the Free Software Foundation; either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * The Dimension Test Suite is distributed in the hope that it will be *
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty *
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
+ *************************************************************************/
+
+#include "tests.h"
+#include <GL/glx.h>
+#include <GL/gl.h>
+#include <stdlib.h>
+
+struct dmnsn_display {
+ Display *dpy;
+ Window win;
+ Colormap cmap;
+ GLXContext cx;
+ XEvent event;
+ XVisualInfo *vi;
+};
+
+/* XIfEvent callback */
+static Bool
+WaitForNotify(Display *d, XEvent *e, char *arg)
+{
+ return (e->type == MapNotify) && (e->xmap.window == (Window)arg);
+}
+
+dmnsn_display *
+dmnsn_new_display(const dmnsn_canvas *canvas)
+{
+ int attributeList[] = {
+ GLX_RGBA,
+ GLX_DOUBLEBUFFER,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ None
+ };
+ XSetWindowAttributes swa;
+ dmnsn_display *display;
+
+ display = dmnsn_malloc(sizeof(dmnsn_display));
+
+ display->dpy = NULL;
+ display->win = 0;
+ display->cmap = 0;
+ display->cx = NULL;
+ display->vi = NULL;
+
+ /* Get an X connection */
+ display->dpy = XOpenDisplay(0);
+ if (!display->dpy) {
+ dmnsn_delete_display(display);
+ return NULL;
+ }
+
+ /* Get an appropriate visual */
+ display->vi = glXChooseVisual(display->dpy, DefaultScreen(display->dpy),
+ attributeList);
+ if (!display->vi) {
+ dmnsn_delete_display(display);
+ return NULL;
+ }
+
+ /* Create a GLX context */
+ display->cx = glXCreateContext(display->dpy, display->vi, 0, GL_TRUE);
+ if (!display->cx) {
+ dmnsn_delete_display(display);
+ return NULL;
+ }
+
+ /* Create a color map */
+ display->cmap = XCreateColormap(display->dpy,
+ RootWindow(display->dpy, display->vi->screen),
+ display->vi->visual, AllocNone);
+ if (!display->cmap) {
+ dmnsn_delete_display(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, display->vi->screen),
+ 0, 0, canvas->width, canvas->height,
+ 0, display->vi->depth, InputOutput,
+ display->vi->visual,
+ CWBorderPixel|CWColormap|CWEventMask, &swa);
+ if (!display->win) {
+ dmnsn_delete_display(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);
+ glClearColor(0.0, 0.0, 0.0, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ dmnsn_display_flush(display);
+
+ return display;
+}
+
+void
+dmnsn_delete_display(dmnsn_display *display)
+{
+ if (display) {
+ if (display->win)
+ XDestroyWindow(display->dpy, display->win);
+
+ if (display->cmap)
+ XFreeColormap(display->dpy, display->cmap);
+
+ if (display->cx)
+ glXDestroyContext(display->dpy, display->cx);
+
+ if (display->vi)
+ XFree(display->vi);
+
+ if (display->dpy)
+ XCloseDisplay(display->dpy);
+
+ dmnsn_free(display);
+ }
+}
+
+void
+dmnsn_display_flush(dmnsn_display *display)
+{
+ glXWaitX();
+ glXSwapBuffers(display->dpy, display->win);
+}