72bf6631a795ff7ffcf94f28ad9346a4921b9575
[platform/upstream/kmscon.git] / tests / test_output.c
1 /*
2  * test_output - Test KMS/DRI output
3  *
4  * Copyright (c) 2011 David Herrmann <dh.herrmann@googlemail.com>
5  * Copyright (c) 2011 University of Tuebingen
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining
8  * a copy of this software and associated documentation files
9  * (the "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included
16  * in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  */
26
27 /*
28  * Test KMS/DRI output subsystem
29  * This is an example how to use the output subsystem. Invoked without
30  * arguments it prints a list of all connected outputs and their modes.
31  * If you pass numbers as arguments, it will enable these outputs and show an
32  * image on the given monitors for 5 seconds.
33  *
34  * This lists all outputs:
35  * $ ./test_output
36  *
37  * This would show a test screen on output 0 and 4:
38  * $ ./test_output 0 4
39  * The test screen is a colored quad with 4 different colors in each corner.
40  */
41
42 #include <errno.h>
43 #include <GL/gl.h>
44 #include <inttypes.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <unistd.h>
49
50 #include "eloop.h"
51 #include "gl.h"
52 #include "log.h"
53 #include "uterm.h"
54 #include "test_include.h"
55
56 /* eloop object */
57 static struct ev_eloop *eloop;
58
59 /* a colored quad */
60 float d_vert[] = { -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1 };
61 float d_col[] = { 1, 1, 0, 1,
62                 1, 1, 1, 1,
63                 0, 1, 1, 1,
64                 1, 1, 1, 1,
65                 0, 0, 1, 1,
66                 0, 1, 1, 1 };
67
68 static int set_outputs(struct uterm_video *video, int num, char **list)
69 {
70         struct uterm_display *iter;
71         int i, j, val, ret;
72         struct gl_shader *shader;
73         struct uterm_screen *screen;
74
75         ret = gl_shader_new(&shader);
76         if (ret) {
77                 log_err("Cannot create shader: %d", ret);
78                 return ret;
79         }
80
81         j = 0;
82         iter = uterm_video_get_displays(video);
83         for ( ; iter; iter = uterm_display_next(iter)) {
84                 for (i = 0; i < num; ++i) {
85                         val = atoi(list[i]);
86                         if (val == j)
87                                 break;
88                 }
89
90                 if (i == num) {
91                         log_notice("Ignoring display %d", j);
92                 } else {
93                         log_notice("Activating display %d %p...", j, iter);
94                         ret = uterm_display_activate(iter, NULL);
95                         if (ret)
96                                 log_err("Cannot activate display %d: %d", j,
97                                                                         ret);
98                         else
99                                 log_notice("Successfully activated display %d",
100                                                 j);
101
102                         ret = uterm_display_set_dpms(iter, UTERM_DPMS_ON);
103                         if (ret)
104                                 log_err("Cannot set DPMS to ON: %d", ret);
105                 }
106
107                 ++j;
108         }
109
110         iter = uterm_video_get_displays(video);
111         for ( ; iter; iter = uterm_display_next(iter)) {
112                 if (uterm_display_get_state(iter) != UTERM_DISPLAY_ACTIVE)
113                         continue;
114
115                 ret = uterm_screen_new_single(&screen, iter);
116                 if (ret) {
117                         log_err("Cannot create temp-screen object: %d", ret);
118                         continue;
119                 }
120
121                 ret = uterm_screen_use(screen);
122                 if (ret) {
123                         log_err("Cannot use screen: %d", ret);
124                         uterm_screen_unref(screen);
125                         continue;
126                 }
127
128                 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
129                 glClear(GL_COLOR_BUFFER_BIT);
130                 glViewport(0, 0,
131                                 uterm_screen_width(screen),
132                                 uterm_screen_height(screen));
133
134                 gl_shader_draw_def(shader, d_vert, d_col, 6);
135                 if (gl_has_error())
136                         log_err("GL error occurred");
137
138                 ret = uterm_screen_swap(screen);
139                 if (ret) {
140                         log_err("Cannot swap screen: %d", ret);
141                         uterm_screen_unref(screen);
142                         continue;
143                 }
144
145                 log_notice("Successfully set screen on display %p", iter);
146                 uterm_screen_unref(screen);
147         }
148
149         log_notice("Waiting 5 seconds...");
150         ev_eloop_run(eloop, 5000);
151         log_notice("Exiting...");
152
153         gl_shader_unref(shader);
154
155         return 0;
156 }
157
158 static int list_outputs(struct uterm_video *video)
159 {
160         struct uterm_display *iter;
161         struct uterm_mode *cur, *mode;
162         int i;
163
164         log_notice("List of Outputs:");
165
166         i = 0;
167         iter = uterm_video_get_displays(video);
168         for ( ; iter; iter = uterm_display_next(iter)) {
169                 cur = uterm_display_get_current(iter);
170
171                 log_notice("Output %d:", i++);
172                 log_notice("  active: %d", uterm_display_get_state(iter));
173                 log_notice("  has current: %s", cur ? "yes" : "no");
174
175                 mode = uterm_display_get_modes(iter);
176                 for ( ; mode; mode = uterm_mode_next(mode)) {
177                         log_notice("  Mode '%s':", uterm_mode_get_name(mode));
178                         log_notice("    x: %u", uterm_mode_get_width(mode));
179                         log_notice("    y: %u", uterm_mode_get_height(mode));
180                 }
181         }
182
183         log_notice("End of Output list");
184
185         return 0;
186 }
187
188 int main(int argc, char **argv)
189 {
190         struct uterm_video *video;
191         int ret;
192
193         ret = test_prepare(argc, argv, &eloop);
194         if (ret)
195                 goto err_fail;
196
197         log_notice("Creating video object...");
198         ret = uterm_video_new(&video, UTERM_VIDEO_DRM, eloop);
199         if (ret)
200                 goto err_exit;
201
202         log_notice("Wakeing up video object...");
203         ret = uterm_video_wake_up(video);
204         if (ret < 0)
205                 goto err_unref;
206
207         if (argc < 2) {
208                 ret = list_outputs(video);
209                 if (ret) {
210                         log_err("Cannot list outputs: %d", ret);
211                         goto err_unref;
212                 }
213         } else {
214                 ret = set_outputs(video, argc - 1, &argv[1]);
215                 if (ret) {
216                         log_err("Cannot set outputs: %d", ret);
217                         goto err_unref;
218                 }
219         }
220
221 err_unref:
222         uterm_video_unref(video);
223 err_exit:
224         test_exit(eloop);
225 err_fail:
226         test_fail(ret);
227         return abs(ret);
228 }