]> git.cworth.org Git - fips/blob - test/handle-events.c
test: Reduce code duplication in test-suite programs
[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 draw (Display *dpy, Window window, int width, int height)
66 {
67         int i;
68         int visual_attr[] = {
69                 GLX_RGBA,
70                 GLX_RED_SIZE,           8,
71                 GLX_GREEN_SIZE,         8,
72                 GLX_BLUE_SIZE,          8,
73                 GLX_ALPHA_SIZE,         8,
74                 GLX_DOUBLEBUFFER,
75                 GLX_DEPTH_SIZE,         24,
76                 GLX_STENCIL_SIZE,       8,
77                 GLX_X_VISUAL_TYPE,      GLX_DIRECT_COLOR,
78                 None
79         };
80
81         /* Window and context setup. */
82         XVisualInfo *visual_info = _(glXChooseVisual) (dpy, 0, visual_attr);
83         GLXContext ctx = _(glXCreateContext) (dpy, visual_info, NULL, True);
84         _(glXMakeCurrent) (dpy, window, ctx);
85
86         _(glViewport) (0, 0, width, height);
87
88         set_2d_projection (width, height);
89
90 /* Simply count through some colors, frame by frame. */
91 #define RGB(frame) (((frame+1)/4) % 2), (((frame+1)/2) % 2), ((frame+1) % 2)
92
93         int frame = 0;
94         for (i = 0; i < 2; i++) {
95                 /* Frame: Draw a solid (magenta) frame */
96                 paint_rgb_using_clear (RGB(frame));
97                 _(glXSwapBuffers) (dpy, window);
98                 frame++;
99
100                 /* Frame: Draw a solid (yellow) frame */
101                 paint_rgb_using_clear (RGB(frame));
102                 _(glXSwapBuffers) (dpy, window);
103                 frame++;
104
105                 /* Frame: Draw a solid (cyan) frame */
106                 paint_rgb_using_clear (RGB(frame));
107                 _(glXSwapBuffers) (dpy, window);
108                 frame++;
109         }
110
111         /* Cleanup */
112         _(glXDestroyContext) (dpy, ctx);
113 }
114
115 static void
116 handle_events(Display *dpy, Window window)
117 {
118         XEvent xev;
119         int width = 0;
120         int height = 0;
121
122         XNextEvent (dpy, &xev);
123
124         while (1) {
125                 XNextEvent (dpy, &xev);
126                 switch (xev.type) {
127                 case ConfigureNotify:
128                         width = xev.xconfigure.width;
129                         height = xev.xconfigure.height;
130                         break;
131                 case Expose:
132                         if (xev.xexpose.count == 0) {
133                                 draw (dpy, window, width, height);
134                                 return;
135                         }
136                         break;
137                 }
138         }
139 }