]> git.cworth.org Git - fips/blob - test/handle-events.c
util-x11: Rework init_window interface to accept XVisualInfo
[fips] / test / handle-events.c
1 /* Copyright © 2013, Intel Corporation
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to deal
5  * in the Software without restriction, including without limitation the rights
6  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7  * copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19  * THE SOFTWARE.
20  */
21
22 /* This is C code intended to be included (yes, included) by test
23  * programs in the fips test suite.
24  *
25  * It defines a function:
26  *
27  *      static void
28  *      handle_events(Display *dpy, Window window);
29  *
30  * which handles X events, responding by drawing a few frames using
31  * OpenGL.
32  *
33  * Before including this file, the test program must define a macro
34  * HANDLE_EVENTS_GL_PREFIX to some prefix. This macro can be empty (to
35  * directly call functions in an OpenGL-library directly linked) or
36  * can be some custom prefix to call through symbols defined in the
37  * test program.
38  */
39
40 #ifndef HANDLE_EVENTS_GL_PREFIX
41 #error Code including handle-events.c must define HANDLE_EVENTS_GL_PREFIX
42 #endif
43
44 #define concat_(a,b) a ## b
45 #define concat(a,b) concat_(a,b)
46 #define _(func) concat(HANDLE_EVENTS_GL_PREFIX, func)
47
48 static void
49 set_2d_projection (int width, int height)
50 {
51         _(glMatrixMode) (GL_PROJECTION);
52         _(glLoadIdentity) ();
53         _(glOrtho) (0, width, height, 0, 0, 1);
54         _(glMatrixMode) (GL_MODELVIEW);
55 }
56
57 static void
58 paint_rgb_using_clear (double r, double g, double b)
59 {
60         _(glClearColor) (r, g, b, 1.0);
61         _(glClear) (GL_COLOR_BUFFER_BIT);
62 }
63
64 static void
65 create_context (Display *dpy, GLXContext *ctx_ret, XVisualInfo **visual_info_ret)
66 {
67         int visual_attr[] = {
68                 GLX_RGBA,
69                 GLX_RED_SIZE,           8,
70                 GLX_GREEN_SIZE,         8,
71                 GLX_BLUE_SIZE,          8,
72                 GLX_ALPHA_SIZE,         8,
73                 GLX_DOUBLEBUFFER,
74                 GLX_DEPTH_SIZE,         24,
75                 GLX_STENCIL_SIZE,       8,
76                 GLX_X_VISUAL_TYPE,      GLX_DIRECT_COLOR,
77                 None
78         };
79
80         /* Window and context setup. */
81         *visual_info_ret = _(glXChooseVisual) (dpy, 0, visual_attr);
82         *ctx_ret = _(glXCreateContext) (dpy, *visual_info_ret, NULL, True);
83 }
84
85 static void
86 draw (Display *dpy, GLXContext ctx, Window window, int width, int height)
87 {
88         int i;
89         _(glXMakeCurrent) (dpy, window, ctx);
90
91         _(glViewport) (0, 0, width, height);
92
93         set_2d_projection (width, height);
94
95 /* Simply count through some colors, frame by frame. */
96 #define RGB(frame) (((frame+1)/4) % 2), (((frame+1)/2) % 2), ((frame+1) % 2)
97
98         int frame = 0;
99         for (i = 0; i < 2; i++) {
100                 /* Frame: Draw a solid (magenta) frame */
101                 paint_rgb_using_clear (RGB(frame));
102                 _(glXSwapBuffers) (dpy, window);
103                 frame++;
104
105                 /* Frame: Draw a solid (yellow) frame */
106                 paint_rgb_using_clear (RGB(frame));
107                 _(glXSwapBuffers) (dpy, window);
108                 frame++;
109
110                 /* Frame: Draw a solid (cyan) frame */
111                 paint_rgb_using_clear (RGB(frame));
112                 _(glXSwapBuffers) (dpy, window);
113                 frame++;
114         }
115
116         /* Cleanup */
117         _(glXDestroyContext) (dpy, ctx);
118 }
119
120 static void
121 handle_events(Display *dpy, GLXContext ctx, Window window)
122 {
123         XEvent xev;
124         int width = 0;
125         int height = 0;
126
127         XNextEvent (dpy, &xev);
128
129         while (1) {
130                 XNextEvent (dpy, &xev);
131                 switch (xev.type) {
132                 case ConfigureNotify:
133                         width = xev.xconfigure.width;
134                         height = xev.xconfigure.height;
135                         break;
136                 case Expose:
137                         if (xev.xexpose.count == 0) {
138                                 draw (dpy, ctx, window, width, height);
139                                 return;
140                         }
141                         break;
142                 }
143         }
144 }