Merge branch '7.8'
[mesa.git] / progs / xdemos / opencloseopen.c
1 /*
2 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
3 * (C) Copyright IBM Corporation 2003
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <unistd.h>
26 #include <string.h>
27 #include <X11/Xlib.h>
28 #include <GL/gl.h>
29 #include <GL/glx.h>
30
31 /** \file opencloseopen.c
32 * Simple test for Mesa bug #508473. Create a window and rendering context.
33 * Draw a single frame. Close the window, destroy the context, and close
34 * the display. Re-open the display, create a new window and context. This
35 * should work, but, at least as of Mesa 5.1, it segfaults. See the bug
36 * report for more details.
37 *
38 * Most of the code here was lifed from various other Mesa xdemos.
39 */
40
41 static void
42 draw(void)
43 {
44 glViewport(0, 0, 300, 300);
45 glMatrixMode(GL_PROJECTION);
46 glLoadIdentity();
47 glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
48 glMatrixMode(GL_MODELVIEW);
49
50 glShadeModel(GL_FLAT);
51 glClearColor(0.5, 0.5, 0.5, 1.0);
52 glClear(GL_COLOR_BUFFER_BIT);
53
54 /* draw blue quad */
55 glLoadIdentity();
56 glColor3f(0.3, 0.3, 1.0);
57 glPushMatrix();
58 glRotatef(0, 0, 0, 1);
59 glBegin(GL_POLYGON);
60 glVertex2f(-0.5, -0.25);
61 glVertex2f( 0.5, -0.25);
62 glVertex2f( 0.5, 0.25);
63 glVertex2f(-0.5, 0.25);
64 glEnd();
65 glPopMatrix();}
66
67
68 /*
69 * Create an RGB, double-buffered window.
70 * Return the window and context handles.
71 */
72 static void
73 make_window( const char * dpyName, const char *name,
74 int x, int y, int width, int height,
75 Display **dpyRet, Window *winRet, GLXContext *ctxRet)
76 {
77 int attrib[] = { GLX_RGBA,
78 GLX_RED_SIZE, 1,
79 GLX_GREEN_SIZE, 1,
80 GLX_BLUE_SIZE, 1,
81 GLX_DOUBLEBUFFER,
82 None };
83 int scrnum;
84 XSetWindowAttributes attr;
85 unsigned long mask;
86 Window root;
87 Window win;
88 GLXContext ctx;
89 XVisualInfo *visinfo;
90 Display *dpy;
91
92 dpy = XOpenDisplay(dpyName);
93 if (!dpy) {
94 printf("Error: couldn't open display %s\n", XDisplayName(dpyName));
95 exit(1);
96 }
97
98 *dpyRet = dpy;
99 scrnum = DefaultScreen( dpy );
100 root = RootWindow( dpy, scrnum );
101
102 visinfo = glXChooseVisual( dpy, scrnum, attrib );
103 if (!visinfo) {
104 printf("Error: couldn't get an RGB, Double-buffered visual\n");
105 exit(1);
106 }
107
108 /* window attributes */
109 attr.background_pixel = 0;
110 attr.border_pixel = 0;
111 attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
112 attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
113 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
114
115 win = XCreateWindow( dpy, root, 0, 0, width, height,
116 0, visinfo->depth, InputOutput,
117 visinfo->visual, mask, &attr );
118
119 /* set hints and properties */
120 {
121 XSizeHints sizehints;
122 sizehints.x = x;
123 sizehints.y = y;
124 sizehints.width = width;
125 sizehints.height = height;
126 sizehints.flags = USSize | USPosition;
127 XSetNormalHints(dpy, win, &sizehints);
128 XSetStandardProperties(dpy, win, name, name,
129 None, (char **)NULL, 0, &sizehints);
130 }
131
132 ctx = glXCreateContext( dpy, visinfo, NULL, True );
133 if (!ctx) {
134 printf("Error: glXCreateContext failed\n");
135 exit(1);
136 }
137
138 XFree(visinfo);
139
140 *winRet = win;
141 *ctxRet = ctx;
142 }
143
144
145 static void
146 destroy_window( Display *dpy, Window win, GLXContext ctx )
147 {
148 glXMakeCurrent(dpy, None, NULL);
149 glXDestroyContext(dpy, ctx);
150 XDestroyWindow(dpy, win);
151 XCloseDisplay(dpy);
152 }
153
154
155 int
156 main(int argc, char *argv[])
157 {
158 Display *dpy;
159 Window win;
160 GLXContext ctx;
161 char *dpyName = NULL;
162 int i;
163
164 for (i = 1; i < argc; i++) {
165 if (strcmp(argv[i], "-display") == 0) {
166 dpyName = argv[i+1];
167 i++;
168 }
169 }
170
171 printf("If this program segfaults, then Mesa bug #508473 is probably "
172 "back.\n");
173 make_window(dpyName, "Open-close-open", 0, 0, 300, 300, &dpy, &win, &ctx);
174 XMapWindow(dpy, win);
175 glXMakeCurrent(dpy, win, ctx);
176
177 draw();
178 glXSwapBuffers(dpy, win);
179 sleep(2);
180
181 destroy_window(dpy, win, ctx);
182
183 make_window(dpyName, "Open-close-open", 0, 0, 300, 300, &dpy, &win, &ctx);
184 XMapWindow(dpy, win);
185 glXMakeCurrent(dpy, win, ctx);
186 destroy_window(dpy, win, ctx);
187
188 return 0;
189 }