1e52adb7bSmrg/*
2e52adb7bSmrg * Copyright © 2009, 2013 Intel Corporation
3e52adb7bSmrg *
4e52adb7bSmrg * Permission is hereby granted, free of charge, to any person obtaining a
5e52adb7bSmrg * copy of this software and associated documentation files (the "Software"),
6e52adb7bSmrg * to deal in the Software without restriction, including without limitation
7e52adb7bSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8e52adb7bSmrg * and/or sell copies of the Software, and to permit persons to whom the
9e52adb7bSmrg * Software is furnished to do so, subject to the following conditions:
10e52adb7bSmrg *
11e52adb7bSmrg * The above copyright notice and this permission notice (including the next
12e52adb7bSmrg * paragraph) shall be included in all copies or substantial portions of the
13e52adb7bSmrg * Software.
14e52adb7bSmrg *
15e52adb7bSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16e52adb7bSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17e52adb7bSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18e52adb7bSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19e52adb7bSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20e52adb7bSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21e52adb7bSmrg * IN THE SOFTWARE.
22e52adb7bSmrg */
23e52adb7bSmrg
24e52adb7bSmrg#include <stdio.h>
25e52adb7bSmrg#include <stdlib.h>
26e52adb7bSmrg#include <X11/Xlib.h>
27e52adb7bSmrg#include "glx_common.h"
28e52adb7bSmrg
29e52adb7bSmrgDisplay *
30e52adb7bSmrgget_display_or_skip(void)
31e52adb7bSmrg{
32e52adb7bSmrg	Display *dpy = XOpenDisplay(NULL);
33e52adb7bSmrg
34e52adb7bSmrg	if (!dpy) {
35ca86eba8Smrg		fputs("couldn't open display\n", stderr);
36e52adb7bSmrg		exit(77);
37e52adb7bSmrg	}
38e52adb7bSmrg
39e52adb7bSmrg	return dpy;
40e52adb7bSmrg}
41e52adb7bSmrg
42e52adb7bSmrgXVisualInfo *
43e52adb7bSmrgget_glx_visual(Display *dpy)
44e52adb7bSmrg{
45e52adb7bSmrg	XVisualInfo *visinfo;
46e52adb7bSmrg	int attrib[] = {
47e52adb7bSmrg		GLX_RGBA,
48e52adb7bSmrg		GLX_RED_SIZE, 1,
49e52adb7bSmrg		GLX_GREEN_SIZE, 1,
50e52adb7bSmrg		GLX_BLUE_SIZE, 1,
51e52adb7bSmrg		GLX_DOUBLEBUFFER,
52e52adb7bSmrg		None
53e52adb7bSmrg	};
54e52adb7bSmrg	int screen = DefaultScreen(dpy);
55e52adb7bSmrg
56e52adb7bSmrg	visinfo = glXChooseVisual(dpy, screen, attrib);
57e52adb7bSmrg	if (visinfo == NULL) {
58ca86eba8Smrg		fputs("Couldn't get an RGBA, double-buffered visual\n", stderr);
59e52adb7bSmrg		exit(1);
60e52adb7bSmrg	}
61e52adb7bSmrg
62e52adb7bSmrg	return visinfo;
63e52adb7bSmrg}
64e52adb7bSmrg
65e52adb7bSmrgWindow
66e52adb7bSmrgget_glx_window(Display *dpy, XVisualInfo *visinfo, bool map)
67e52adb7bSmrg{
68e52adb7bSmrg	XSetWindowAttributes window_attr;
69e52adb7bSmrg	unsigned long mask;
70e52adb7bSmrg	int screen = DefaultScreen(dpy);
71e52adb7bSmrg	Window root_win = RootWindow(dpy, screen);
72e52adb7bSmrg	Window win;
73e52adb7bSmrg
74e52adb7bSmrg	window_attr.background_pixel = 0;
75e52adb7bSmrg	window_attr.border_pixel = 0;
76e52adb7bSmrg	window_attr.colormap = XCreateColormap(dpy, root_win,
77e52adb7bSmrg					       visinfo->visual, AllocNone);
78e52adb7bSmrg	window_attr.event_mask = StructureNotifyMask | ExposureMask |
79e52adb7bSmrg		KeyPressMask;
80e52adb7bSmrg	mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
81e52adb7bSmrg	win = XCreateWindow(dpy, root_win, 0, 0,
82e52adb7bSmrg			    10, 10, /* width, height */
83e52adb7bSmrg			    0, visinfo->depth, InputOutput,
84e52adb7bSmrg			    visinfo->visual, mask, &window_attr);
85e52adb7bSmrg
86e52adb7bSmrg	return win;
87e52adb7bSmrg}
88e52adb7bSmrg
89e52adb7bSmrgvoid
90e52adb7bSmrgmake_glx_context_current_or_skip(Display *dpy)
91e52adb7bSmrg{
92e52adb7bSmrg	GLXContext ctx;
93e52adb7bSmrg	XVisualInfo *visinfo = get_glx_visual(dpy);
94e52adb7bSmrg	Window win = get_glx_window(dpy, visinfo, false);
95e52adb7bSmrg
96e52adb7bSmrg	ctx = glXCreateContext(dpy, visinfo, False, True);
97e52adb7bSmrg	if (ctx == None) {
98ca86eba8Smrg		fputs("glXCreateContext failed\n", stderr);
99e52adb7bSmrg		exit(1);
100e52adb7bSmrg	}
101e52adb7bSmrg
102e52adb7bSmrg	glXMakeCurrent(dpy, win, ctx);
103e52adb7bSmrg}
104e52adb7bSmrg
105e52adb7bSmrgGLXFBConfig
106e52adb7bSmrgget_fbconfig_for_visinfo(Display *dpy, XVisualInfo *visinfo)
107e52adb7bSmrg{
108e52adb7bSmrg	int i, nconfigs;
109e52adb7bSmrg	GLXFBConfig ret = None, *configs;
110e52adb7bSmrg
111e52adb7bSmrg	configs = glXGetFBConfigs(dpy, visinfo->screen, &nconfigs);
112e52adb7bSmrg	if (!configs)
113e52adb7bSmrg		return None;
114e52adb7bSmrg
115e52adb7bSmrg	for (i = 0; i < nconfigs; i++) {
116e52adb7bSmrg		int v;
117e52adb7bSmrg
118e52adb7bSmrg		if (glXGetFBConfigAttrib(dpy, configs[i], GLX_VISUAL_ID, &v))
119e52adb7bSmrg			continue;
120e52adb7bSmrg
121e52adb7bSmrg		if (v == visinfo->visualid) {
122e52adb7bSmrg			ret = configs[i];
123e52adb7bSmrg			break;
124e52adb7bSmrg		}
125e52adb7bSmrg	}
126e52adb7bSmrg
127e52adb7bSmrg	XFree(configs);
128e52adb7bSmrg	return ret;
129e52adb7bSmrg}
130